diff --git a/include/boost/smart_ptr/intrusive_ptr.hpp b/include/boost/smart_ptr/intrusive_ptr.hpp index b6f5bcd..42fdd92 100644 --- a/include/boost/smart_ptr/intrusive_ptr.hpp +++ b/include/boost/smart_ptr/intrusive_ptr.hpp @@ -151,6 +151,13 @@ public: return px; } + T * detach() BOOST_NOEXCEPT + { + T * ret = px; + px = 0; + return ret; + } + T & operator*() const { BOOST_ASSERT( px != 0 ); diff --git a/intrusive_ptr.html b/intrusive_ptr.html index 562d27a..7028444 100644 --- a/intrusive_ptr.html +++ b/intrusive_ptr.html @@ -71,6 +71,7 @@ T & operator*() const; // never throws T * operator->() const; // never throws T * get() const; // never throws + T * detach(); // never throws operator unspecified-bool-type() const; // never throws @@ -179,6 +180,22 @@ intrusive_ptr & operator=(T * r);
Returns: the stored pointer.
Throws: nothing.
+T * detach(); // never throws+
+Returns: the stored pointer.
+Throws: nothing.
+Postconditions:
+get() == 0
.Notes: The returned pointer has an elevated reference count. This + allows conversion of an intrusive_ptr back to a raw pointer, + without the performance overhead of acquiring and dropping an extra + reference. It can be viewed as the complement of the + non-reference-incrementing constructor.
+Caution: Using
+detach
escapes the safety of automatic + reference counting provided byintrusive_ptr
. It should + by used only where strictly necessary (such as when interfacing to an + existing API), and when the implications are thoroughly understood.
operator unspecified-bool-type () const; // never throws
diff --git a/test/intrusive_ptr_test.cpp b/test/intrusive_ptr_test.cpp index 614a9cb..f53d75d 100644 --- a/test/intrusive_ptr_test.cpp +++ b/test/intrusive_ptr_test.cpp @@ -330,6 +330,13 @@ void test() BOOST_TEST(get_pointer(px) == px.get()); } + + { + boost::intrusive_ptrpx(new X); + X* detached = px.detach(); + BOOST_TEST(detached->use_count() == 1); + delete detached; + } } } // namespace n_access