Line data Source code
1 : // Boost.Signals2 library 2 : 3 : // Copyright Frank Mori Hess 2007-2008. 4 : // Copyright Timmo Stange 2007. 5 : // Copyright Douglas Gregor 2001-2004. Use, modification and 6 : // distribution is subject to the Boost Software License, Version 7 : // 1.0. (See accompanying file LICENSE_1_0.txt or copy at 8 : // http://www.boost.org/LICENSE_1_0.txt) 9 : 10 : // For more information, see http://www.boost.org 11 : 12 : #ifndef BOOST_SIGNALS2_TRACKED_OBJECTS_VISITOR_HPP 13 : #define BOOST_SIGNALS2_TRACKED_OBJECTS_VISITOR_HPP 14 : 15 : #include <boost/core/ref.hpp> 16 : #include <boost/mpl/bool.hpp> 17 : #include <boost/signals2/detail/signals_common.hpp> 18 : #include <boost/signals2/slot_base.hpp> 19 : #include <boost/signals2/trackable.hpp> 20 : #include <boost/type_traits/is_function.hpp> 21 : #include <boost/type_traits/is_pointer.hpp> 22 : #include <boost/type_traits/remove_pointer.hpp> 23 : #include <boost/core/addressof.hpp> 24 : 25 : namespace boost 26 : { 27 : namespace signals2 28 : { 29 : namespace detail 30 : { 31 : // Visitor to collect tracked objects from a bound function. 32 : class tracked_objects_visitor 33 : { 34 : public: 35 1424 : tracked_objects_visitor(slot_base *slot) : slot_(slot) 36 1424 : {} 37 : template<typename T> 38 712 : void operator()(const T& t) const 39 : { 40 712 : m_visit_reference_wrapper(t, mpl::bool_<is_reference_wrapper<T>::value>()); 41 712 : } 42 : private: 43 : template<typename T> 44 : void m_visit_reference_wrapper(const reference_wrapper<T> &t, const mpl::bool_<true> &) const 45 : { 46 : m_visit_pointer(t.get_pointer(), mpl::bool_<true>()); 47 : } 48 : template<typename T> 49 712 : void m_visit_reference_wrapper(const T &t, const mpl::bool_<false> &) const 50 : { 51 712 : m_visit_pointer(t, mpl::bool_<is_pointer<T>::value>()); 52 712 : } 53 : template<typename T> 54 712 : void m_visit_pointer(const T &t, const mpl::bool_<true> &) const 55 : { 56 712 : m_visit_not_function_pointer(t, mpl::bool_<!is_function<typename remove_pointer<T>::type>::value>()); 57 712 : } 58 : template<typename T> 59 712 : void m_visit_pointer(const T &t, const mpl::bool_<false> &) const 60 : { 61 712 : m_visit_pointer(boost::addressof(t), mpl::bool_<true>()); 62 712 : } 63 : template<typename T> 64 712 : void m_visit_not_function_pointer(const T *t, const mpl::bool_<true> &) const 65 : { 66 712 : m_visit_signal(t, mpl::bool_<is_signal<T>::value>()); 67 712 : } 68 : template<typename T> 69 : void m_visit_not_function_pointer(const T &, const mpl::bool_<false> &) const 70 : {} 71 : template<typename T> 72 28 : void m_visit_signal(const T *signal, const mpl::bool_<true> &) const 73 : { 74 28 : if(signal) 75 28 : slot_->track_signal(*signal); 76 28 : } 77 : template<typename T> 78 684 : void m_visit_signal(const T &t, const mpl::bool_<false> &) const 79 : { 80 684 : add_if_trackable(t); 81 684 : } 82 : void add_if_trackable(const trackable *trackable) const 83 : { 84 : if(trackable) 85 : slot_->_tracked_objects.push_back(trackable->get_weak_ptr()); 86 : } 87 684 : void add_if_trackable(const void *) const {} 88 : 89 : mutable slot_base * slot_; 90 : }; 91 : 92 : 93 : } // end namespace detail 94 : } // end namespace signals2 95 : } // end namespace boost 96 : 97 : #endif // BOOST_SIGNALS2_TRACKED_OBJECTS_VISITOR_HPP 98 :