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 static_cast_tag {};
struct dynamic_cast_tag {}; struct dynamic_cast_tag {};
struct polymorphic_cast_tag {};
template<typename T> struct shared_ptr_traits 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 #ifndef BOOST_NO_AUTO_PTR
template<typename Y> 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()); 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); 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()); 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 // get_pointer() enables boost::mem_fn to recognize shared_ptr
template<typename T> inline T * get_pointer(shared_ptr<T> const & p) 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> template<typename Y>
weak_ptr & operator=(weak_ptr<Y> const & r) // never throws 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()); 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 // get_pointer() enables boost::mem_fn to recognize weak_ptr
template<class T> inline T * get_pointer(weak_ptr<T> const & p) 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 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; 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); 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> }</pre>
@ -244,7 +248,7 @@ Provided as an aid to generic programming.</p>
<h3><a name="shared_static_cast">shared_static_cast</a></h3> <h3><a name="shared_static_cast">shared_static_cast</a></h3>
<pre>template&lt;typename T, typename U&gt; <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>. <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> The resulting smart pointer will share its use count with the original pointer.</p>
<p>Note that the seemingly equivalent expression</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> <h3><a name="shared_dynamic_cast">shared_dynamic_cast</a></h3>
<pre>template&lt;typename T, typename U&gt; <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>. <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 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 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> <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> <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> <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. <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 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; 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); 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> }</pre>
@ -192,19 +196,35 @@ Provided as an aid to generic programming.</p>
<h3><a name="shared_static_cast">shared_static_cast</a></h3> <h3><a name="shared_static_cast">shared_static_cast</a></h3>
<pre>template&lt;typename T, typename U&gt; <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>. <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> 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> <h3><a name="shared_dynamic_cast">shared_dynamic_cast</a></h3>
<pre>template&lt;typename T, typename U&gt; <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>. <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 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 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 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> 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> <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> <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>