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/assert.hpp> 17 #include <boost/scoped_ptr.hpp> 18 #include <boost/smart_ptr/bad_weak_ptr.hpp> 19 #include <boost/utility/swap.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 { ~foreign_shared_ptr_impl_baseboost::signals2::detail::foreign_shared_ptr_impl_base63 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: foreign_shared_ptr_impl(const FSP & p)71 foreign_shared_ptr_impl(const FSP &p): _p(p) 72 {} clone() const73 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: foreign_void_shared_ptr()84 foreign_void_shared_ptr(): 85 _p(0) 86 {} foreign_void_shared_ptr(const foreign_void_shared_ptr & other)87 foreign_void_shared_ptr(const foreign_void_shared_ptr &other): 88 _p(other._p->clone()) 89 {} 90 template<typename FSP> foreign_void_shared_ptr(const FSP & fsp)91 explicit foreign_void_shared_ptr(const FSP &fsp): 92 _p(new foreign_shared_ptr_impl<FSP>(fsp)) 93 {} ~foreign_void_shared_ptr()94 ~foreign_void_shared_ptr() 95 { 96 delete _p; 97 } operator =(const foreign_void_shared_ptr & other)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 } swap(foreign_void_shared_ptr & other)104 void swap(foreign_void_shared_ptr &other) 105 { 106 boost::swap(_p, other._p); 107 } 108 private: 109 foreign_shared_ptr_impl_base *_p; 110 }; 111 112 struct foreign_weak_ptr_impl_base 113 { ~foreign_weak_ptr_impl_baseboost::signals2::detail::foreign_weak_ptr_impl_base114 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: foreign_weak_ptr_impl(const FWP & p)124 foreign_weak_ptr_impl(const FWP &p): _p(p) 125 {} lock() const126 virtual foreign_void_shared_ptr lock() const 127 { 128 return foreign_void_shared_ptr(_p.lock()); 129 } expired() const130 virtual bool expired() const 131 { 132 return _p.expired(); 133 } clone() const134 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: foreign_void_weak_ptr()145 foreign_void_weak_ptr() 146 {} foreign_void_weak_ptr(const foreign_void_weak_ptr & other)147 foreign_void_weak_ptr(const foreign_void_weak_ptr &other): 148 _p(other._p->clone()) 149 {} 150 template<typename FWP> foreign_void_weak_ptr(const FWP & fwp)151 explicit foreign_void_weak_ptr(const FWP &fwp): 152 _p(new foreign_weak_ptr_impl<FWP>(fwp)) 153 {} operator =(const foreign_void_weak_ptr & other)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 } swap(foreign_void_weak_ptr & other)160 void swap(foreign_void_weak_ptr &other) 161 { 162 boost::swap(_p, other._p); 163 } lock() const164 foreign_void_shared_ptr lock() const 165 { 166 return _p->lock(); 167 } expired() const168 bool expired() const 169 { 170 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 181