File indexing completed on 2025-12-16 10:08:48
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012 #ifndef BOOST_SIGNALS2_SLOT_BASE_HPP
0013 #define BOOST_SIGNALS2_SLOT_BASE_HPP
0014
0015 #include <boost/shared_ptr.hpp>
0016 #include <boost/weak_ptr.hpp>
0017 #include <boost/signals2/detail/foreign_ptr.hpp>
0018 #include <boost/signals2/expired_slot.hpp>
0019 #include <boost/signals2/signal_base.hpp>
0020 #include <boost/throw_exception.hpp>
0021 #include <boost/variant/apply_visitor.hpp>
0022 #include <boost/variant/variant.hpp>
0023 #include <vector>
0024
0025 namespace boost
0026 {
0027 namespace signals2
0028 {
0029 namespace detail
0030 {
0031 class tracked_objects_visitor;
0032 class trackable_pointee;
0033
0034 typedef boost::variant<boost::weak_ptr<trackable_pointee>, boost::weak_ptr<void>, detail::foreign_void_weak_ptr > void_weak_ptr_variant;
0035 typedef boost::variant<boost::shared_ptr<void>, detail::foreign_void_shared_ptr > void_shared_ptr_variant;
0036 class lock_weak_ptr_visitor
0037 {
0038 public:
0039 typedef void_shared_ptr_variant result_type;
0040 template<typename WeakPtr>
0041 result_type operator()(const WeakPtr &wp) const
0042 {
0043 return wp.lock();
0044 }
0045
0046
0047 result_type operator()(const weak_ptr<trackable_pointee> &) const
0048 {
0049 return boost::shared_ptr<void>();
0050 }
0051 };
0052 class expired_weak_ptr_visitor
0053 {
0054 public:
0055 typedef bool result_type;
0056 template<typename WeakPtr>
0057 bool operator()(const WeakPtr &wp) const
0058 {
0059 return wp.expired();
0060 }
0061 };
0062 }
0063
0064 class slot_base
0065 {
0066 public:
0067 typedef std::vector<detail::void_weak_ptr_variant> tracked_container_type;
0068 typedef std::vector<detail::void_shared_ptr_variant> locked_container_type;
0069
0070 const tracked_container_type& tracked_objects() const {return _tracked_objects;}
0071 locked_container_type lock() const
0072 {
0073 locked_container_type locked_objects;
0074 tracked_container_type::const_iterator it;
0075 for(it = tracked_objects().begin(); it != tracked_objects().end(); ++it)
0076 {
0077 locked_objects.push_back(apply_visitor(detail::lock_weak_ptr_visitor(), *it));
0078 if(apply_visitor(detail::expired_weak_ptr_visitor(), *it))
0079 {
0080 boost::throw_exception(expired_slot());
0081 }
0082 }
0083 return locked_objects;
0084 }
0085 bool expired() const
0086 {
0087 tracked_container_type::const_iterator it;
0088 for(it = tracked_objects().begin(); it != tracked_objects().end(); ++it)
0089 {
0090 if(apply_visitor(detail::expired_weak_ptr_visitor(), *it)) return true;
0091 }
0092 return false;
0093 }
0094 protected:
0095 friend class detail::tracked_objects_visitor;
0096
0097 void track_signal(const signal_base &signal)
0098 {
0099 _tracked_objects.push_back(signal.lock_pimpl());
0100 }
0101
0102 tracked_container_type _tracked_objects;
0103 };
0104 }
0105 }
0106
0107 #endif