Line data Source code
1 : 2 : // helper code for dealing with tracking non-boost shared_ptr/weak_ptr 3 : 4 : // Copyright Frank Mori Hess 2009. 5 : // Distributed under the Boost Software License, Version 6 : // 1.0. (See accompanying file LICENSE_1_0.txt or copy at 7 : // http://www.boost.org/LICENSE_1_0.txt) 8 : 9 : // See http://www.boost.org/libs/signals2 for library home page. 10 : 11 : #ifndef BOOST_SIGNALS2_FOREIGN_PTR_HPP 12 : #define BOOST_SIGNALS2_FOREIGN_PTR_HPP 13 : 14 : #include <algorithm> 15 : #include <boost/config.hpp> 16 : #include <boost/core/invoke_swap.hpp> 17 : #include <boost/assert.hpp> 18 : #include <boost/scoped_ptr.hpp> 19 : #include <boost/smart_ptr/bad_weak_ptr.hpp> 20 : 21 : #ifndef BOOST_NO_CXX11_SMART_PTR 22 : #include <memory> 23 : #endif 24 : 25 : namespace boost 26 : { 27 : template<typename T> class shared_ptr; 28 : template<typename T> class weak_ptr; 29 : 30 : namespace signals2 31 : { 32 : template<typename WeakPtr> struct weak_ptr_traits 33 : {}; 34 : template<typename T> struct weak_ptr_traits<boost::weak_ptr<T> > 35 : { 36 : typedef boost::shared_ptr<T> shared_type; 37 : }; 38 : #ifndef BOOST_NO_CXX11_SMART_PTR 39 : template<typename T> struct weak_ptr_traits<std::weak_ptr<T> > 40 : { 41 : typedef std::shared_ptr<T> shared_type; 42 : }; 43 : #endif 44 : 45 : template<typename SharedPtr> struct shared_ptr_traits 46 : {}; 47 : 48 : template<typename T> struct shared_ptr_traits<boost::shared_ptr<T> > 49 : { 50 : typedef boost::weak_ptr<T> weak_type; 51 : }; 52 : #ifndef BOOST_NO_CXX11_SMART_PTR 53 : template<typename T> struct shared_ptr_traits<std::shared_ptr<T> > 54 : { 55 : typedef std::weak_ptr<T> weak_type; 56 : }; 57 : #endif 58 : 59 : namespace detail 60 : { 61 : struct foreign_shared_ptr_impl_base 62 : { 63 : virtual ~foreign_shared_ptr_impl_base() {} 64 : virtual foreign_shared_ptr_impl_base * clone() const = 0; 65 : }; 66 : 67 : template<typename FSP> 68 : class foreign_shared_ptr_impl: public foreign_shared_ptr_impl_base 69 : { 70 : public: 71 : foreign_shared_ptr_impl(const FSP &p): _p(p) 72 : {} 73 : virtual foreign_shared_ptr_impl * clone() const 74 : { 75 : return new foreign_shared_ptr_impl(*this); 76 : } 77 : private: 78 : FSP _p; 79 : }; 80 : 81 : class foreign_void_shared_ptr 82 : { 83 : public: 84 : foreign_void_shared_ptr(): 85 : _p(0) 86 : {} 87 0 : foreign_void_shared_ptr(const foreign_void_shared_ptr &other): 88 0 : _p(other._p->clone()) 89 0 : {} 90 : template<typename FSP> 91 : explicit foreign_void_shared_ptr(const FSP &fsp): 92 : _p(new foreign_shared_ptr_impl<FSP>(fsp)) 93 : {} 94 0 : ~foreign_void_shared_ptr() 95 0 : { 96 0 : delete _p; 97 0 : } 98 : foreign_void_shared_ptr & operator=(const foreign_void_shared_ptr &other) 99 : { 100 : if(&other == this) return *this; 101 : foreign_void_shared_ptr(other).swap(*this); 102 : return *this; 103 : } 104 : void swap(foreign_void_shared_ptr &other) 105 : { 106 : boost::core::invoke_swap(_p, other._p); 107 : } 108 : private: 109 : foreign_shared_ptr_impl_base *_p; 110 : }; 111 : 112 : struct foreign_weak_ptr_impl_base 113 : { 114 : virtual ~foreign_weak_ptr_impl_base() {} 115 : virtual foreign_void_shared_ptr lock() const = 0; 116 : virtual bool expired() const = 0; 117 : virtual foreign_weak_ptr_impl_base * clone() const = 0; 118 : }; 119 : 120 : template<typename FWP> 121 : class foreign_weak_ptr_impl: public foreign_weak_ptr_impl_base 122 : { 123 : public: 124 : foreign_weak_ptr_impl(const FWP &p): _p(p) 125 : {} 126 : virtual foreign_void_shared_ptr lock() const 127 : { 128 : return foreign_void_shared_ptr(_p.lock()); 129 : } 130 : virtual bool expired() const 131 : { 132 : return _p.expired(); 133 : } 134 : virtual foreign_weak_ptr_impl * clone() const 135 : { 136 : return new foreign_weak_ptr_impl(*this); 137 : } 138 : private: 139 : FWP _p; 140 : }; 141 : 142 : class foreign_void_weak_ptr 143 : { 144 : public: 145 : foreign_void_weak_ptr() 146 : {} 147 0 : foreign_void_weak_ptr(const foreign_void_weak_ptr &other): 148 0 : _p(other._p->clone()) 149 0 : {} 150 : template<typename FWP> 151 : explicit foreign_void_weak_ptr(const FWP &fwp): 152 : _p(new foreign_weak_ptr_impl<FWP>(fwp)) 153 : {} 154 : foreign_void_weak_ptr & operator=(const foreign_void_weak_ptr &other) 155 : { 156 : if(&other == this) return *this; 157 : foreign_void_weak_ptr(other).swap(*this); 158 : return *this; 159 : } 160 : void swap(foreign_void_weak_ptr &other) 161 : { 162 : boost::core::invoke_swap(_p, other._p); 163 : } 164 0 : foreign_void_shared_ptr lock() const 165 : { 166 0 : return _p->lock(); 167 : } 168 0 : bool expired() const 169 : { 170 0 : return _p->expired(); 171 : } 172 : private: 173 : boost::scoped_ptr<foreign_weak_ptr_impl_base> _p; 174 : }; 175 : } // namespace detail 176 : 177 : } // namespace signals2 178 : } // namespace boost 179 : 180 : #endif // BOOST_SIGNALS2_FOREIGN_PTR_HPP