diff --git a/enable_shared_from_this_test.cpp b/enable_shared_from_this_test.cpp index 66f9c17..8225a39 100644 --- a/enable_shared_from_this_test.cpp +++ b/enable_shared_from_this_test.cpp @@ -72,7 +72,10 @@ int main() return boost::report_errors(); } -class impl: public X, public Y, public boost::enable_shared_from_this +// virtual inheritance from Y to stress the implementation +// (prevents Y* -> impl* casts) + +class impl: public X, public virtual Y, public boost::enable_shared_from_this { public: @@ -88,8 +91,14 @@ public: } }; +// intermediate impl2 to stress the implementation + +class impl2: public impl +{ +}; + boost::shared_ptr createY() { - boost::shared_ptr pi(new impl); + boost::shared_ptr pi(new impl2); return pi; } diff --git a/include/boost/enable_shared_from_this.hpp b/include/boost/enable_shared_from_this.hpp index ae5d809..4dfdab6 100644 --- a/include/boost/enable_shared_from_this.hpp +++ b/include/boost/enable_shared_from_this.hpp @@ -28,28 +28,20 @@ public: shared_ptr shared_from_this() { - shared_ptr p(weak_this); + shared_ptr p(_internal_weak_this); BOOST_ASSERT(p.get() == this); return p; } shared_ptr shared_from_this() const { - shared_ptr p(weak_this); + shared_ptr p(_internal_weak_this); BOOST_ASSERT(p.get() == this); return p; } -#ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS - -private: - - template friend class shared_ptr; - -#endif - - typedef T element_type; // for bcc 5.5.1 - weak_ptr weak_this; + typedef T _internal_element_type; // for bcc 5.5.1 + weak_ptr<_internal_element_type> _internal_weak_this; }; } // namespace boost diff --git a/include/boost/shared_ptr.hpp b/include/boost/shared_ptr.hpp index b03a391..8fc45ea 100644 --- a/include/boost/shared_ptr.hpp +++ b/include/boost/shared_ptr.hpp @@ -39,6 +39,9 @@ namespace boost { +template class weak_ptr; +template class enable_shared_from_this; + namespace detail { @@ -65,6 +68,17 @@ template<> struct shared_ptr_traits #endif +// enable_shared_from_this support + +template void sp_enable_shared_from_this(boost::enable_shared_from_this * pe, Y * px, shared_count const & pn) +{ + pe->_internal_weak_this._internal_assign(px, pn); +} + +void sp_enable_shared_from_this(void const *, void const *, shared_count const &) +{ +} + } // namespace detail @@ -76,9 +90,6 @@ template<> struct shared_ptr_traits // is destroyed or reset. // -template class weak_ptr; -template class enable_shared_from_this; - template class shared_ptr { private: @@ -86,17 +97,6 @@ private: // Borland 5.5.1 specific workaround typedef shared_ptr this_type; - // enable_shared_from_this support - - template void sp_enable_shared_from_this(boost::enable_shared_from_this * q) - { - q->weak_this = *this; - } - - void sp_enable_shared_from_this(void *) - { - } - public: typedef T element_type; @@ -111,7 +111,7 @@ public: template explicit shared_ptr(Y * p): px(p), pn(p, checked_deleter()) // Y must be complete { - sp_enable_shared_from_this(p); + detail::sp_enable_shared_from_this(p, p, pn); } // @@ -122,7 +122,7 @@ public: template shared_ptr(Y * p, D d): px(p), pn(p, d) { - sp_enable_shared_from_this(p); + detail::sp_enable_shared_from_this(p, p, pn); } // generated copy constructor, assignment, destructor are fine... @@ -179,7 +179,7 @@ public: { Y * tmp = r.get(); pn = detail::shared_count(r); - sp_enable_shared_from_this(tmp); + detail::sp_enable_shared_from_this(tmp, tmp, pn); } #endif @@ -270,7 +270,7 @@ public: pn.swap(other.pn); } - bool less(this_type const & rhs) const // implementation detail, never throws + bool _internal_less(this_type const & rhs) const // implementation detail, never throws { return pn < rhs.pn; } @@ -316,7 +316,7 @@ template inline bool operator!=(shared_ptr const & a, shared_ptr template inline bool operator<(shared_ptr const & a, shared_ptr const & b) { - return a.less(b); + return a._internal_less(b); } template inline void swap(shared_ptr & a, shared_ptr & b) diff --git a/include/boost/weak_ptr.hpp b/include/boost/weak_ptr.hpp index b65309e..a4154ea 100644 --- a/include/boost/weak_ptr.hpp +++ b/include/boost/weak_ptr.hpp @@ -92,7 +92,13 @@ public: pn.swap(other.pn); } - bool less(this_type const & rhs) const // implementation detail, never throws + void _internal_assign(T * px2, detail::shared_count const & pn2) // implementation detail + { + px = px2; + pn = pn2; + } + + bool _internal_less(this_type const & rhs) const // implementation detail, never throws { return pn < rhs.pn; } @@ -116,7 +122,7 @@ private: template inline bool operator<(weak_ptr const & a, weak_ptr const & b) { - return a.less(b); + return a._internal_less(b); } template void swap(weak_ptr & a, weak_ptr & b)