Boost logo

Boost :

Subject: [boost] [PATCH Boost.smart_ptr] Add intrusive_ptr<>::release()
From: Avi Kivity (avi_at_[hidden])
Date: 2013-12-02 07:57:06


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                        | 23 ++++++++++++++++++-----
 test/intrusive_ptr_test.cpp               |  7 +++++++
 3 files changed, 32 insertions(+), 5 deletions(-)
diff --git a/include/boost/smart_ptr/intrusive_ptr.hpp b/include/boost/smart_ptr/intrusive_ptr.hpp
index a855a10..8c73fe2 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 * release() 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..ef6238b 100644
--- a/intrusive_ptr.html
+++ b/intrusive_ptr.html
@@ -71,6 +71,7 @@
       T &amp; operator*() const; // never throws
       T * operator->() const; // never throws
       T * get() const; // never throws
+      T * release(); // never throws
 
       operator unspecified-bool-type() const; // never throws
 
@@ -174,11 +175,23 @@ intrusive_ptr &amp; operator=(T * r);</pre>
 			<p><b>Throws:</b> nothing.</p>
 		</blockquote>
 		<h3><a name="get">get</a></h3>
-		<pre>T * get() const; // never throws</pre>
-		<blockquote>
-			<p><b>Returns:</b> the stored pointer.</p>
-			<p><b>Throws:</b> nothing.</p>
-		</blockquote>
+                <pre>T * get() const; // never throws</pre>
+                <blockquote>
+                        <p><b>Returns:</b> the stored pointer.</p>
+                        <p><b>Throws:</b> nothing.</p>
+                </blockquote>
+                <h3><a name="release">release</a></h3>
+                <pre>T * release(); // never throws</pre>
+                <blockquote>
+                        <p><b>Returns:</b> the stored pointer.</p>
+                        <p><b>Throws:</b> nothing.</p>
+                        <p><b>Postconditions:</b> <code>get() == 0</code>.</p>
+                        <p><b>Notes:</b> The returned pointer has an elevated reference count. This 
+                                 allows conversion of an <b>intrusive_ptr</b> 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.</p>
+                </blockquote>
 		<h3><a name="conversions">conversions</a></h3>
 		<pre>operator <i>unspecified-bool-type</i> () const; // never throws</pre>
 		<blockquote>
diff --git a/test/intrusive_ptr_test.cpp b/test/intrusive_ptr_test.cpp
index 614a9cb..90248fe 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<X> px(new X);
+        X* released = px.release();
+        BOOST_TEST(released->use_count() == 1);
+        delete released;
+    }
 }
 
 } // namespace n_access
-- 
1.8.3.1

Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk