Boost logo

Boost :

From: Frank Mori Hess (frank.hess_at_[hidden])
Date: 2008-03-17 17:31:52


-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Here's a proof-of-concept patch to svn trunk for enable_shared_from_this.hpp
and shared_ptr.hpp. After applying the patch, you should be able to use
shared_from_this() successfully from a constructor. It's only a
proof-of-concept because it includes some quick-and-dirty nastiness (it makes
the shared_count in shared_ptr public!).

- --
Frank
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.6 (GNU/Linux)

iD8DBQFH3uNL5vihyNWuA4URAtSVAKCLPq3Def6CUWDN4C42YmiLNv9XogCgyHBb
j/qQOCA+lo1GUj6tQ5J3N14=
=0xDw
-----END PGP SIGNATURE-----

--Boundary-00=_LNu3HI13NubLkRO
Content-Type: text/x-diff; charset="iso-8859-1";
        name="enable_shared_from_this_proof_of_concept.patch"
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment;
        filename="enable_shared_from_this_proof_of_concept.patch"

Index: boost/enable_shared_from_this.hpp
===================================================================
--- boost/enable_shared_from_this.hpp (revision 43677)
+++ boost/enable_shared_from_this.hpp (working copy)
@@ -25,7 +25,10 @@
 {
 protected:
 
- enable_shared_from_this()
+ enable_shared_from_this():
+ _internal_shared_this(static_cast<T*>(this), &_internal_shared_this_deleter, detail::ignore_shared_from_this_tag()),
+ _internal_weak_this(_internal_shared_this),
+ _owned(false)
     {
     }
 
@@ -58,6 +61,16 @@
         return p;
     }
 
+ bool owned() const
+ {
+ return _owned;
+ }
+
+ static void _internal_shared_this_deleter(const enable_shared_from_this *obj)
+ {
+ detail::shared_count().swap(obj->_user_deleter);
+ }
+
 // Note: No, you don't need to initialize _internal_weak_this
 //
 // Please read the documentation, not the code
@@ -65,7 +78,10 @@
 // http://www.boost.org/libs/smart_ptr/enable_shared_from_this.html
 
     typedef T _internal_element_type; // for bcc 5.5.1
+ mutable shared_ptr<_internal_element_type> _internal_shared_this;
+ mutable detail::shared_count _user_deleter;
     mutable weak_ptr<_internal_element_type> _internal_weak_this;
+ mutable bool _owned;
 };
 
 } // namespace boost
Index: boost/shared_ptr.hpp
===================================================================
--- boost/shared_ptr.hpp (revision 43677)
+++ boost/shared_ptr.hpp (working copy)
@@ -90,10 +90,18 @@
 
 // enable_shared_from_this support
 
-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 )
+struct ignore_shared_from_this_tag {};
+
+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)
 {
- if(pe != 0) pe->_internal_weak_this._internal_assign(const_cast<Y*>(px), pn);
+ if(pe != 0)
+ {
+ pe->_user_deleter = pn;
+ pn.swap(pe->_internal_shared_this.pn);
+ pe->_internal_shared_this.reset();
+ pe->_owned = true;
 }
+}
 
 #ifdef _MANAGED
 
@@ -104,7 +112,7 @@
     template<class T> sp_any_pointer( T* ) {}
 };
 
-inline void sp_enable_shared_from_this( shared_count const & /*pn*/, sp_any_pointer, sp_any_pointer )
+inline void sp_enable_shared_from_this( shared_count & /*pn*/, sp_any_pointer, sp_any_pointer )
 {
 }
 
@@ -115,7 +123,7 @@
 # pragma set woff 3506
 #endif
 
-inline void sp_enable_shared_from_this( shared_count const & /*pn*/, ... )
+inline void sp_enable_shared_from_this( shared_count & /*pn*/, ... )
 {
 }
 
@@ -186,6 +194,13 @@
         boost::detail::sp_enable_shared_from_this( pn, p, p );
     }
 
+ // constructor that doesn't trigger enable_shared_from_this code, needed
+ // for enable_shared_from_this internal implementation
+ template<class Y, class D> shared_ptr(Y * p, D d, detail::ignore_shared_from_this_tag tag):
+ px(p), pn(p, d)
+ {}
+
+
     // As above, but with allocator. A's copy constructor shall not throw.
 
     template<class Y, class D, class A> shared_ptr( Y * p, D d, A a ): px( p ), pn( p, d, a )
@@ -480,6 +495,8 @@
 #endif
 
     T * px; // contained pointer
+/*yikes! made pn public to get this hack working */
+public:
     boost::detail::shared_count pn; // reference counter
 
 }; // shared_ptr

--Boundary-00=_LNu3HI13NubLkRO--


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk