diff --git a/include/boost/smart_ptr/enable_shared_from_raw.hpp b/include/boost/smart_ptr/enable_shared_from_raw.hpp index 5ce23d7..b147a01 100644 --- a/include/boost/smart_ptr/enable_shared_from_raw.hpp +++ b/include/boost/smart_ptr/enable_shared_from_raw.hpp @@ -21,6 +21,7 @@ namespace boost { template boost::shared_ptr shared_from_raw(T *); +template boost::weak_ptr weak_from_raw(T *); namespace detail { @@ -72,6 +73,7 @@ public: private: template friend class shared_ptr; template friend boost::shared_ptr shared_from_raw(T *); + template friend boost::weak_ptr weak_from_raw(T *); template< class X, class Y > friend inline void detail::sp_enable_shared_from_this( boost::shared_ptr * ppx, Y const * py, boost::enable_shared_from_raw const * pe ); #endif @@ -114,9 +116,19 @@ private: template boost::shared_ptr shared_from_raw(T *p) { + BOOST_ASSERT(p != 0); return boost::shared_ptr(p->enable_shared_from_raw::shared_from_this(), p); } +template +boost::weak_ptr weak_from_raw(T *p) +{ + BOOST_ASSERT(p != 0); + boost::weak_ptr result; + result._internal_aliasing_assign(p->enable_shared_from_raw::weak_this_, p); + return result; +} + namespace detail { template< class X, class Y > inline void sp_enable_shared_from_this( boost::shared_ptr * ppx, Y const * py, boost::enable_shared_from_raw const * pe ) diff --git a/include/boost/smart_ptr/weak_ptr.hpp b/include/boost/smart_ptr/weak_ptr.hpp index 621c433..1ccbaf9 100644 --- a/include/boost/smart_ptr/weak_ptr.hpp +++ b/include/boost/smart_ptr/weak_ptr.hpp @@ -183,10 +183,11 @@ public: pn.swap(other.pn); } - void _internal_assign(T * px2, boost::detail::shared_count const & pn2) + template + void _internal_aliasing_assign(weak_ptr const & r, T * px2) { px = px2; - pn = pn2; + pn = r.pn; } template bool _internal_less(weak_ptr const & rhs) const @@ -225,6 +226,6 @@ template void swap(weak_ptr & a, weak_ptr & b) #ifdef BOOST_MSVC # pragma warning(pop) -#endif +#endif #endif // #ifndef BOOST_SMART_PTR_WEAK_PTR_HPP_INCLUDED diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index db4bfb1..815ac8f 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -59,6 +59,7 @@ import testing ; [ run sp_recursive_assign_rv_test.cpp ] [ run sp_recursive_assign2_rv_test.cpp ] [ run esft_constructor_test.cpp ] + [ run enable_shared_from_raw_test.cpp ] [ compile-fail auto_ptr_lv_fail.cpp ] [ run atomic_count_test2.cpp ] ; diff --git a/test/enable_shared_from_raw_test.cpp b/test/enable_shared_from_raw_test.cpp new file mode 100644 index 0000000..ba95ecc --- /dev/null +++ b/test/enable_shared_from_raw_test.cpp @@ -0,0 +1,39 @@ +#include + +// +// weak_from_raw_test.cpp +// +// Copyright (c) 2009 Frank Mori Hess +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// + + +#include + +#include + + +struct X: public boost::enable_shared_from_raw +{}; + +void basic_weak_from_raw_test() +{ + X *p(new X); + boost::weak_ptr weak = boost::weak_from_raw(p); + BOOST_TEST(weak.expired()); + boost::shared_ptr shared(p); + weak = boost::weak_from_raw(p); + BOOST_TEST(weak.expired() == false); + boost::shared_ptr shared2(weak); + BOOST_TEST((shared < shared2 || shared2 < shared) == false); + BOOST_TEST(shared.get() == p); +} + +int main() +{ + basic_weak_from_raw_test(); + return boost::report_errors(); +}