From 7cdfcff4835e4e77d48aac11aaac1f5f9162476a Mon Sep 17 00:00:00 2001 Message-Id: <7cdfcff4835e4e77d48aac11aaac1f5f9162476a.1386091519.git.avi@cloudius-systems.com> From: Avi Kivity Date: Mon, 2 Dec 2013 12:30:20 +0200 Subject: [PATCH] Add intrusive_ptr<>::detach() This provides a way to escape from automatic reference counting, and taking manual control of the reference. Useful when interfacing to a C API that expects a pointer with an elevated reference count. Similar to std::unique_ptr<>::release(). --- include/boost/smart_ptr/intrusive_ptr.hpp | 7 +++++++ intrusive_ptr.html | 17 +++++++++++++++++ test/intrusive_ptr_test.cpp | 7 +++++++ 3 files changed, 31 insertions(+) diff --git a/include/boost/smart_ptr/intrusive_ptr.hpp b/include/boost/smart_ptr/intrusive_ptr.hpp index a855a10..171dcbd 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.

+

detach

+
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 by intrusive_ptr. It should + by used only where strictly necessary (such as when interfacing to an + existing API), and when the implications are thoroughly understood.

+

conversions

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_ptr px(new X); + X* detached = px.detach(); + BOOST_TEST(detached->use_count() == 1); + delete detached; + } } } // namespace n_access -- 1.8.3.1