Chris@16: // Boost.Signals library Chris@16: Chris@16: // Copyright Douglas Gregor 2001-2004. Use, modification and Chris@16: // distribution is subject to the Boost Software License, Version Chris@16: // 1.0. (See accompanying file LICENSE_1_0.txt or copy at Chris@16: // http://www.boost.org/LICENSE_1_0.txt) Chris@16: Chris@16: // For more information, see http://www.boost.org Chris@16: Chris@16: #ifndef BOOST_SIGNALS_TRACKABLE_HPP Chris@16: #define BOOST_SIGNALS_TRACKABLE_HPP Chris@16: Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: Chris@16: #ifdef BOOST_HAS_ABI_HEADERS Chris@16: # include BOOST_ABI_PREFIX Chris@16: #endif Chris@16: Chris@16: namespace boost { Chris@16: Chris@16: namespace BOOST_SIGNALS_NAMESPACE { Chris@16: // Base class for "trackable" objects that can be tracked when they are Chris@16: // bound in slot target functions. When a trackable object is destroyed, Chris@16: // the signal/slot connections are disconnected automatically. Chris@16: class BOOST_SIGNALS_DECL trackable { Chris@16: private: Chris@16: static void signal_disconnected(void* obj, void* data); Chris@16: Chris@16: friend class detail::signal_base_impl; Chris@16: friend class detail::slot_base; Chris@16: void signal_connected(connection, BOOST_SIGNALS_NAMESPACE::detail::bound_object&) const; Chris@16: Chris@16: protected: Chris@16: trackable() : connected_signals(), dying(false) {} Chris@16: trackable(const trackable&) : connected_signals(), dying(false) {} Chris@16: ~trackable(); Chris@16: Chris@16: trackable& operator=(const trackable&) Chris@16: { Chris@16: dying = true; Chris@16: connected_signals.clear(); Chris@16: dying = false; Chris@16: return *this; Chris@16: } Chris@16: Chris@16: private: Chris@16: typedef std::list connection_list; Chris@16: typedef connection_list::iterator connection_iterator; Chris@16: Chris@16: // List of connections that this object is part of Chris@16: mutable connection_list connected_signals; Chris@16: Chris@16: // True when the object is being destroyed Chris@16: mutable bool dying; Chris@16: }; Chris@16: Chris@16: namespace detail { Chris@16: template struct truth {}; Chris@16: Chris@16: // A visitor that adds each trackable object to a vector Chris@16: class bound_objects_visitor { Chris@16: public: Chris@16: bound_objects_visitor(std::vector& v) : Chris@16: bound_objects(v) Chris@16: { Chris@16: } Chris@16: Chris@16: template Chris@16: void operator()(const T& t) const Chris@16: { Chris@16: decode(t, 0); Chris@16: } Chris@16: Chris@16: private: Chris@16: // decode() decides between a reference wrapper and anything else Chris@16: template Chris@16: void decode(const reference_wrapper& t, int) const Chris@16: { Chris@16: add_if_trackable(t.get_pointer()); Chris@16: } Chris@16: Chris@16: template Chris@16: void decode(const T& t, long) const Chris@16: { Chris@16: typedef truth<(is_pointer::value)> is_a_pointer; Chris@16: maybe_get_pointer(t, is_a_pointer()); Chris@16: } Chris@16: Chris@16: // maybe_get_pointer() decides between a pointer and a non-pointer Chris@16: template Chris@16: void maybe_get_pointer(const T& t, truth) const Chris@16: { Chris@16: add_if_trackable(t); Chris@16: } Chris@16: Chris@16: template Chris@16: void maybe_get_pointer(const T& t, truth) const Chris@16: { Chris@16: // Take the address of this object, because the object itself may be Chris@16: // trackable Chris@16: add_if_trackable(boost::addressof(t)); Chris@16: } Chris@16: Chris@16: // add_if_trackable() adds trackable objects to the list of bound objects Chris@16: inline void add_if_trackable(const trackable* b) const Chris@16: { Chris@16: if (b) { Chris@16: bound_objects.push_back(b); Chris@16: } Chris@16: } Chris@16: Chris@16: inline void add_if_trackable(const void*) const { } Chris@16: Chris@16: template Chris@16: inline void add_if_trackable(R (*)()) const { } Chris@16: Chris@16: template Chris@16: inline void add_if_trackable(R (*)(T1)) const { } Chris@16: Chris@16: template Chris@16: inline void add_if_trackable(R (*)(T1, T2)) const { } Chris@16: Chris@16: template Chris@16: inline void add_if_trackable(R (*)(T1, T2, T3)) const { } Chris@16: Chris@16: template Chris@16: inline void add_if_trackable(R (*)(T1, T2, T3, T4)) const { } Chris@16: Chris@16: template Chris@16: inline void add_if_trackable(R (*)(T1, T2, T3, T4, T5)) const { } Chris@16: Chris@16: template Chris@16: inline void add_if_trackable(R (*)(T1, T2, T3, T4, T5, T6)) const { } Chris@16: Chris@16: template Chris@16: inline void add_if_trackable(R (*)(T1, T2, T3, T4, T5, T6, T7)) const { } Chris@16: Chris@16: template Chris@16: inline void Chris@16: add_if_trackable(R (*)(T1, T2, T3, T4, T5, T6, T7, T8)) const { } Chris@16: Chris@16: template Chris@16: inline void Chris@16: add_if_trackable(R (*)(T1, T2, T3, T4, T5, T6, T7, T8, T9)) const { } Chris@16: Chris@16: template Chris@16: inline void Chris@16: add_if_trackable(R (*)(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10)) const { } Chris@16: Chris@16: std::vector& bound_objects; Chris@16: }; Chris@16: } // end namespace detail Chris@16: } // end namespace BOOST_SIGNALS_NAMESPACE Chris@16: Chris@16: } // end namespace boost Chris@16: Chris@16: #ifdef BOOST_HAS_ABI_HEADERS Chris@16: # include BOOST_ABI_SUFFIX Chris@16: #endif Chris@16: Chris@16: #endif // BOOST_SIGNALS_TRACKABLE_HPP