]> git.lyx.org Git - lyx.git/blob - boost/boost/signals/detail/slot_call_iterator.hpp
Boost 1.31.0
[lyx.git] / boost / boost / signals / detail / slot_call_iterator.hpp
1 // Boost.Signals library
2
3 // Copyright Doug Gregor 2001-2003. Use, modification and
4 // distribution is subject to the Boost Software License, Version
5 // 1.0. (See accompanying file LICENSE_1_0.txt or copy at
6 // http://www.boost.org/LICENSE_1_0.txt)
7
8 // For more information, see http://www.boost.org
9
10 #ifndef BOOST_SIGNALS_SLOT_CALL_ITERATOR
11 #define BOOST_SIGNALS_SLOT_CALL_ITERATOR
12
13 #include <functional>
14 #include <boost/iterator/iterator_facade.hpp>
15 #include <boost/smart_ptr.hpp>
16 #include <boost/signals/detail/config.hpp>
17 #include <boost/signals/connection.hpp>
18
19 #ifdef BOOST_HAS_ABI_HEADERS
20 #  include BOOST_ABI_PREFIX
21 #endif
22
23 namespace boost {
24   namespace BOOST_SIGNALS_NAMESPACE {
25     namespace detail {
26       // A cached return value from a slot
27       template<typename T>
28       struct cached_return_value {
29         cached_return_value(const T& t) : value(t) {}
30
31         T value;
32       };
33
34       // Generates a slot call iterator. Essentially, this is an iterator that:
35       //   - skips over disconnected slots in the underlying list
36       //   - calls the connected slots when dereferenced
37       //   - caches the result of calling the slots
38       template<typename Function, typename Iterator>
39       class slot_call_iterator
40         : public iterator_facade<slot_call_iterator<Function, Iterator>,
41                                  typename Function::result_type,
42                                  single_pass_traversal_tag,
43                                  typename Function::result_type const&>
44       {
45         typedef iterator_facade<slot_call_iterator<Function, Iterator>,
46                                 typename Function::result_type,
47                                 single_pass_traversal_tag,
48                                 typename Function::result_type const&>
49           inherited;
50
51         typedef typename Function::result_type result_type;
52
53         friend class iterator_core_access;
54
55       public:
56         slot_call_iterator() {}
57
58         slot_call_iterator(Iterator iter_in, Iterator end_in, Function f)
59           : iter(iter_in), end(end_in), f(f), cache()
60         {
61           iter = std::find_if(iter, end, std::not1(is_disconnected()));
62         }
63
64         typename inherited::reference
65         dereference() const
66         {
67           if (!cache.get()) {
68             cache.reset(new cached_return_value<result_type>(f(*iter)));
69           }
70
71           return cache->value;
72         }
73
74         void increment()
75         {
76           iter = std::find_if(++iter, end, std::not1(is_disconnected()));
77           cache.reset();
78         }
79
80         bool equal(const slot_call_iterator& other) const
81         {
82           iter = std::find_if(iter, end, std::not1(is_disconnected()));
83           other.iter = std::find_if(other.iter, other.end,
84                                     std::not1(is_disconnected()));
85           return iter == other.iter;
86         }
87
88       private:
89         mutable Iterator iter;
90         Iterator end;
91         Function f;
92         mutable shared_ptr< cached_return_value<result_type> > cache;
93       };
94     } // end namespace detail
95   } // end namespace BOOST_SIGNALS_NAMESPACE
96 } // end namespace boost
97
98 #ifdef BOOST_HAS_ABI_HEADERS
99 #  include BOOST_ABI_SUFFIX
100 #endif
101
102 #endif // BOOST_SIGNALS_SLOT_CALL_ITERATOR