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_SLOT_BASE_HPP 13 : #define BOOST_SIGNALS2_SLOT_BASE_HPP 14 : 15 : #include <boost/shared_ptr.hpp> 16 : #include <boost/weak_ptr.hpp> 17 : #include <boost/signals2/detail/foreign_ptr.hpp> 18 : #include <boost/signals2/expired_slot.hpp> 19 : #include <boost/signals2/signal_base.hpp> 20 : #include <boost/throw_exception.hpp> 21 : #include <boost/variant/apply_visitor.hpp> 22 : #include <boost/variant/variant.hpp> 23 : #include <vector> 24 : 25 : namespace boost 26 : { 27 : namespace signals2 28 : { 29 : namespace detail 30 : { 31 : class tracked_objects_visitor; 32 : class trackable_pointee; 33 : 34 : typedef boost::variant<boost::weak_ptr<trackable_pointee>, boost::weak_ptr<void>, detail::foreign_void_weak_ptr > void_weak_ptr_variant; 35 : typedef boost::variant<boost::shared_ptr<void>, detail::foreign_void_shared_ptr > void_shared_ptr_variant; 36 : class lock_weak_ptr_visitor 37 : { 38 : public: 39 : typedef void_shared_ptr_variant result_type; 40 : template<typename WeakPtr> 41 104603 : result_type operator()(const WeakPtr &wp) const 42 : { 43 104603 : return wp.lock(); 44 0 : } 45 : // overload to prevent incrementing use count of shared_ptr associated 46 : // with signals2::trackable objects 47 0 : result_type operator()(const weak_ptr<trackable_pointee> &) const 48 : { 49 0 : return boost::shared_ptr<void>(); 50 0 : } 51 : }; 52 : class expired_weak_ptr_visitor 53 : { 54 : public: 55 : typedef bool result_type; 56 : template<typename WeakPtr> 57 105762 : bool operator()(const WeakPtr &wp) const 58 : { 59 105762 : return wp.expired(); 60 : } 61 : }; 62 : } 63 : 64 : class slot_base 65 : { 66 : public: 67 : typedef std::vector<detail::void_weak_ptr_variant> tracked_container_type; 68 : typedef std::vector<detail::void_shared_ptr_variant> locked_container_type; 69 : 70 866984 : const tracked_container_type& tracked_objects() const {return _tracked_objects;} 71 : locked_container_type lock() const 72 : { 73 : locked_container_type locked_objects; 74 : tracked_container_type::const_iterator it; 75 : for(it = tracked_objects().begin(); it != tracked_objects().end(); ++it) 76 : { 77 : locked_objects.push_back(apply_visitor(detail::lock_weak_ptr_visitor(), *it)); 78 : if(apply_visitor(detail::expired_weak_ptr_visitor(), *it)) 79 : { 80 : boost::throw_exception(expired_slot()); 81 : } 82 : } 83 : return locked_objects; 84 : } 85 5079 : bool expired() const 86 : { 87 5079 : tracked_container_type::const_iterator it; 88 6238 : for(it = tracked_objects().begin(); it != tracked_objects().end(); ++it) 89 : { 90 1159 : if(apply_visitor(detail::expired_weak_ptr_visitor(), *it)) return true; 91 1159 : } 92 5079 : return false; 93 5079 : } 94 : protected: 95 : friend class detail::tracked_objects_visitor; 96 : 97 6628 : void track_signal(const signal_base &signal) 98 : { 99 6628 : _tracked_objects.push_back(signal.lock_pimpl()); 100 6628 : } 101 : 102 : tracked_container_type _tracked_objects; 103 : }; 104 : } 105 : } // end namespace boost 106 : 107 : #endif // BOOST_SIGNALS2_SLOT_BASE_HPP