New casts for smart pointers.

[SVN r12743]
This commit is contained in:
Darin Adler
2002-02-06 19:42:04 +00:00
parent f9782387d9
commit 0dd3285d56
4 changed files with 86 additions and 5 deletions

View File

@ -43,6 +43,7 @@ namespace detail
struct static_cast_tag {};
struct dynamic_cast_tag {};
struct polymorphic_cast_tag {};
template<typename T> struct shared_ptr_traits
{
@ -114,6 +115,15 @@ public:
}
}
template<typename Y>
shared_ptr(shared_ptr<Y> const & r, detail::polymorphic_cast_tag): px(dynamic_cast<element_type *>(r.px)), pn(r.pn)
{
if (px == 0)
{
throw std::bad_cast();
}
}
#ifndef BOOST_NO_AUTO_PTR
template<typename Y>
@ -219,7 +229,7 @@ template<typename T> inline bool operator<(shared_ptr<T> const & a, shared_ptr<T
return std::less<T*>()(a.get(), b.get());
}
template<typename T> void swap(shared_ptr<T> & a, shared_ptr<T> & b)
template<typename T> inline void swap(shared_ptr<T> & a, shared_ptr<T> & b)
{
a.swap(b);
}
@ -234,6 +244,17 @@ template<typename T, typename U> shared_ptr<T> shared_dynamic_cast(shared_ptr<U>
return shared_ptr<T>(r, detail::dynamic_cast_tag());
}
template<typename T, typename U> shared_ptr<T> shared_polymorphic_cast(shared_ptr<U> const & r)
{
return shared_ptr<T>(r, detail::polymorphic_cast_tag());
}
template<typename T, typename U> shared_ptr<T> shared_polymorphic_downcast(shared_ptr<U> const & r)
{
BOOST_ASSERT(dynamic_cast<T *>(r.get()) == r.get());
return shared_static_cast<T>(r);
}
// get_pointer() enables boost::mem_fn to recognize shared_ptr
template<typename T> inline T * get_pointer(shared_ptr<T> const & p)

View File

@ -73,6 +73,15 @@ public:
}
}
template<typename Y>
weak_ptr(weak_ptr<Y> const & r, detail::polymorphic_cast_tag): px(dynamic_cast<element_type *>(r.px)), pn(r.pn)
{
if (px == 0)
{
throw std::bad_cast();
}
}
template<typename Y>
weak_ptr & operator=(weak_ptr<Y> const & r) // never throws
{
@ -170,6 +179,17 @@ template<class T, class U> weak_ptr<T> shared_dynamic_cast(weak_ptr<U> const & r
return weak_ptr<T>(r, detail::dynamic_cast_tag());
}
template<typename T, typename U> weak_ptr<T> shared_polymorphic_cast(weak_ptr<U> const & r)
{
return weak_ptr<T>(r, detail::polymorphic_cast_tag());
}
template<typename T, typename U> weak_ptr<T> shared_polymorphic_downcast(weak_ptr<U> const & r)
{
BOOST_ASSERT(dynamic_cast<T *>(r.get()) == r.get());
return shared_static_cast<T>(r);
}
// get_pointer() enables boost::mem_fn to recognize weak_ptr
template<class T> inline T * get_pointer(weak_ptr<T> const & p)

View File

@ -97,6 +97,10 @@ function must be passed in, or the pointed-to object must have a trivial destruc
shared_ptr&lt;T&gt <a href="#shared_static_cast">shared_static_cast</a>(shared_ptr&lt;U&gt; const &amp; r); // never throws
template&lt;typename T, typename U&gt;
shared_ptr&lt;T&gt <a href="#shared_dynamic_cast">shared_dynamic_cast</a>(shared_ptr&lt;U&gt; const &amp; r);
template&lt;typename T, typename U&gt;
shared_ptr&lt;T&gt <a href="#shared_polymorphic_cast">shared_polymorphic_cast</a>(shared_ptr&lt;U&gt; const &amp; r);
template&lt;typename T, typename U&gt;
shared_ptr&lt;T&gt <a href="#shared_polymorphic_downcast">shared_polymorphic_downcast</a>(shared_ptr&lt;U&gt; const &amp; r); // never throws
}</pre>
@ -244,7 +248,7 @@ Provided as an aid to generic programming.</p>
<h3><a name="shared_static_cast">shared_static_cast</a></h3>
<pre>template&lt;typename T, typename U&gt;
shared_ptr&lt;T&gt <a href="#shared_static_cast">shared_static_cast</a>(shared_ptr&lt;U&gt; const &amp; r); // never throws</pre>
shared_ptr&lt;T&gt shared_static_cast(shared_ptr&lt;U&gt; const &amp; r); // never throws</pre>
<p>Perform a <b>static_cast</b> on the stored pointer, returning another <b>shared_ptr</b>.
The resulting smart pointer will share its use count with the original pointer.</p>
<p>Note that the seemingly equivalent expression</p>
@ -253,7 +257,7 @@ The resulting smart pointer will share its use count with the original pointer.<
<h3><a name="shared_dynamic_cast">shared_dynamic_cast</a></h3>
<pre>template&lt;typename T, typename U&gt;
shared_ptr&lt;T&gt <a href="#shared_dynamic_cast">shared_dynamic_cast</a>(shared_ptr&lt;U&gt; const &amp; r);</pre>
shared_ptr&lt;T&gt shared_dynamic_cast(shared_ptr&lt;U&gt; const &amp; r);</pre>
<p>Perform a <b>dynamic_cast</b> on the stored pointer, returning another <b>shared_ptr</b>.
The resulting smart pointer will share its use count with the original pointer unless the result of the
cast is 0. The only exception which may be thrown is <b>std::bad_alloc</b>, which may be thrown during the
@ -263,6 +267,22 @@ cast has no effect.</p>
<blockquote><code>shared_ptr&lt;T&gt;(dynamic_cast&lt;T*&gt;(r.get()))</code></blockquote>
<p>will eventually result in undefined behavior, attempting to delete the same object twice.</p>
<h3><a name="shared_polymorphic_cast">shared_polymorphic_cast</a></h3>
<pre>template&lt;typename T, typename U&gt;
shared_ptr&lt;T&gt shared_polymorphic_cast(shared_ptr&lt;U&gt; const &amp; r);</pre>
<p>Perform a <a href="../conversion/cast.htm#Polymorphic_cast"><b>polymorphic_cast</b><a> on the stored pointer,
returning another <b>shared_ptr</b>.
The resulting smart pointer will share its use count with the original pointer.
The only exception which may be thrown is <b>std::bad_cast</b>, if the pointer type can not be converted.
If an exception is thrown, the cast has no effect.</p>
<h3><a name="shared_polymorphic_downcast">shared_polymorphic_downcast</a></h3>
<pre>template&lt;typename T, typename U&gt;
shared_ptr&lt;T&gt shared_polymorphic_downcast(shared_ptr&lt;U&gt; const &amp; r); // never throws</pre>
<p>Perform a <a href="../conversion/cast.htm#Polymorphic_cast"><b>polymorphic_downcast</b><a> on the stored pointer,
returning another <b>shared_ptr</b>.
The resulting smart pointer will share its use count with the original pointer.</p>
<h2><a name="example">Example</a></h2>
<p>See <a href="shared_ptr_example.cpp">shared_ptr_example.cpp</a> for a complete example program.

View File

@ -71,6 +71,10 @@ pointed to. <b>T</b> must meet the smart pointer
weak_ptr&lt;T&gt <a href="#shared_static_cast">shared_static_cast</a>(weak_ptr&lt;U&gt; const &amp; r); // never throws
template&lt;typename T, typename U&gt;
weak_ptr&lt;T&gt <a href="#shared_dynamic_cast">shared_dynamic_cast</a>(weak_ptr&lt;U&gt; const &amp; r);
template&lt;typename T, typename U&gt;
weak_ptr&lt;T&gt <a href="#shared_polymorphic_cast">shared_polymorphic_cast</a>(weak_ptr&lt;U&gt; const &amp; r);
template&lt;typename T, typename U&gt;
weak_ptr&lt;T&gt <a href="#shared_polymorphic_downcast">shared_polymorphic_downcast</a>(weak_ptr&lt;U&gt; const &amp; r); // never throws
}</pre>
@ -192,19 +196,35 @@ Provided as an aid to generic programming.</p>
<h3><a name="shared_static_cast">shared_static_cast</a></h3>
<pre>template&lt;typename T, typename U&gt;
weak_ptr&lt;T&gt <a href="#shared_static_cast">shared_static_cast</a>(weak_ptr&lt;U&gt; const &amp; r); // never throws</pre>
weak_ptr&lt;T&gt shared_static_cast(weak_ptr&lt;U&gt; const &amp; r); // never throws</pre>
<p>Perform a <b>static_cast</b> on the stored pointer, returning another <b>weak_ptr</b>.
The resulting smart pointer will share its use count with the original pointer.</p>
<h3><a name="shared_dynamic_cast">shared_dynamic_cast</a></h3>
<pre>template&lt;typename T, typename U&gt;
weak_ptr&lt;T&gt <a href="#shared_dynamic_cast">shared_dynamic_cast</a>(weak_ptr&lt;U&gt; const &amp; r);</pre>
weak_ptr&lt;T&gt shared_dynamic_cast(weak_ptr&lt;U&gt; const &amp; r);</pre>
<p>Perform a <b>dynamic_cast</b> on the stored pointer, returning another <b>weak_ptr</b>.
The resulting smart pointer will share its use count with the original pointer unless the result of the
cast is 0. The only exception which may be thrown is <b>std::bad_alloc</b>, which may be thrown during the
construction of the new <b>weak_ptr</b> if the result of the cast is 0. If an exception is thrown, the
cast has no effect.</p>
<h3><a name="shared_polymorphic_cast">shared_polymorphic_cast</a></h3>
<pre>template&lt;typename T, typename U&gt;
weak_ptr&lt;T&gt shared_polymorphic_cast(weak_ptr&lt;U&gt; const &amp; r);</pre>
<p>Perform a <a href="../conversion/cast.htm#Polymorphic_cast"><b>polymorphic_cast</b><a> on the stored pointer,
returning another <b>weak_ptr</b>.
The resulting smart pointer will share its use count with the original pointer.
The only exception which may be thrown is <b>std::bad_cast</b>, if the pointer type can not be converted.
If an exception is thrown, the cast has no effect.</p>
<h3><a name="shared_polymorphic_downcast">shared_polymorphic_downcast</a></h3>
<pre>template&lt;typename T, typename U&gt;
weak_ptr&lt;T&gt shared_polymorphic_downcast(weak_ptr&lt;U&gt; const &amp; r); // never throws</pre>
<p>Perform a <a href="../conversion/cast.htm#Polymorphic_cast"><b>polymorphic_downcast</b><a> on the stored pointer,
returning another <b>weak_ptr</b>.
The resulting smart pointer will share its use count with the original pointer.</p>
<hr>
<p>Revised <!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B %Y" startspan -->1 February 2002<!--webbot bot="Timestamp" i-checksum="38439" endspan --></p>