]> git.lyx.org Git - lyx.git/blob - boost/boost/signals/trackable.hpp
Boost 1.31.0
[lyx.git] / boost / boost / signals / trackable.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_TRACKABLE_HPP
11 #define BOOST_SIGNALS_TRACKABLE_HPP
12
13 #include <boost/type_traits.hpp>
14 #include <boost/signals/connection.hpp>
15 #include <boost/pending/ct_if.hpp>
16 #include <boost/ref.hpp>
17 #include <boost/utility/addressof.hpp>
18 #include <list>
19 #include <vector>
20
21 #ifdef BOOST_HAS_ABI_HEADERS
22 #  include BOOST_ABI_PREFIX
23 #endif
24
25 namespace boost {
26
27 namespace BOOST_SIGNALS_NAMESPACE {
28   // Base class for "trackable" objects that can be tracked when they are
29   // bound in slot target functions. When a trackable object is destroyed,
30   // the signal/slot connections are disconnected automatically.
31   class BOOST_SIGNALS_DECL trackable {
32   private:
33     static void signal_disconnected(void* obj, void* data);
34
35     friend class detail::signal_base_impl;
36     friend class detail::slot_base;
37     void signal_connected(connection, BOOST_SIGNALS_NAMESPACE::detail::bound_object&) const;
38
39   protected:
40     trackable() : connected_signals(), dying(false) {}
41     trackable(const trackable&) : connected_signals(), dying(false) {}
42     ~trackable();
43
44     trackable& operator=(const trackable&)
45     {
46       connected_signals.clear();
47       return *this;
48     }
49
50   private:
51     typedef std::list<connection> connection_list;
52     typedef connection_list::iterator connection_iterator;
53
54     // List of connections that this object is part of
55     mutable connection_list connected_signals;
56
57     // True when the object is being destroyed
58     mutable bool dying;
59   };
60
61   namespace detail {
62     template<bool Cond> struct truth {};
63
64     // A visitor that adds each trackable object to a vector
65     class bound_objects_visitor {
66     public:
67       bound_objects_visitor(std::vector<const trackable*>& v) :
68         bound_objects(v)
69       {
70       }
71
72       template<typename T>
73       void operator()(const T& t) const
74       {
75         decode(t, 0);
76       }
77
78     private:
79       // decode() decides between a reference wrapper and anything else
80       template<typename T>
81       void decode(const reference_wrapper<T>& t, int) const
82       {
83         add_if_trackable(t.get_pointer());
84       }
85
86       template<typename T>
87       void decode(const T& t, long) const
88       {
89         typedef truth<(is_pointer<T>::value)> is_a_pointer;
90         maybe_get_pointer(t, is_a_pointer());
91       }
92
93       // maybe_get_pointer() decides between a pointer and a non-pointer
94       template<typename T>
95       void maybe_get_pointer(const T& t, truth<true>) const
96       {
97         add_if_trackable(t);
98       }
99
100       template<typename T>
101       void maybe_get_pointer(const T& t, truth<false>) const
102       {
103         // Take the address of this object, because the object itself may be
104         // trackable
105         add_if_trackable(addressof(t));
106       }
107
108       // add_if_trackable() adds trackable objects to the list of bound objects
109       inline void add_if_trackable(const trackable* b) const
110       {
111         if (b) {
112           bound_objects.push_back(b);
113         }
114       }
115
116       inline void add_if_trackable(const void*) const
117       {
118       }
119
120       template<typename R>
121       inline void add_if_trackable(R (*)()) const
122       {
123       }
124
125       template<typename R, typename T1>
126       inline void add_if_trackable(R (*)(T1)) const
127       {
128       }
129
130       template<typename R, typename T1, typename T2>
131       inline void add_if_trackable(R (*)(T1, T2)) const
132       {
133       }
134
135       template<typename R, typename T1, typename T2, typename T3>
136       inline void add_if_trackable(R (*)(T1, T2, T3)) const
137       {
138       }
139
140       template<typename R, typename T1, typename T2, typename T3, typename T4>
141       inline void add_if_trackable(R (*)(T1, T2, T3, T4)) const
142       {
143       }
144
145       template<typename R, typename T1, typename T2, typename T3, typename T4,
146                typename T5>
147       inline void add_if_trackable(R (*)(T1, T2, T3, T4, T5)) const
148       {
149       }
150
151       template<typename R, typename T1, typename T2, typename T3, typename T4,
152                typename T5, typename T6>
153       inline void add_if_trackable(R (*)(T1, T2, T3, T4, T5, T6)) const
154       {
155       }
156
157       template<typename R, typename T1, typename T2, typename T3, typename T4,
158                typename T5, typename T6, typename T7>
159       inline void add_if_trackable(R (*)(T1, T2, T3, T4, T5, T6, T7)) const
160       {
161       }
162
163       template<typename R, typename T1, typename T2, typename T3, typename T4,
164                typename T5, typename T6, typename T7, typename T8>
165       inline void add_if_trackable(R (*)(T1, T2, T3, T4, T5, T6, T7, T8)) const
166       {
167       }
168
169       template<typename R, typename T1, typename T2, typename T3, typename T4,
170                typename T5, typename T6, typename T7, typename T8, typename T9>
171       inline void
172       add_if_trackable(R (*)(T1, T2, T3, T4, T5, T6, T7, T8, T9)) const
173       {
174       }
175
176       template<typename R, typename T1, typename T2, typename T3, typename T4,
177                typename T5, typename T6, typename T7, typename T8, typename T9,
178                typename T10>
179       inline void
180       add_if_trackable(R (*)(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10)) const
181       {
182       }
183
184       std::vector<const trackable*>& bound_objects;
185     };
186   } // end namespace detail
187 } // end namespace BOOST_SIGNALS_NAMESPACE
188
189 } // end namespace boost
190
191 #ifdef BOOST_HAS_ABI_HEADERS
192 #  include BOOST_ABI_PREFIX
193 #endif
194
195 #endif // BOOST_SIGNALS_TRACKABLE_HPP