Ticket #1696: enable_shared_from_this_proof_of_concept.patch
File enable_shared_from_this_proof_of_concept.patch, 4.4 KB (added by , 15 years ago) |
---|
-
boost/enable_shared_from_this.hpp
23 23 24 24 template<class T> class enable_shared_from_this 25 25 { 26 void init_internal_shared_once() const 27 { 28 if(_owned == false && _internal_shared_this == 0) 29 { 30 _internal_shared_this = shared_ptr<T>(dynamic_cast<T *>(const_cast<enable_shared_from_this*>(this)), 31 &_internal_shared_this_deleter, detail::ignore_shared_from_this_tag()); 32 BOOST_ASSERT(_internal_shared_this.get() == this); 33 _internal_weak_this = _internal_shared_this; 34 } 35 } 36 26 37 protected: 27 38 28 enable_shared_from_this() 39 enable_shared_from_this(): 40 _owned(false) 29 41 { 30 42 } 31 43 … … 38 50 return *this; 39 51 } 40 52 41 ~enable_shared_from_this()53 virtual ~enable_shared_from_this() 42 54 { 43 55 } 44 56 … … 46 58 47 59 shared_ptr<T> shared_from_this() 48 60 { 61 init_internal_shared_once(); 49 62 shared_ptr<T> p(_internal_weak_this); 50 63 BOOST_ASSERT(p.get() == this); 51 64 return p; … … 53 66 54 67 shared_ptr<T const> shared_from_this() const 55 68 { 69 init_internal_shared_once(); 56 70 shared_ptr<T const> p(_internal_weak_this); 57 71 BOOST_ASSERT(p.get() == this); 58 72 return p; 59 73 } 60 74 75 bool owned() const 76 { 77 return _owned; 78 } 79 80 void _internal_set_user_deleter(const detail::shared_count &user_deleter) const 81 { 82 init_internal_shared_once(); 83 _user_deleter = user_deleter; 84 } 85 static void _internal_shared_this_deleter(const enable_shared_from_this *obj) 86 { 87 detail::shared_count().swap(obj->_user_deleter); 88 } 89 61 90 // Note: No, you don't need to initialize _internal_weak_this 62 91 // 63 92 // Please read the documentation, not the code … … 65 94 // http://www.boost.org/libs/smart_ptr/enable_shared_from_this.html 66 95 67 96 typedef T _internal_element_type; // for bcc 5.5.1 97 mutable shared_ptr<_internal_element_type> _internal_shared_this; 98 mutable detail::shared_count _user_deleter; 68 99 mutable weak_ptr<_internal_element_type> _internal_weak_this; 100 mutable bool _owned; 69 101 }; 70 102 71 103 } // namespace boost -
boost/shared_ptr.hpp
90 90 91 91 // enable_shared_from_this support 92 92 93 template<class T, class Y> void sp_enable_shared_from_this( shared_count const & pn, boost::enable_shared_from_this<T> const * pe, Y const * px ) 93 struct ignore_shared_from_this_tag {}; 94 95 template<class T, class Y> void sp_enable_shared_from_this( shared_count & pn, boost::enable_shared_from_this<T> const * pe, Y const * px) 94 96 { 95 if(pe != 0) pe->_internal_weak_this._internal_assign(const_cast<Y*>(px), pn); 97 if(pe != 0) 98 { 99 pe->_internal_set_user_deleter(pn); 100 pn.swap(pe->_internal_shared_this.pn); 101 pe->_internal_shared_this.reset(); 102 pe->_owned = true; 96 103 } 104 } 97 105 98 106 #ifdef _MANAGED 99 107 … … 104 112 template<class T> sp_any_pointer( T* ) {} 105 113 }; 106 114 107 inline void sp_enable_shared_from_this( shared_count const& /*pn*/, sp_any_pointer, sp_any_pointer )115 inline void sp_enable_shared_from_this( shared_count & /*pn*/, sp_any_pointer, sp_any_pointer ) 108 116 { 109 117 } 110 118 … … 115 123 # pragma set woff 3506 116 124 #endif 117 125 118 inline void sp_enable_shared_from_this( shared_count const& /*pn*/, ... )126 inline void sp_enable_shared_from_this( shared_count & /*pn*/, ... ) 119 127 { 120 128 } 121 129 … … 186 194 boost::detail::sp_enable_shared_from_this( pn, p, p ); 187 195 } 188 196 197 // constructor that doesn't trigger enable_shared_from_this code, needed 198 // for enable_shared_from_this internal implementation 199 template<class Y, class D> shared_ptr(Y * p, D d, detail::ignore_shared_from_this_tag tag): 200 px(p), pn(p, d) 201 {} 202 203 189 204 // As above, but with allocator. A's copy constructor shall not throw. 190 205 191 206 template<class Y, class D, class A> shared_ptr( Y * p, D d, A a ): px( p ), pn( p, d, a ) … … 480 495 #endif 481 496 482 497 T * px; // contained pointer 498 /*yikes! made pn public to get this hack working */ 499 public: 483 500 boost::detail::shared_count pn; // reference counter 484 501 485 502 }; // shared_ptr