source: NonGTP/Boost/boost/signals/trackable.hpp @ 857

Revision 857, 5.7 KB checked in by igarcia, 18 years ago (diff)
Line 
1// Boost.Signals library
2
3// Copyright Douglas Gregor 2001-2004. 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
25namespace boost {
26
27namespace 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(boost::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_SUFFIX
193#endif
194
195#endif // BOOST_SIGNALS_TRACKABLE_HPP
Note: See TracBrowser for help on using the repository browser.