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().
This commit is contained in:
Avi Kivity
2013-12-02 12:30:20 +02:00
committed by Peter Dimov
parent d7fa365843
commit 73153d5797
3 changed files with 31 additions and 0 deletions

View File

@ -151,6 +151,13 @@ public:
return px; return px;
} }
T * detach() BOOST_NOEXCEPT
{
T * ret = px;
px = 0;
return ret;
}
T & operator*() const T & operator*() const
{ {
BOOST_ASSERT( px != 0 ); BOOST_ASSERT( px != 0 );

View File

@ -71,6 +71,7 @@
T &amp; <A href="#indirection" >operator*</A>() const; // never throws T &amp; <A href="#indirection" >operator*</A>() const; // never throws
T * <A href="#indirection" >operator-&gt;</A>() const; // never throws T * <A href="#indirection" >operator-&gt;</A>() const; // never throws
T * <A href="#get" >get</A>() const; // never throws T * <A href="#get" >get</A>() const; // never throws
T * <A href="#detach" >detach</A>(); // never throws
operator <A href="#conversions" ><i>unspecified-bool-type</i></A>() const; // never throws operator <A href="#conversions" ><i>unspecified-bool-type</i></A>() const; // never throws
@ -179,6 +180,22 @@ intrusive_ptr &amp; operator=(T * r);</pre>
<p><b>Returns:</b> the stored pointer.</p> <p><b>Returns:</b> the stored pointer.</p>
<p><b>Throws:</b> nothing.</p> <p><b>Throws:</b> nothing.</p>
</blockquote> </blockquote>
<h3><a name="detach">detach</a></h3>
<pre>T * detach(); // 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>
<p><b>Caution:</b> Using <code>detach</code> escapes the safety of automatic
reference counting provided by <code>intrusive_ptr</code>. It should
by used only where strictly necessary (such as when interfacing to an
existing API), and when the implications are thoroughly understood.</p>
</blockquote>
<h3><a name="conversions">conversions</a></h3> <h3><a name="conversions">conversions</a></h3>
<pre>operator <i>unspecified-bool-type</i> () const; // never throws</pre> <pre>operator <i>unspecified-bool-type</i> () const; // never throws</pre>
<blockquote> <blockquote>

View File

@ -330,6 +330,13 @@ void test()
BOOST_TEST(get_pointer(px) == px.get()); BOOST_TEST(get_pointer(px) == px.get());
} }
{
boost::intrusive_ptr<X> px(new X);
X* detached = px.detach();
BOOST_TEST(detached->use_count() == 1);
delete detached;
}
} }
} // namespace n_access } // namespace n_access