From 7cdfcff4835e4e77d48aac11aaac1f5f9162476a Mon Sep 17 00:00:00 2001
Message-Id: <7cdfcff4835e4e77d48aac11aaac1f5f9162476a.1386091519.git.avi@cloudius-systems.com>
From: Avi Kivity <avi@cloudius-systems.com>
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
|
b
|
public:
|
151 | 151 | return px; |
152 | 152 | } |
153 | 153 | |
| 154 | T * detach() BOOST_NOEXCEPT |
| 155 | { |
| 156 | T * ret = px; |
| 157 | px = 0; |
| 158 | return ret; |
| 159 | } |
| 160 | |
154 | 161 | T & operator*() const |
155 | 162 | { |
156 | 163 | BOOST_ASSERT( px != 0 ); |
diff --git a/intrusive_ptr.html b/intrusive_ptr.html
index 562d27a..7028444 100644
a
|
b
|
|
71 | 71 | T & <A href="#indirection" >operator*</A>() const; // never throws |
72 | 72 | T * <A href="#indirection" >operator-></A>() const; // never throws |
73 | 73 | T * <A href="#get" >get</A>() const; // never throws |
| 74 | T * <A href="#detach" >detach</A>(); // never throws |
74 | 75 | |
75 | 76 | operator <A href="#conversions" ><i>unspecified-bool-type</i></A>() const; // never throws |
76 | 77 | |
… |
… |
intrusive_ptr & operator=(T * r);</pre>
|
179 | 180 | <p><b>Returns:</b> the stored pointer.</p> |
180 | 181 | <p><b>Throws:</b> nothing.</p> |
181 | 182 | </blockquote> |
| 183 | <h3><a name="detach">detach</a></h3> |
| 184 | <pre>T * detach(); // never throws</pre> |
| 185 | <blockquote> |
| 186 | <p><b>Returns:</b> the stored pointer.</p> |
| 187 | <p><b>Throws:</b> nothing.</p> |
| 188 | <p><b>Postconditions:</b> <code>get() == 0</code>.</p> |
| 189 | <p><b>Notes:</b> The returned pointer has an elevated reference count. This |
| 190 | allows conversion of an <b>intrusive_ptr</b> back to a raw pointer, |
| 191 | without the performance overhead of acquiring and dropping an extra |
| 192 | reference. It can be viewed as the complement of the |
| 193 | non-reference-incrementing constructor.</p> |
| 194 | <p><b>Caution:</b> Using <code>detach</code> escapes the safety of automatic |
| 195 | reference counting provided by <code>intrusive_ptr</code>. It should |
| 196 | by used only where strictly necessary (such as when interfacing to an |
| 197 | existing API), and when the implications are thoroughly understood.</p> |
| 198 | </blockquote> |
182 | 199 | <h3><a name="conversions">conversions</a></h3> |
183 | 200 | <pre>operator <i>unspecified-bool-type</i> () const; // never throws</pre> |
184 | 201 | <blockquote> |
diff --git a/test/intrusive_ptr_test.cpp b/test/intrusive_ptr_test.cpp
index 614a9cb..f53d75d 100644
a
|
b
|
void test()
|
330 | 330 | |
331 | 331 | BOOST_TEST(get_pointer(px) == px.get()); |
332 | 332 | } |
| 333 | |
| 334 | { |
| 335 | boost::intrusive_ptr<X> px(new X); |
| 336 | X* detached = px.detach(); |
| 337 | BOOST_TEST(detached->use_count() == 1); |
| 338 | delete detached; |
| 339 | } |
333 | 340 | } |
334 | 341 | |
335 | 342 | } // namespace n_access |