Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r81463 - in trunk: boost/smart_ptr libs/smart_ptr/test
From: pdimov_at_[hidden]
Date: 2012-11-21 12:43:49


Author: pdimov
Date: 2012-11-21 12:43:48 EST (Wed, 21 Nov 2012)
New Revision: 81463
URL: http://svn.boost.org/trac/boost/changeset/81463

Log:
Update shared_ptr casts.
Added:
   trunk/libs/smart_ptr/test/sp_array_cast_test.cpp (contents, props changed)
Text files modified:
   trunk/boost/smart_ptr/shared_ptr.hpp | 81 +++++++++++----------------------------
   trunk/libs/smart_ptr/test/Jamfile.v2 | 1
   2 files changed, 25 insertions(+), 57 deletions(-)

Modified: trunk/boost/smart_ptr/shared_ptr.hpp
==============================================================================
--- trunk/boost/smart_ptr/shared_ptr.hpp (original)
+++ trunk/boost/smart_ptr/shared_ptr.hpp 2012-11-21 12:43:48 EST (Wed, 21 Nov 2012)
@@ -62,11 +62,6 @@
 namespace detail
 {
 
-struct static_cast_tag {};
-struct const_cast_tag {};
-struct dynamic_cast_tag {};
-struct polymorphic_cast_tag {};
-
 // sp_element, element_type
 
 template< class T > struct sp_element
@@ -420,36 +415,6 @@
     {
     }
 
- template<class Y>
- shared_ptr(shared_ptr<Y> const & r, boost::detail::static_cast_tag)
- BOOST_NOEXCEPT : px(static_cast<element_type *>(r.px)), pn(r.pn)
- {
- }
-
- template<class Y>
- shared_ptr(shared_ptr<Y> const & r, boost::detail::const_cast_tag)
- BOOST_NOEXCEPT : px(const_cast<element_type *>(r.px)), pn(r.pn)
- {
- }
-
- template<class Y>
- shared_ptr(shared_ptr<Y> const & r, boost::detail::dynamic_cast_tag): px(dynamic_cast<element_type *>(r.px)), pn(r.pn)
- {
- if(px == 0) // need to allocate new counter -- the cast failed
- {
- pn = boost::detail::shared_count();
- }
- }
-
- template<class Y>
- shared_ptr(shared_ptr<Y> const & r, boost::detail::polymorphic_cast_tag): px(dynamic_cast<element_type *>(r.px)), pn(r.pn)
- {
- if(px == 0)
- {
- boost::throw_exception(std::bad_cast());
- }
- }
-
 #ifndef BOOST_NO_AUTO_PTR
 
     template<class Y>
@@ -723,42 +688,44 @@
     a.swap(b);
 }
 
-template<class T, class U> shared_ptr<T> static_pointer_cast(shared_ptr<U> const & r)
+template<class T, class U> shared_ptr<T> static_pointer_cast( shared_ptr<U> const & r ) BOOST_NOEXCEPT
 {
- return shared_ptr<T>(r, boost::detail::static_cast_tag());
-}
+ (void) static_cast< T* >( static_cast< U* >( 0 ) );
 
-template<class T, class U> shared_ptr<T> const_pointer_cast(shared_ptr<U> const & r)
-{
- return shared_ptr<T>(r, boost::detail::const_cast_tag());
+ typedef typename shared_ptr<T>::element_type E;
+
+ E * p = static_cast< E* >( r.get() );
+ return shared_ptr<T>( r, p );
 }
 
-template<class T, class U> shared_ptr<T> dynamic_pointer_cast(shared_ptr<U> const & r)
+template<class T, class U> shared_ptr<T> const_pointer_cast( shared_ptr<U> const & r ) BOOST_NOEXCEPT
 {
- return shared_ptr<T>(r, boost::detail::dynamic_cast_tag());
-}
+ (void) const_cast< T* >( static_cast< U* >( 0 ) );
 
-// shared_*_cast names are deprecated. Use *_pointer_cast instead.
+ typedef typename shared_ptr<T>::element_type E;
 
-template<class T, class U> shared_ptr<T> shared_static_cast(shared_ptr<U> const & r)
-{
- return shared_ptr<T>(r, boost::detail::static_cast_tag());
+ E * p = const_cast< E* >( r.get() );
+ return shared_ptr<T>( r, p );
 }
 
-template<class T, class U> shared_ptr<T> shared_dynamic_cast(shared_ptr<U> const & r)
+template<class T, class U> shared_ptr<T> dynamic_pointer_cast( shared_ptr<U> const & r ) BOOST_NOEXCEPT
 {
- return shared_ptr<T>(r, boost::detail::dynamic_cast_tag());
-}
+ (void) dynamic_cast< T* >( static_cast< U* >( 0 ) );
 
-template<class T, class U> shared_ptr<T> shared_polymorphic_cast(shared_ptr<U> const & r)
-{
- return shared_ptr<T>(r, boost::detail::polymorphic_cast_tag());
+ typedef typename shared_ptr<T>::element_type E;
+
+ E * p = dynamic_cast< E* >( r.get() );
+ return p? shared_ptr<T>( r, p ): shared_ptr<T>();
 }
 
-template<class T, class U> shared_ptr<T> shared_polymorphic_downcast(shared_ptr<U> const & r)
+template<class T, class U> shared_ptr<T> reinterpret_pointer_cast( shared_ptr<U> const & r ) BOOST_NOEXCEPT
 {
- BOOST_ASSERT(dynamic_cast<T *>(r.get()) == r.get());
- return shared_static_cast<T>(r);
+ (void) reinterpret_cast< T* >( static_cast< U* >( 0 ) );
+
+ typedef typename shared_ptr<T>::element_type E;
+
+ E * p = reinterpret_cast< E* >( r.get() );
+ return shared_ptr<T>( r, p );
 }
 
 // get_pointer() enables boost::mem_fn to recognize shared_ptr

Modified: trunk/libs/smart_ptr/test/Jamfile.v2
==============================================================================
--- trunk/libs/smart_ptr/test/Jamfile.v2 (original)
+++ trunk/libs/smart_ptr/test/Jamfile.v2 2012-11-21 12:43:48 EST (Wed, 21 Nov 2012)
@@ -74,6 +74,7 @@
           [ compile sp_array_cv_test.cpp ]
           [ run sp_convertible_test.cpp ]
           [ run sp_array_n_test.cpp ]
+ [ run sp_array_cast_test.cpp ]
 
           [ compile-fail array_fail_spa_sp_c.cpp ]
           [ compile-fail array_fail_sp_spa_c.cpp ]

Added: trunk/libs/smart_ptr/test/sp_array_cast_test.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/smart_ptr/test/sp_array_cast_test.cpp 2012-11-21 12:43:48 EST (Wed, 21 Nov 2012)
@@ -0,0 +1,202 @@
+//
+// sp_array_cast_test.cpp
+//
+// Copyright (c) 2012 Peter Dimov
+//
+// Distributed under the Boost Software License, Version 1.0.
+// See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt
+//
+
+#include <boost/shared_ptr.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+struct X
+{
+};
+
+void static_cast_test()
+{
+ {
+ boost::shared_ptr<void> pv;
+
+ boost::shared_ptr<int[]> pi = boost::static_pointer_cast<int[]>( pv );
+ BOOST_TEST( pi.get() == 0 );
+
+ boost::shared_ptr<int[3]> pi2 = boost::static_pointer_cast<int[3]>( pv );
+ BOOST_TEST( pi2.get() == 0 );
+
+ boost::shared_ptr<X[]> px = boost::static_pointer_cast<X[]>( pv );
+ BOOST_TEST( px.get() == 0 );
+
+ boost::shared_ptr<X[5]> px2 = boost::static_pointer_cast<X[5]>( pv );
+ BOOST_TEST( px2.get() == 0 );
+ }
+
+ {
+ boost::shared_ptr<int[]> pi( new int[2] );
+ boost::shared_ptr<void> pv( pi );
+
+ boost::shared_ptr<int[]> pi2 = boost::static_pointer_cast<int[]>( pv );
+ BOOST_TEST(pi.get() == pi2.get());
+ BOOST_TEST(!(pi < pi2 || pi2 < pi));
+
+ boost::shared_ptr<int[2]> pi3 = boost::static_pointer_cast<int[2]>( pv );
+ BOOST_TEST(pi.get() == pi3.get());
+ BOOST_TEST(!(pi < pi3 || pi3 < pi));
+
+ boost::shared_ptr<void> pv2( pi3 );
+
+ boost::shared_ptr<int[]> pi4 = boost::static_pointer_cast<int[]>( pv2 );
+ BOOST_TEST(pi.get() == pi4.get());
+ BOOST_TEST(!(pi < pi4 || pi4 < pi));
+ }
+
+ {
+ boost::shared_ptr<X[]> px( new X[4] );
+ boost::shared_ptr<void> pv( px );
+
+ boost::shared_ptr<X[]> px2 = boost::static_pointer_cast<X[]>( pv );
+ BOOST_TEST(px.get() == px2.get());
+ BOOST_TEST(!(px < px2 || px2 < px));
+
+ boost::shared_ptr<X[4]> px3 = boost::static_pointer_cast<X[4]>( pv );
+ BOOST_TEST(px.get() == px3.get());
+ BOOST_TEST(!(px < px3 || px3 < px));
+
+ boost::shared_ptr<void> pv2( px3 );
+
+ boost::shared_ptr<X[]> px4 = boost::static_pointer_cast<X[]>( pv2 );
+ BOOST_TEST(px.get() == px4.get());
+ BOOST_TEST(!(px < px4 || px4 < px));
+ }
+}
+
+void const_cast_test()
+{
+ {
+ boost::shared_ptr<int const volatile[]> px;
+
+ boost::shared_ptr<int[]> px2 = boost::const_pointer_cast<int[]>(px);
+ BOOST_TEST( px2.get() == 0 );
+ }
+
+ {
+ boost::shared_ptr<int const volatile[2]> px;
+
+ boost::shared_ptr<int[2]> px2 = boost::const_pointer_cast<int[2]>(px);
+ BOOST_TEST( px2.get() == 0 );
+ }
+
+ {
+ boost::shared_ptr<X const volatile[]> px;
+
+ boost::shared_ptr<X[]> px2 = boost::const_pointer_cast<X[]>(px);
+ BOOST_TEST( px2.get() == 0 );
+ }
+
+ {
+ boost::shared_ptr<X const volatile[5]> px;
+
+ boost::shared_ptr<X[5]> px2 = boost::const_pointer_cast<X[5]>(px);
+ BOOST_TEST( px2.get() == 0 );
+ }
+
+ {
+ boost::shared_ptr<int const volatile[]> px( new int[3] );
+
+ boost::shared_ptr<int[]> px2 = boost::const_pointer_cast<int[]>(px);
+ BOOST_TEST(px.get() == px2.get());
+ BOOST_TEST(!(px < px2 || px2 < px));
+ }
+
+ {
+ boost::shared_ptr<int const volatile[3]> px( new int[3] );
+
+ boost::shared_ptr<int[3]> px2 = boost::const_pointer_cast<int[3]>(px);
+ BOOST_TEST(px.get() == px2.get());
+ BOOST_TEST(!(px < px2 || px2 < px));
+ }
+
+ {
+ boost::shared_ptr<X const volatile[]> px( new X[4] );
+
+ boost::shared_ptr<X[]> px2 = boost::const_pointer_cast<X[]>(px);
+ BOOST_TEST(px.get() == px2.get());
+ BOOST_TEST(!(px < px2 || px2 < px));
+ }
+
+ {
+ boost::shared_ptr<X const volatile[4]> px( new X[4] );
+
+ boost::shared_ptr<X[4]> px2 = boost::const_pointer_cast<X[4]>(px);
+ BOOST_TEST(px.get() == px2.get());
+ BOOST_TEST(!(px < px2 || px2 < px));
+ }
+}
+
+void reinterpret_cast_test()
+{
+ {
+ boost::shared_ptr<int[]> pi;
+ BOOST_TEST( pi.get() == 0 );
+
+ boost::shared_ptr<int[3]> pi2 = boost::reinterpret_pointer_cast<int[3]>( pi );
+ BOOST_TEST( pi2.get() == 0 );
+
+ boost::shared_ptr<int[6]> pi3 = boost::reinterpret_pointer_cast<int[6]>( pi2 );
+ BOOST_TEST( pi3.get() == 0 );
+ }
+
+ {
+ boost::shared_ptr<X[]> px;
+ BOOST_TEST( px.get() == 0 );
+
+ boost::shared_ptr<X[5]> px2 = boost::reinterpret_pointer_cast<X[5]>( px );
+ BOOST_TEST( px2.get() == 0 );
+
+ boost::shared_ptr<X[9]> px3 = boost::reinterpret_pointer_cast<X[9]>( px2 );
+ BOOST_TEST( px3.get() == 0 );
+ }
+
+ {
+ boost::shared_ptr<int[]> pi( new int[2] );
+
+ boost::shared_ptr<int[2]> pi2 = boost::reinterpret_pointer_cast<int[2]>( pi );
+ BOOST_TEST(pi.get() == pi2.get());
+ BOOST_TEST(!(pi < pi2 || pi2 < pi));
+
+ boost::shared_ptr<int[1]> pi3 = boost::reinterpret_pointer_cast<int[1]>( pi2 );
+ BOOST_TEST(pi.get() == pi3.get());
+ BOOST_TEST(!(pi < pi3 || pi3 < pi));
+
+ boost::shared_ptr<int[]> pi4 = boost::reinterpret_pointer_cast<int[]>( pi3 );
+ BOOST_TEST(pi.get() == pi4.get());
+ BOOST_TEST(!(pi < pi4 || pi4 < pi));
+ }
+
+ {
+ boost::shared_ptr<X[]> px( new X[4] );
+
+ boost::shared_ptr<X[7]> px2 = boost::reinterpret_pointer_cast<X[7]>( px );
+ BOOST_TEST(px.get() == px2.get());
+ BOOST_TEST(!(px < px2 || px2 < px));
+
+ boost::shared_ptr<X[4]> px3 = boost::reinterpret_pointer_cast<X[4]>( px2 );
+ BOOST_TEST(px.get() == px3.get());
+ BOOST_TEST(!(px < px3 || px3 < px));
+
+ boost::shared_ptr<X[]> px4 = boost::reinterpret_pointer_cast<X[]>( px3 );
+ BOOST_TEST(px.get() == px4.get());
+ BOOST_TEST(!(px < px4 || px4 < px));
+ }
+}
+
+int main()
+{
+ static_cast_test();
+ const_cast_test();
+ reinterpret_cast_test();
+
+ return boost::report_errors();
+}


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk