get_shared_ptr renamed to weak_ptr::lock.

[SVN r17307]
This commit is contained in:
Peter Dimov
2003-02-10 15:56:36 +00:00
parent 34f423f811
commit 851d87a1bb
7 changed files with 69 additions and 73 deletions

View File

@@ -24,8 +24,6 @@
namespace boost
{
template<class T> shared_ptr<T> get_shared_ptr(weak_ptr<T> const & r); // never throws
template<class T> class weak_ptr
{
private:
@@ -64,7 +62,7 @@ public:
template<class Y>
weak_ptr(weak_ptr<Y> const & r): pn(r.pn) // never throws
{
px = boost::get_shared_ptr(r).get();
px = r.lock().get();
}
template<class Y>
@@ -77,7 +75,7 @@ public:
template<class Y>
weak_ptr & operator=(weak_ptr<Y> const & r) // never throws
{
px = boost::get_shared_ptr(r).get();
px = r.lock().get();
pn = r.pn;
return *this;
}
@@ -92,9 +90,33 @@ public:
#endif
void reset() // never throws in 1.30+
shared_ptr<T> lock() const // never throws
{
this_type().swap(*this);
#if defined(BOOST_HAS_THREADS)
// optimization: avoid throw overhead
if(expired())
{
return shared_ptr<element_type>();
}
try
{
return shared_ptr<element_type>(*this);
}
catch(bad_weak_ptr const &)
{
// Q: how can we get here?
// A: another thread may have invalidated r after the use_count test above.
return shared_ptr<element_type>();
}
#else
// optimization: avoid try/catch overhead when single threaded
return expired()? shared_ptr<element_type>(): shared_ptr<element_type>(*this);
#endif
}
long use_count() const // never throws
@@ -107,6 +129,11 @@ public:
return pn.use_count() == 0;
}
void reset() // never throws in 1.30+
{
this_type().swap(*this);
}
void swap(this_type & other) // never throws
{
std::swap(px, other.px);
@@ -151,39 +178,10 @@ template<class T> void swap(weak_ptr<T> & a, weak_ptr<T> & b)
a.swap(b);
}
template<class T> shared_ptr<T> get_shared_ptr(weak_ptr<T> const & r) // never throws
{
#if defined(BOOST_HAS_THREADS)
// optimization: avoid throw overhead
if(r.use_count() == 0)
{
return shared_ptr<T>();
}
try
{
return shared_ptr<T>(r);
}
catch(bad_weak_ptr const &)
{
// Q: how can we get here?
// A: another thread may have invalidated r after the use_count test above.
return shared_ptr<T>();
}
#else
// optimization: avoid try/catch overhead when single threaded
return r.use_count() == 0? shared_ptr<T>(): shared_ptr<T>(r);
#endif
}
// deprecated, provided for backward compatibility
template<class T> shared_ptr<T> make_shared(weak_ptr<T> const & r)
{
return boost::get_shared_ptr(r);
return r.lock();
}
} // namespace boost

View File

@@ -390,8 +390,8 @@ q = p;
many of the implicit conversion pitfalls.</P>
</blockquote>
<P><EM>[The conversion to bool is not merely syntactic sugar. It allows <STRONG>shared_ptr</STRONG>s
to be declared in conditions when using <STRONG>dynamic_pointer_cast </STRONG>or
<STRONG>get_shared_ptr</STRONG>.]</EM></P>
to be declared in conditions when using <A href="#dynamic_pointer_cast">dynamic_pointer_cast</A> or
<A href="weak_ptr.htm#lock">weak_ptr::lock</A>.]</EM></P>
<h3><a name="swap">swap</a></h3>
<pre>void swap(shared_ptr &amp; b); // never throws</pre>
<blockquote>

View File

@@ -413,7 +413,7 @@ public:
virtual shared_ptr&lt;X&gt; getX()
{
shared_ptr&lt;X&gt; px = get_shared_ptr(weak_this);
shared_ptr&lt;X&gt; px = weak_this.lock();
return px;
}
};

View File

@@ -94,7 +94,7 @@ template<class T> void test_is_Y(boost::shared_ptr<T> const & p)
template<class T> void test_is_Y(boost::weak_ptr<T> const & p)
{
boost::shared_ptr<T> q = boost::get_shared_ptr(p);
boost::shared_ptr<T> q = p.lock();
BOOST_TEST(q.get() != 0);
BOOST_TEST(q->id() == 2);
}
@@ -221,7 +221,7 @@ int main()
{
}
test_is_zero(boost::get_shared_ptr(wp1));
test_is_zero(wp1.lock());
weak_ptr<X> wp2 = static_pointer_cast<X>(p5);
@@ -232,10 +232,10 @@ int main()
// Scoped to not affect the subsequent use_count() tests.
{
shared_ptr<X> sp2(wp2);
test_is_nonzero(boost::get_shared_ptr(wp2));
test_is_nonzero(wp2.lock());
}
weak_ptr<Y> wp3 = dynamic_pointer_cast<Y>(boost::get_shared_ptr(wp2));
weak_ptr<Y> wp3 = dynamic_pointer_cast<Y>(wp2.lock());
BOOST_TEST(wp3.use_count() == 1);
test_shared(wp2, wp3);
@@ -246,7 +246,7 @@ int main()
test_shared(wp2, wp4);
wp1 = p2;
test_is_zero(boost::get_shared_ptr(wp1));
test_is_zero(wp1.lock());
wp1 = p4;
wp1 = wp3;

View File

@@ -3094,7 +3094,7 @@ public:
virtual boost::shared_ptr<X> getX()
{
boost::shared_ptr<X> px = boost::get_shared_ptr(weak_this);
boost::shared_ptr<X> px = weak_this.lock();
return px;
}
};

View File

@@ -1183,14 +1183,14 @@ void test()
} // namespace n_comparison
namespace n_get_shared_ptr
namespace n_lock
{
void test()
{
}
} // namespace n_get_shared_ptr
} // namespace n_lock
namespace n_map
{
@@ -1272,7 +1272,7 @@ int main()
n_use_count::test();
n_swap::test();
n_comparison::test();
n_get_shared_ptr::test();
n_lock::test();
n_map::test();

View File

@@ -17,12 +17,12 @@
<p>The <b>weak_ptr</b> class template stores a "weak reference" to an object that's
already managed by a <b>shared_ptr</b>. To access the object, a <STRONG>weak_ptr</STRONG>
can be converted to a <STRONG>shared_ptr</STRONG> using <A href="shared_ptr.htm#constructors">
the <STRONG>shared_ptr</STRONG> constructor</A> or the function <STRONG><A href="#get_shared_ptr">
get_shared_ptr</A></STRONG>. When the last <b>shared_ptr</b> to the
object goes away and the object is deleted, the attempt to obtain a <STRONG>shared_ptr</STRONG>
the <STRONG>shared_ptr</STRONG> constructor</A> or the member function <STRONG><A href="#lock">
lock</A></STRONG>. When the last <b>shared_ptr</b> to the object goes
away and the object is deleted, the attempt to obtain a <STRONG>shared_ptr</STRONG>
from the <b>weak_ptr</b> instances that refer to the deleted object will fail:
the constructor will throw an exception of type <STRONG>boost::bad_weak_ptr</STRONG>,
and <STRONG>get_shared_ptr</STRONG> will return an <EM>empty</EM> <STRONG>shared_ptr</STRONG>.</p>
and <STRONG>weak_ptr::lock</STRONG> will return an <EM>empty</EM> <STRONG>shared_ptr</STRONG>.</p>
<p>Every <b>weak_ptr</b> meets the <b>CopyConstructible</b> and <b>Assignable</b> requirements
of the C++ Standard Library, and so can be used in standard library containers.
Comparison operators are supplied so that <b>weak_ptr</b> works with the
@@ -33,7 +33,8 @@
<P>Compared to <STRONG>shared_ptr</STRONG>, <STRONG>weak_ptr</STRONG> provides a
very limited subset of operations since accessing its stored pointer is often
dangerous in multithreaded programs, and sometimes unsafe even within a single
thread (that is, it may invoke undefined behavior.) Consider, for example, this
thread (that is, it may invoke undefined behavior.) Pretend for a moment that <b>weak_ptr</b>
has a <b>get</b> member function that returns a raw pointer, and consider this
innocent piece of code:</P>
<pre>shared_ptr&lt;int&gt; p(new int(5));
weak_ptr&lt;int&gt; q(p);
@@ -55,14 +56,16 @@ weak_ptr&lt;int&gt; q(p);
// some time later
if(shared_ptr&lt;int&gt; r = <A href="#get_shared_ptr" >get_shared_ptr</A>(q))
if(shared_ptr&lt;int&gt; r = q.<A href="#lock" >lock</A>())
{
// use *r
}
</pre>
<p>Now <STRONG>r</STRONG> holds a reference to the object that was pointed by <STRONG>q</STRONG>.
Even if <code>p.reset()</code> is executed in another thread, the object will
stay alive until <STRONG>r</STRONG> goes out of scope (or is reset.)</p>
stay alive until <STRONG>r</STRONG> goes out of scope or is reset. By obtaining
a <STRONG>shared_ptr</STRONG> to the object, we have effectively locked it
against destruction.</p>
<h2><a name="Synopsis">Synopsis</a></h2>
<pre>namespace boost {
@@ -83,11 +86,11 @@ if(shared_ptr&lt;int&gt; r = <A href="#get_shared_ptr" >get_shared_ptr</A>(q))
template&lt;class Y&gt; weak_ptr &amp; <A href="#assignment" >operator=</A>(weak_ptr&lt;Y&gt; const &amp; r);
template&lt;class Y&gt; weak_ptr &amp; <A href="#assignment" >operator=</A>(shared_ptr&lt;Y&gt; const &amp; r);
void <A href="#reset" >reset</A>();
long <A href="#use_count" >use_count</A>() const;
bool <A href="#expired" >expired</A>() const;
shared_ptr&lt;T&gt; <A href="#lock" >lock</A>() const;
void <A href="#reset" >reset</A>();
void <A href="#swap" >swap</A>(weak_ptr&lt;T&gt; &amp; b);
};
@@ -96,10 +99,6 @@ if(shared_ptr&lt;int&gt; r = <A href="#get_shared_ptr" >get_shared_ptr</A>(q))
template&lt;class T&gt;
void <A href="#free-swap" >swap</A>(weak_ptr&lt;T&gt; &amp; a, weak_ptr&lt;T&gt; &amp; b);
template&lt;class T&gt;
shared_ptr&lt;T&gt; <A href="#get_shared_ptr" >get_shared_ptr</A>(weak_ptr&lt;T&gt; const &amp; r);
}
</pre>
<h2><a name="Members">Members</a></h2>
@@ -143,11 +142,6 @@ template&lt;class Y&gt; weak_ptr &amp; operator=(shared_ptr&lt;Y&gt; const &amp;
<P><B>Notes:</B> The implementation is free to meet the effects (and the implied
guarantees) via different means, without creating a temporary.</P>
</BLOCKQUOTE>
<h3><a name="reset">reset</a></h3>
<pre>void reset();</pre>
<BLOCKQUOTE>
<P><B>Effects:</B> Equivalent to <code>weak_ptr().swap(*this)</code>.</P>
</BLOCKQUOTE>
<h3><a name="use_count">use_count</a></h3>
<pre>long use_count() const;</pre>
<blockquote>
@@ -165,6 +159,17 @@ template&lt;class Y&gt; weak_ptr &amp; operator=(shared_ptr&lt;Y&gt; const &amp;
<p><b>Throws:</b> nothing.</p>
<P><B>Notes:</B> <code>expired()</code> may be faster than <code>use_count()</code>.</P>
</blockquote>
<h3><a name="lock">lock</a></h3>
<pre>shared_ptr&lt;T&gt; lock() const;</pre>
<BLOCKQUOTE>
<P><B>Returns:</B> <code>expired()? shared_ptr&lt;T&gt;(): shared_ptr&lt;T&gt;(*this)</code>.</P>
<P><B>Throws:</B> nothing.</P>
</BLOCKQUOTE>
<h3><a name="reset">reset</a></h3>
<pre>void reset();</pre>
<BLOCKQUOTE>
<P><B>Effects:</B> Equivalent to <code>weak_ptr().swap(*this)</code>.</P>
</BLOCKQUOTE>
<h3><a name="swap">swap</a></h3>
<pre>void swap(weak_ptr &amp; b);</pre>
<blockquote>
@@ -198,13 +203,6 @@ template&lt;class Y&gt; weak_ptr &amp; operator=(shared_ptr&lt;Y&gt; const &amp;
<P><B>Notes:</B> Matches the interface of <B>std::swap</B>. Provided as an aid to
generic programming.</P>
</BLOCKQUOTE>
<h3><a name="get_shared_ptr">get_shared_ptr</a></h3>
<pre>template&lt;class T&gt;
shared_ptr&lt;T&gt; get_shared_ptr(weak_ptr&lt;T&gt; &amp; const r)</pre>
<BLOCKQUOTE>
<P><B>Returns:</B> <code>r.expired()? shared_ptr&lt;T&gt;(): shared_ptr&lt;T&gt;(r)</code>.</P>
<P><B>Throws:</B> nothing.</P>
</BLOCKQUOTE>
<h2><a name="FAQ">Frequently Asked Questions</a></h2>
<P><B>Q.</B> Can an object create a <STRONG>weak_ptr</STRONG> to itself in its
constructor?</P>