1 // Boost.Signals library
3 // Copyright (C) 2001-2002 Doug Gregor (gregod@cs.rpi.edu)
5 // Permission to copy, use, sell and distribute this software is granted
6 // provided this copyright notice appears in all copies.
7 // Permission to modify the code and to distribute modified code is granted
8 // provided this copyright notice appears in all copies, and a notice
9 // that the code was modified is included with the copyright notice.
11 // This software is provided "as is" without express or implied warranty,
12 // and with no claim as to its suitability for any purpose.
14 // For more information, see http://www.boost.org
16 #ifndef BOOST_SIGNALS_SLOT_CALL_ITERATOR
17 #define BOOST_SIGNALS_SLOT_CALL_ITERATOR
20 #include <boost/iterator_adaptors.hpp>
21 #include <boost/smart_ptr.hpp>
22 #include <boost/signals/connection.hpp>
25 namespace BOOST_SIGNALS_NAMESPACE {
27 // A cached return value from a slot
29 struct cached_return_value {
30 cached_return_value(const T& t) : value(t) {}
35 // Generates a slot call iterator. Essentially, this is an iterator that:
36 // - skips over disconnected slots in the underlying list
37 // - calls the connected slots when dereferenced
38 // - caches the result of calling the slots
39 template<typename Function, typename Iterator>
40 class slot_call_policies : public default_iterator_policies {
42 typedef typename Function::result_type result_type;
44 slot_call_policies() {}
46 slot_call_policies(const Iterator& x, Function fi) :
47 end(x), f(fi), cache()
51 void initialize(Iterator& x)
53 x = std::find_if(x, end, std::not1(is_disconnected()));
57 template <class IteratorAdaptor>
58 typename IteratorAdaptor::reference
59 dereference(const IteratorAdaptor& x) const
62 cache.reset(new cached_return_value<result_type>(f(*x.base())));
68 template<typename IteratorAdaptor>
69 void increment(IteratorAdaptor& x)
72 x.base() = std::find_if(x.base(), x.policies().end,
73 std::not1(is_disconnected()));
77 template<typename IteratorAdaptor1, typename IteratorAdaptor2>
78 bool equal(const IteratorAdaptor1& x, const IteratorAdaptor2& y) const
80 Iterator xb = std::find_if(x.base(), x.policies().end,
81 std::not1(is_disconnected()));
82 Iterator yb = std::find_if(y.base(), y.policies().end,
83 std::not1(is_disconnected()));
84 const_cast<IteratorAdaptor1&>(x).base() = xb;
85 const_cast<IteratorAdaptor1&>(y).base() = yb;
92 mutable shared_ptr< cached_return_value<result_type> > cache;
95 template<typename Function, typename Iterator>
96 class slot_call_iterator_generator {
98 typedef typename Function::result_type value_type;
100 typedef slot_call_policies<Function, Iterator> policy_type;
101 typedef iterator_adaptor<Iterator, policy_type, value_type,
102 value_type&, value_type*,
103 std::input_iterator_tag> type;
106 template<typename Function, typename Iterator>
107 inline typename slot_call_iterator_generator<Function, Iterator>::type
108 make_slot_call_iterator(Iterator first, Iterator last, Function f)
110 typedef slot_call_iterator_generator<Function, Iterator> gen;
111 typedef typename gen::type sc_iterator;
112 typedef typename gen::policy_type sc_policy;
114 return sc_iterator(first, sc_policy(last, f));
116 } // end namespace detail
117 } // end namespace BOOST_SIGNALS_NAMESPACE
118 } // end namespace boost
119 #endif // BOOST_SIGNALS_SLOT_CALL_ITERATOR