Update shared_ptr casts.

[SVN r81463]
This commit is contained in:
Peter Dimov
2012-11-21 17:43:48 +00:00
parent 7835914d83
commit 97d32745aa
3 changed files with 229 additions and 59 deletions

View File

@ -62,11 +62,6 @@ class enable_shared_from_raw;
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 @@ public:
{
}
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 @@ template<class T> inline void swap(shared_ptr<T> & a, shared_ptr<T> & b) BOOST_N
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 ) );
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> const_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::const_cast_tag());
(void) const_cast< T* >( static_cast< U* >( 0 ) );
typedef typename shared_ptr<T>::element_type E;
E * p = const_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> 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 ) );
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>();
}
// shared_*_cast names are deprecated. Use *_pointer_cast instead.
template<class T, class U> shared_ptr<T> shared_static_cast(shared_ptr<U> const & r)
template<class T, class U> shared_ptr<T> reinterpret_pointer_cast( shared_ptr<U> const & r ) BOOST_NOEXCEPT
{
return shared_ptr<T>(r, boost::detail::static_cast_tag());
}
(void) reinterpret_cast< T* >( static_cast< U* >( 0 ) );
template<class T, class U> shared_ptr<T> shared_dynamic_cast(shared_ptr<U> const & r)
{
return shared_ptr<T>(r, boost::detail::dynamic_cast_tag());
}
typedef typename shared_ptr<T>::element_type E;
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());
}
template<class T, class 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);
E * p = reinterpret_cast< E* >( r.get() );
return shared_ptr<T>( r, p );
}
// get_pointer() enables boost::mem_fn to recognize shared_ptr

View File

@ -74,6 +74,7 @@ import testing ;
[ 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 ]

202
test/sp_array_cast_test.cpp Normal file
View File

@ -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();
}