]> git.lyx.org Git - lyx.git/blob - boost/boost/signals/detail/slot_call_iterator.hpp
update boost to pre-1.30.0
[lyx.git] / boost / boost / signals / detail / slot_call_iterator.hpp
1 // Boost.Signals library
2 //
3 // Copyright (C) 2001-2002 Doug Gregor (gregod@cs.rpi.edu)
4 //
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.
10 //
11 // This software is provided "as is" without express or implied warranty,
12 // and with no claim as to its suitability for any purpose.
13  
14 // For more information, see http://www.boost.org
15
16 #ifndef BOOST_SIGNALS_SLOT_CALL_ITERATOR
17 #define BOOST_SIGNALS_SLOT_CALL_ITERATOR
18
19 #include <functional>
20 #include <boost/iterator_adaptors.hpp>
21 #include <boost/smart_ptr.hpp>
22 #include <boost/signals/connection.hpp>
23
24 namespace boost {
25   namespace BOOST_SIGNALS_NAMESPACE {
26     namespace detail {
27       // A cached return value from a slot
28       template<typename T>
29       struct cached_return_value {
30         cached_return_value(const T& t) : value(t) {}
31         
32         T value;
33       };
34
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 {
41       public:
42         typedef typename Function::result_type result_type;
43
44         slot_call_policies() {}
45
46         slot_call_policies(const Iterator& x, Function fi) :
47           end(x), f(fi), cache()
48         {
49         }
50         
51         void initialize(Iterator& x)
52         { 
53           x = std::find_if(x, end, std::not1(is_disconnected()));
54           cache.reset();
55         }
56         
57         template <class IteratorAdaptor>
58         typename IteratorAdaptor::reference 
59         dereference(const IteratorAdaptor& x) const
60         {
61           if (!cache.get()) {
62             cache.reset(new cached_return_value<result_type>(f(*x.base())));
63           }
64           
65           return cache->value;
66         }
67
68         template<typename IteratorAdaptor>
69         void increment(IteratorAdaptor& x)
70         {
71           ++x.base();
72           x.base() = std::find_if(x.base(), x.policies().end, 
73                                   std::not1(is_disconnected()));
74           cache.reset();
75         }
76         
77         template<typename IteratorAdaptor1, typename IteratorAdaptor2>
78         bool equal(const IteratorAdaptor1& x, const IteratorAdaptor2& y) const
79         {
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;
86           return xb == yb; 
87         }
88         
89       private:
90         Iterator end;
91         Function f;
92         mutable shared_ptr< cached_return_value<result_type> > cache;
93       };
94
95       template<typename Function, typename Iterator>
96       class slot_call_iterator_generator {
97       private:
98         typedef typename Function::result_type value_type;
99       public:
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;
104       };
105
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)
109       {
110         typedef slot_call_iterator_generator<Function, Iterator> gen;
111         typedef typename gen::type sc_iterator;
112         typedef typename gen::policy_type sc_policy;
113
114         return sc_iterator(first, sc_policy(last, f));
115       }
116     } // end namespace detail
117   } // end namespace BOOST_SIGNALS_NAMESPACE
118 } // end namespace boost
119 #endif // BOOST_SIGNALS_SLOT_CALL_ITERATOR