|
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