Fix shared_ptr<T[]> EDG issues.

[SVN r81159]
This commit is contained in:
Peter Dimov
2012-11-03 14:49:45 +00:00
parent 8c15401ea7
commit 0b6cab9f2f
5 changed files with 85 additions and 15 deletions

View File

@@ -48,6 +48,31 @@ template< class Y, class T > struct sp_convertible
enum _vt { value = sizeof( (f)( static_cast<Y*>(0) ) ) == sizeof(yes) }; enum _vt { value = sizeof( (f)( static_cast<Y*>(0) ) ) == sizeof(yes) };
}; };
template< class Y, class T > struct sp_convertible< Y, T[] >
{
enum _vt { value = false };
};
template< class T > struct sp_convertible< T[], T[] >
{
enum _vt { value = true };
};
template< class T > struct sp_convertible< T[], T const [] >
{
enum _vt { value = true };
};
template< class T > struct sp_convertible< T[], T volatile [] >
{
enum _vt { value = true };
};
template< class T > struct sp_convertible< T[], T const volatile [] >
{
enum _vt { value = true };
};
struct sp_empty struct sp_empty
{ {
}; };

View File

@@ -205,8 +205,10 @@ template< class T, class R > struct sp_enable_if_auto_ptr< std::auto_ptr< T >, R
// sp_assert_convertible // sp_assert_convertible
template< class T > inline void sp_assert_convertible( T * ) template< class Y, class T > inline void sp_assert_convertible()
{ {
T* p = static_cast< Y* >( 0 );
(void)p;
} }
// pointer constructor helper // pointer constructor helper
@@ -221,7 +223,7 @@ template< class T, class Y > inline void sp_pointer_construct( boost::shared_ptr
template< class T, class Y > inline void sp_pointer_construct( boost::shared_ptr< T[] > * /*ppx*/, Y * p, boost::detail::shared_count & pn ) template< class T, class Y > inline void sp_pointer_construct( boost::shared_ptr< T[] > * /*ppx*/, Y * p, boost::detail::shared_count & pn )
{ {
sp_assert_convertible< T[] >( static_cast< Y (*) [] >( 0 ) ); sp_assert_convertible< Y[], T[] >();
boost::detail::shared_count( p, boost::checked_array_deleter< T >() ).swap( pn ); boost::detail::shared_count( p, boost::checked_array_deleter< T >() ).swap( pn );
} }
@@ -239,7 +241,7 @@ template< class T, class Y > inline void sp_deleter_construct( boost::shared_ptr
template< class T, class Y > inline void sp_deleter_construct( boost::shared_ptr< T[] > * /*ppx*/, Y * /*p*/ ) template< class T, class Y > inline void sp_deleter_construct( boost::shared_ptr< T[] > * /*ppx*/, Y * /*p*/ )
{ {
sp_assert_convertible< T[] >( static_cast< Y (*) [] >( 0 ) ); sp_assert_convertible< Y[], T[] >();
} }
#endif // !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION ) #endif // !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION )
@@ -309,7 +311,7 @@ public:
template<class Y> template<class Y>
explicit shared_ptr( weak_ptr<Y> const & r ): pn( r.pn ) // may throw explicit shared_ptr( weak_ptr<Y> const & r ): pn( r.pn ) // may throw
{ {
boost::detail::sp_assert_convertible< T >( static_cast< Y* >( 0 ) ); boost::detail::sp_assert_convertible< Y, T >();
// it is now safe to copy r.px, as pn(r.pn) did not throw // it is now safe to copy r.px, as pn(r.pn) did not throw
px = r.px; px = r.px;
@@ -336,7 +338,7 @@ public:
#endif #endif
: px( r.px ), pn( r.pn ) // never throws : px( r.px ), pn( r.pn ) // never throws
{ {
boost::detail::sp_assert_convertible< T >( static_cast< Y* >( 0 ) ); boost::detail::sp_assert_convertible< Y, T >();
} }
// aliasing // aliasing
@@ -378,7 +380,7 @@ public:
template<class Y> template<class Y>
explicit shared_ptr(std::auto_ptr<Y> & r): px(r.get()), pn() explicit shared_ptr(std::auto_ptr<Y> & r): px(r.get()), pn()
{ {
boost::detail::sp_assert_convertible< T >( static_cast< Y* >( 0 ) ); boost::detail::sp_assert_convertible< Y, T >();
Y * tmp = r.get(); Y * tmp = r.get();
pn = boost::detail::shared_count(r); pn = boost::detail::shared_count(r);
@@ -393,7 +395,7 @@ public:
{ {
typedef typename Ap::element_type Y; typedef typename Ap::element_type Y;
boost::detail::sp_assert_convertible< T >( static_cast< Y* >( 0 ) ); boost::detail::sp_assert_convertible< Y, T >();
Y * tmp = r.get(); Y * tmp = r.get();
pn = boost::detail::shared_count( r ); pn = boost::detail::shared_count( r );
@@ -410,7 +412,7 @@ public:
template< class Y, class D > template< class Y, class D >
shared_ptr( std::unique_ptr< Y, D > && r ): px( r.get() ), pn() shared_ptr( std::unique_ptr< Y, D > && r ): px( r.get() ), pn()
{ {
boost::detail::sp_assert_convertible< T >( static_cast< Y* >( 0 ) ); boost::detail::sp_assert_convertible< Y, T >();
typename std::unique_ptr< Y, D >::pointer tmp = r.get(); typename std::unique_ptr< Y, D >::pointer tmp = r.get();
pn = boost::detail::shared_count( r ); pn = boost::detail::shared_count( r );
@@ -483,7 +485,7 @@ public:
#endif #endif
: px( r.px ), pn() // never throws : px( r.px ), pn() // never throws
{ {
boost::detail::sp_assert_convertible< T >( static_cast< Y* >( 0 ) ); boost::detail::sp_assert_convertible< Y, T >();
pn.swap( r.pn ); pn.swap( r.pn );
r.px = 0; r.px = 0;

View File

@@ -83,7 +83,7 @@ public:
#endif #endif
: px(r.lock().get()), pn(r.pn) // never throws : px(r.lock().get()), pn(r.pn) // never throws
{ {
boost::detail::sp_assert_convertible< T >( static_cast< Y* >( 0 ) ); boost::detail::sp_assert_convertible< Y, T >();
} }
#if defined( BOOST_HAS_RVALUE_REFS ) #if defined( BOOST_HAS_RVALUE_REFS )
@@ -100,7 +100,7 @@ public:
#endif #endif
: px( r.lock().get() ), pn( static_cast< boost::detail::weak_count && >( r.pn ) ) // never throws : px( r.lock().get() ), pn( static_cast< boost::detail::weak_count && >( r.pn ) ) // never throws
{ {
boost::detail::sp_assert_convertible< T >( static_cast< Y* >( 0 ) ); boost::detail::sp_assert_convertible< Y, T >();
r.px = 0; r.px = 0;
} }
@@ -132,7 +132,7 @@ public:
#endif #endif
: px( r.px ), pn( r.pn ) // never throws : px( r.px ), pn( r.pn ) // never throws
{ {
boost::detail::sp_assert_convertible< T >( static_cast< Y* >( 0 ) ); boost::detail::sp_assert_convertible< Y, T >();
} }
#if !defined(BOOST_MSVC) || (BOOST_MSVC >= 1300) #if !defined(BOOST_MSVC) || (BOOST_MSVC >= 1300)
@@ -140,7 +140,7 @@ public:
template<class Y> template<class Y>
weak_ptr & operator=( weak_ptr<Y> const & r ) // never throws weak_ptr & operator=( weak_ptr<Y> const & r ) // never throws
{ {
boost::detail::sp_assert_convertible< T >( static_cast< Y* >( 0 ) ); boost::detail::sp_assert_convertible< Y, T >();
px = r.lock().get(); px = r.lock().get();
pn = r.pn; pn = r.pn;
@@ -162,7 +162,7 @@ public:
template<class Y> template<class Y>
weak_ptr & operator=( shared_ptr<Y> const & r ) // never throws weak_ptr & operator=( shared_ptr<Y> const & r ) // never throws
{ {
boost::detail::sp_assert_convertible< T >( static_cast< Y* >( 0 ) ); boost::detail::sp_assert_convertible< Y, T >();
px = r.px; px = r.px;
pn = r.pn; pn = r.pn;
@@ -204,7 +204,7 @@ public:
} }
template<typename Y> template<typename Y>
void _internal_aliasing_assign(weak_ptr<Y> const & r, T * px2) void _internal_aliasing_assign(weak_ptr<Y> const & r, element_type * px2)
{ {
px = px2; px = px2;
pn = r.pn; pn = r.pn;

View File

@@ -71,6 +71,7 @@ import testing ;
[ run owner_less_test.cpp ] [ run owner_less_test.cpp ]
[ run sp_unique_ptr_test.cpp ] [ run sp_unique_ptr_test.cpp ]
[ run sp_array_test.cpp ] [ run sp_array_test.cpp ]
[ compile sp_array_cv_test.cpp ]
[ compile-fail array_fail_spa_sp_c.cpp ] [ compile-fail array_fail_spa_sp_c.cpp ]
[ compile-fail array_fail_sp_spa_c.cpp ] [ compile-fail array_fail_sp_spa_c.cpp ]

42
test/sp_array_cv_test.cpp Normal file
View File

@@ -0,0 +1,42 @@
//
// sp_array_cv_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>
struct X
{
};
int main()
{
boost::shared_ptr< X[] > px;
boost::shared_ptr< X const[] > pcx( px );
boost::shared_ptr< X volatile[] > pvx( px );
boost::shared_ptr< X const volatile[] > pcvx( px );
boost::shared_ptr< X const volatile[] > pcvx2( pcx );
boost::shared_ptr< X const volatile[] > pcvx3( pvx );
boost::shared_ptr< void > pv( px );
boost::shared_ptr< void const > pcv( px );
boost::shared_ptr< void const > pcv2( pcx );
boost::shared_ptr< void volatile > pvv( px );
boost::shared_ptr< void volatile > pvv2( pvx );
boost::shared_ptr< void const volatile > pcvv( px );
boost::shared_ptr< void const volatile > pcvv2( pcx );
boost::shared_ptr< void const volatile > pcvv3( pvx );
boost::shared_ptr< void const volatile > pcvv4( pcvx );
return 0;
}