diff --git a/.travis.yml b/.travis.yml
index 7cc89de..fb53d45 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -16,8 +16,9 @@ branches:
- develop
install:
- - git clone -b $TRAVIS_BRANCH https://github.com/boostorg/boost.git boost
- - cd boost
+ - cd ..
+ - git clone -b $TRAVIS_BRANCH https://github.com/boostorg/boost.git boost-root
+ - cd boost-root
- git submodule init libs/align
- git submodule init libs/assert
- git submodule init libs/atomic
@@ -29,16 +30,13 @@ install:
- git submodule init libs/move
- git submodule init libs/predef
- git submodule init libs/preprocessor
- - git submodule init libs/smart_ptr
- git submodule init libs/static_assert
- git submodule init libs/throw_exception
- git submodule init libs/type_traits
- git submodule init tools/build
- git submodule init tools/inspect
- git submodule update
- - cd libs/smart_ptr
- - git checkout -q $TRAVIS_COMMIT
- - cd ../..
+ - cp -r $TRAVIS_BUILD_DIR/* libs/smart_ptr
- ./bootstrap.sh
- ./b2 headers
@@ -46,3 +44,7 @@ script:
- TOOLSET=gcc,clang
- if [ $TRAVIS_OS_NAME == osx ]; then TOOLSET=clang; fi
- ./b2 libs/smart_ptr/test toolset=$TOOLSET
+
+notifications:
+ email:
+ on_success: always
diff --git a/appveyor.yml b/appveyor.yml
index 1fbbf38..d35c12d 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -12,8 +12,9 @@ branches:
- develop
install:
- - git clone -b %APPVEYOR_REPO_BRANCH% https://github.com/boostorg/boost.git boost
- - cd boost
+ - cd ..
+ - git clone -b %APPVEYOR_REPO_BRANCH% https://github.com/boostorg/boost.git boost-root
+ - cd boost-root
- git submodule init libs/align
- git submodule init libs/assert
- git submodule init libs/atomic
@@ -25,20 +26,17 @@ install:
- git submodule init libs/move
- git submodule init libs/predef
- git submodule init libs/preprocessor
- - git submodule init libs/smart_ptr
- git submodule init libs/static_assert
- git submodule init libs/throw_exception
- git submodule init libs/type_traits
- git submodule init tools/build
- git submodule init tools/inspect
- git submodule update
- - cd libs\smart_ptr
- - git checkout -q %APPVEYOR_REPO_COMMIT%
- - cd ..\..
+ - xcopy /s /e /q %APPVEYOR_BUILD_FOLDER% libs\smart_ptr
- bootstrap
- b2 headers
build: off
test_script:
- - b2 libs/smart_ptr/test toolset=msvc-9.0,msvc-10.0,msvc-11.0,msvc-12.0
+ - b2 libs/smart_ptr/test toolset=msvc-9.0,msvc-10.0,msvc-11.0,msvc-14.0
diff --git a/include/boost/pointer_cast.hpp b/include/boost/pointer_cast.hpp
index 6e532eb..5af4971 100644
--- a/include/boost/pointer_cast.hpp
+++ b/include/boost/pointer_cast.hpp
@@ -10,6 +10,8 @@
#ifndef BOOST_POINTER_CAST_HPP
#define BOOST_POINTER_CAST_HPP
+#include
+
namespace boost {
//static_pointer_cast overload for raw pointers
@@ -42,4 +44,78 @@ inline T* reinterpret_pointer_cast(U *ptr)
} // namespace boost
+#if !defined( BOOST_NO_CXX11_SMART_PTR )
+
+#include
+#include
+#include
+
+namespace boost {
+
+//static_pointer_cast overload for std::shared_ptr
+using std::static_pointer_cast;
+
+//dynamic_pointer_cast overload for std::shared_ptr
+using std::dynamic_pointer_cast;
+
+//const_pointer_cast overload for std::shared_ptr
+using std::const_pointer_cast;
+
+//reinterpret_pointer_cast overload for std::shared_ptr
+template std::shared_ptr reinterpret_pointer_cast(const std::shared_ptr & r ) BOOST_NOEXCEPT
+{
+ (void) reinterpret_cast< T* >( static_cast< U* >( 0 ) );
+
+ typedef typename std::shared_ptr::element_type E;
+
+ E * p = reinterpret_cast< E* >( r.get() );
+ return std::shared_ptr( r, p );
+}
+
+//static_pointer_cast overload for std::unique_ptr
+template std::unique_ptr static_pointer_cast( std::unique_ptr && r ) BOOST_NOEXCEPT
+{
+ (void) static_cast< T* >( static_cast< U* >( 0 ) );
+
+ typedef typename std::unique_ptr::element_type E;
+
+ return std::unique_ptr( static_cast( r.release() ) );
+}
+
+//dynamic_pointer_cast overload for std::unique_ptr
+template std::unique_ptr dynamic_pointer_cast( std::unique_ptr && r ) BOOST_NOEXCEPT
+{
+ (void) dynamic_cast< T* >( static_cast< U* >( 0 ) );
+
+ BOOST_STATIC_ASSERT_MSG( boost::has_virtual_destructor::value, "The target of dynamic_pointer_cast must have a virtual destructor." );
+
+ T * p = dynamic_cast( r.get() );
+ if( p ) r.release();
+ return std::unique_ptr( p );
+}
+
+//const_pointer_cast overload for std::unique_ptr
+template std::unique_ptr const_pointer_cast( std::unique_ptr && r ) BOOST_NOEXCEPT
+{
+ (void) const_cast< T* >( static_cast< U* >( 0 ) );
+
+ typedef typename std::unique_ptr::element_type E;
+
+ return std::unique_ptr( const_cast( r.release() ) );
+}
+
+//reinterpret_pointer_cast overload for std::unique_ptr
+template std::unique_ptr reinterpret_pointer_cast( std::unique_ptr && r ) BOOST_NOEXCEPT
+{
+ (void) reinterpret_cast< T* >( static_cast< U* >( 0 ) );
+
+ typedef typename std::unique_ptr::element_type E;
+
+ return std::unique_ptr( reinterpret_cast( r.release() ) );
+}
+
+} // namespace boost
+
+#endif // #if !defined( BOOST_NO_CXX11_SMART_PTR )
+
#endif //BOOST_POINTER_CAST_HPP
diff --git a/include/boost/smart_ptr/bad_weak_ptr.hpp b/include/boost/smart_ptr/bad_weak_ptr.hpp
index 3e0a1b7..582fad8 100644
--- a/include/boost/smart_ptr/bad_weak_ptr.hpp
+++ b/include/boost/smart_ptr/bad_weak_ptr.hpp
@@ -36,6 +36,11 @@ namespace boost
# pragma option push -pc
#endif
+#if defined(__clang__)
+# pragma clang diagnostic push
+# pragma clang diagnostic ignored "-Wweak-vtables"
+#endif
+
class bad_weak_ptr: public std::exception
{
public:
@@ -46,6 +51,10 @@ public:
}
};
+#if defined(__clang__)
+# pragma clang diagnostic pop
+#endif
+
#if defined(__BORLANDC__) && __BORLANDC__ <= 0x564
# pragma option pop
#endif
diff --git a/include/boost/smart_ptr/detail/atomic_count.hpp b/include/boost/smart_ptr/detail/atomic_count.hpp
index 8aefd44..6e4f71a 100644
--- a/include/boost/smart_ptr/detail/atomic_count.hpp
+++ b/include/boost/smart_ptr/detail/atomic_count.hpp
@@ -73,6 +73,9 @@
#elif defined( BOOST_DISABLE_THREADS ) && !defined( BOOST_SP_ENABLE_THREADS ) && !defined( BOOST_DISABLE_WIN32 )
# include
+#elif !defined( BOOST_NO_CXX11_HDR_ATOMIC )
+# include
+
#elif defined( __GNUC__ ) && ( defined( __i386__ ) || defined( __x86_64__ ) ) && !defined( __PATHSCALE__ )
# include
diff --git a/include/boost/smart_ptr/detail/sp_counted_base.hpp b/include/boost/smart_ptr/detail/sp_counted_base.hpp
index 0addf07..83ede23 100644
--- a/include/boost/smart_ptr/detail/sp_counted_base.hpp
+++ b/include/boost/smart_ptr/detail/sp_counted_base.hpp
@@ -44,6 +44,9 @@
#elif defined( BOOST_SP_HAS_CLANG_C11_ATOMICS )
# include
+#elif !defined( BOOST_NO_CXX11_HDR_ATOMIC )
+# include
+
#elif defined( __SNC__ )
# include
@@ -65,7 +68,7 @@
#elif defined( __GNUC__ ) && ( defined( __powerpc__ ) || defined( __ppc__ ) || defined( __ppc ) ) && !defined(__PATHSCALE__) && !defined( _AIX )
# include
-#elif defined( __GNUC__ ) && ( defined( __mips__ ) || defined( _mips ) ) && !defined(__PATHSCALE__)
+#elif defined( __GNUC__ ) && ( defined( __mips__ ) || defined( _mips ) ) && !defined(__PATHSCALE__) && !defined( __mips16 )
# include
#elif defined( BOOST_SP_HAS_SYNC )
diff --git a/include/boost/smart_ptr/detail/sp_counted_base_clang.hpp b/include/boost/smart_ptr/detail/sp_counted_base_clang.hpp
index c66b985..7598495 100644
--- a/include/boost/smart_ptr/detail/sp_counted_base_clang.hpp
+++ b/include/boost/smart_ptr/detail/sp_counted_base_clang.hpp
@@ -58,6 +58,11 @@ inline boost::int_least32_t atomic_conditional_increment( atomic_int_least32_t *
}
}
+#if defined(__clang__)
+# pragma clang diagnostic push
+# pragma clang diagnostic ignored "-Wweak-vtables"
+#endif
+
class sp_counted_base
{
private:
@@ -133,6 +138,10 @@ public:
}
};
+#if defined(__clang__)
+# pragma clang diagnostic pop
+#endif
+
} // namespace detail
} // namespace boost
diff --git a/include/boost/smart_ptr/detail/spinlock.hpp b/include/boost/smart_ptr/detail/spinlock.hpp
index 19f93d7..0b618df 100644
--- a/include/boost/smart_ptr/detail/spinlock.hpp
+++ b/include/boost/smart_ptr/detail/spinlock.hpp
@@ -43,6 +43,9 @@
#elif defined( BOOST_SP_USE_PTHREADS )
# include
+#elif !defined( BOOST_NO_CXX11_HDR_ATOMIC )
+# include
+
#elif defined(__GNUC__) && defined( __arm__ ) && !defined( __thumb__ )
# include
diff --git a/include/boost/smart_ptr/make_shared_object.hpp b/include/boost/smart_ptr/make_shared_object.hpp
index 62372fa..3bc78ee 100644
--- a/include/boost/smart_ptr/make_shared_object.hpp
+++ b/include/boost/smart_ptr/make_shared_object.hpp
@@ -13,6 +13,8 @@
// for documentation.
#include
+#include
+#include
#include
#include
#include
@@ -338,466 +340,10 @@ template< class T, class A > typename boost::detail::sp_if_not_array< T >::type
return boost::shared_ptr< T >( pt, pt2 );
}
-#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
-
-// For example MSVC 10.0
-
-template< class T, class A1 >
-typename boost::detail::sp_if_not_array< T >::type make_shared( A1 && a1 )
-{
- boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ) );
-
- boost::detail::sp_ms_deleter< T > * pd = static_cast *>( pt._internal_get_untyped_deleter() );
-
- void * pv = pd->address();
-
- ::new( pv ) T(
- boost::detail::sp_forward( a1 )
- );
-
- pd->set_initialized();
-
- T * pt2 = static_cast< T* >( pv );
-
- boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
- return boost::shared_ptr< T >( pt, pt2 );
-}
-
-template< class T, class A, class A1 >
-typename boost::detail::sp_if_not_array< T >::type allocate_shared( A const & a, A1 && a1 )
-{
- boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ), a );
-
- boost::detail::sp_ms_deleter< T > * pd = static_cast *>( pt._internal_get_untyped_deleter() );
-
- void * pv = pd->address();
-
- ::new( pv ) T(
- boost::detail::sp_forward( a1 )
- );
-
- pd->set_initialized();
-
- T * pt2 = static_cast< T* >( pv );
-
- boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
- return boost::shared_ptr< T >( pt, pt2 );
-}
-
-template< class T, class A1, class A2 >
-typename boost::detail::sp_if_not_array< T >::type make_shared( A1 && a1, A2 && a2 )
-{
- boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ) );
-
- boost::detail::sp_ms_deleter< T > * pd = static_cast *>( pt._internal_get_untyped_deleter() );
-
- void * pv = pd->address();
-
- ::new( pv ) T(
- boost::detail::sp_forward( a1 ),
- boost::detail::sp_forward( a2 )
- );
-
- pd->set_initialized();
-
- T * pt2 = static_cast< T* >( pv );
-
- boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
- return boost::shared_ptr< T >( pt, pt2 );
-}
-
-template< class T, class A, class A1, class A2 >
-typename boost::detail::sp_if_not_array< T >::type allocate_shared( A const & a, A1 && a1, A2 && a2 )
-{
- boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ), a );
-
- boost::detail::sp_ms_deleter< T > * pd = static_cast *>( pt._internal_get_untyped_deleter() );
-
- void * pv = pd->address();
-
- ::new( pv ) T(
- boost::detail::sp_forward( a1 ),
- boost::detail::sp_forward( a2 )
- );
-
- pd->set_initialized();
-
- T * pt2 = static_cast< T* >( pv );
-
- boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
- return boost::shared_ptr< T >( pt, pt2 );
-}
-
-template< class T, class A1, class A2, class A3 >
-typename boost::detail::sp_if_not_array< T >::type make_shared( A1 && a1, A2 && a2, A3 && a3 )
-{
- boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ) );
-
- boost::detail::sp_ms_deleter< T > * pd = static_cast *>( pt._internal_get_untyped_deleter() );
-
- void * pv = pd->address();
-
- ::new( pv ) T(
- boost::detail::sp_forward( a1 ),
- boost::detail::sp_forward( a2 ),
- boost::detail::sp_forward( a3 )
- );
-
- pd->set_initialized();
-
- T * pt2 = static_cast< T* >( pv );
-
- boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
- return boost::shared_ptr< T >( pt, pt2 );
-}
-
-template< class T, class A, class A1, class A2, class A3 >
-typename boost::detail::sp_if_not_array< T >::type allocate_shared( A const & a, A1 && a1, A2 && a2, A3 && a3 )
-{
- boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ), a );
-
- boost::detail::sp_ms_deleter< T > * pd = static_cast *>( pt._internal_get_untyped_deleter() );
-
- void * pv = pd->address();
-
- ::new( pv ) T(
- boost::detail::sp_forward( a1 ),
- boost::detail::sp_forward( a2 ),
- boost::detail::sp_forward( a3 )
- );
-
- pd->set_initialized();
-
- T * pt2 = static_cast< T* >( pv );
-
- boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
- return boost::shared_ptr< T >( pt, pt2 );
-}
-
-template< class T, class A1, class A2, class A3, class A4 >
-typename boost::detail::sp_if_not_array< T >::type make_shared( A1 && a1, A2 && a2, A3 && a3, A4 && a4 )
-{
- boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ) );
-
- boost::detail::sp_ms_deleter< T > * pd = static_cast *>( pt._internal_get_untyped_deleter() );
-
- void * pv = pd->address();
-
- ::new( pv ) T(
- boost::detail::sp_forward( a1 ),
- boost::detail::sp_forward( a2 ),
- boost::detail::sp_forward( a3 ),
- boost::detail::sp_forward( a4 )
- );
-
- pd->set_initialized();
-
- T * pt2 = static_cast< T* >( pv );
-
- boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
- return boost::shared_ptr< T >( pt, pt2 );
-}
-
-template< class T, class A, class A1, class A2, class A3, class A4 >
-typename boost::detail::sp_if_not_array< T >::type allocate_shared( A const & a, A1 && a1, A2 && a2, A3 && a3, A4 && a4 )
-{
- boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ), a );
-
- boost::detail::sp_ms_deleter< T > * pd = static_cast *>( pt._internal_get_untyped_deleter() );
-
- void * pv = pd->address();
-
- ::new( pv ) T(
- boost::detail::sp_forward( a1 ),
- boost::detail::sp_forward( a2 ),
- boost::detail::sp_forward( a3 ),
- boost::detail::sp_forward( a4 )
- );
-
- pd->set_initialized();
-
- T * pt2 = static_cast< T* >( pv );
-
- boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
- return boost::shared_ptr< T >( pt, pt2 );
-}
-
-template< class T, class A1, class A2, class A3, class A4, class A5 >
-typename boost::detail::sp_if_not_array< T >::type make_shared( A1 && a1, A2 && a2, A3 && a3, A4 && a4, A5 && a5 )
-{
- boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ) );
-
- boost::detail::sp_ms_deleter< T > * pd = static_cast *>( pt._internal_get_untyped_deleter() );
-
- void * pv = pd->address();
-
- ::new( pv ) T(
- boost::detail::sp_forward( a1 ),
- boost::detail::sp_forward( a2 ),
- boost::detail::sp_forward( a3 ),
- boost::detail::sp_forward( a4 ),
- boost::detail::sp_forward( a5 )
- );
-
- pd->set_initialized();
-
- T * pt2 = static_cast< T* >( pv );
-
- boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
- return boost::shared_ptr< T >( pt, pt2 );
-}
-
-template< class T, class A, class A1, class A2, class A3, class A4, class A5 >
-typename boost::detail::sp_if_not_array< T >::type allocate_shared( A const & a, A1 && a1, A2 && a2, A3 && a3, A4 && a4, A5 && a5 )
-{
- boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ), a );
-
- boost::detail::sp_ms_deleter< T > * pd = static_cast *>( pt._internal_get_untyped_deleter() );
-
- void * pv = pd->address();
-
- ::new( pv ) T(
- boost::detail::sp_forward( a1 ),
- boost::detail::sp_forward( a2 ),
- boost::detail::sp_forward( a3 ),
- boost::detail::sp_forward( a4 ),
- boost::detail::sp_forward( a5 )
- );
-
- pd->set_initialized();
-
- T * pt2 = static_cast< T* >( pv );
-
- boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
- return boost::shared_ptr< T >( pt, pt2 );
-}
-
-template< class T, class A1, class A2, class A3, class A4, class A5, class A6 >
-typename boost::detail::sp_if_not_array< T >::type make_shared( A1 && a1, A2 && a2, A3 && a3, A4 && a4, A5 && a5, A6 && a6 )
-{
- boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ) );
-
- boost::detail::sp_ms_deleter< T > * pd = static_cast *>( pt._internal_get_untyped_deleter() );
-
- void * pv = pd->address();
-
- ::new( pv ) T(
- boost::detail::sp_forward( a1 ),
- boost::detail::sp_forward( a2 ),
- boost::detail::sp_forward( a3 ),
- boost::detail::sp_forward( a4 ),
- boost::detail::sp_forward( a5 ),
- boost::detail::sp_forward( a6 )
- );
-
- pd->set_initialized();
-
- T * pt2 = static_cast< T* >( pv );
-
- boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
- return boost::shared_ptr< T >( pt, pt2 );
-}
-
-template< class T, class A, class A1, class A2, class A3, class A4, class A5, class A6 >
-typename boost::detail::sp_if_not_array< T >::type allocate_shared( A const & a, A1 && a1, A2 && a2, A3 && a3, A4 && a4, A5 && a5, A6 && a6 )
-{
- boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ), a );
-
- boost::detail::sp_ms_deleter< T > * pd = static_cast *>( pt._internal_get_untyped_deleter() );
-
- void * pv = pd->address();
-
- ::new( pv ) T(
- boost::detail::sp_forward( a1 ),
- boost::detail::sp_forward( a2 ),
- boost::detail::sp_forward( a3 ),
- boost::detail::sp_forward( a4 ),
- boost::detail::sp_forward( a5 ),
- boost::detail::sp_forward( a6 )
- );
-
- pd->set_initialized();
-
- T * pt2 = static_cast< T* >( pv );
-
- boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
- return boost::shared_ptr< T >( pt, pt2 );
-}
-
-template< class T, class A1, class A2, class A3, class A4, class A5, class A6, class A7 >
-typename boost::detail::sp_if_not_array< T >::type make_shared( A1 && a1, A2 && a2, A3 && a3, A4 && a4, A5 && a5, A6 && a6, A7 && a7 )
-{
- boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ) );
-
- boost::detail::sp_ms_deleter< T > * pd = static_cast *>( pt._internal_get_untyped_deleter() );
-
- void * pv = pd->address();
-
- ::new( pv ) T(
- boost::detail::sp_forward( a1 ),
- boost::detail::sp_forward( a2 ),
- boost::detail::sp_forward( a3 ),
- boost::detail::sp_forward( a4 ),
- boost::detail::sp_forward( a5 ),
- boost::detail::sp_forward( a6 ),
- boost::detail::sp_forward( a7 )
- );
-
- pd->set_initialized();
-
- T * pt2 = static_cast< T* >( pv );
-
- boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
- return boost::shared_ptr< T >( pt, pt2 );
-}
-
-template< class T, class A, class A1, class A2, class A3, class A4, class A5, class A6, class A7 >
-typename boost::detail::sp_if_not_array< T >::type allocate_shared( A const & a, A1 && a1, A2 && a2, A3 && a3, A4 && a4, A5 && a5, A6 && a6, A7 && a7 )
-{
- boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ), a );
-
- boost::detail::sp_ms_deleter< T > * pd = static_cast *>( pt._internal_get_untyped_deleter() );
-
- void * pv = pd->address();
-
- ::new( pv ) T(
- boost::detail::sp_forward( a1 ),
- boost::detail::sp_forward( a2 ),
- boost::detail::sp_forward( a3 ),
- boost::detail::sp_forward( a4 ),
- boost::detail::sp_forward( a5 ),
- boost::detail::sp_forward( a6 ),
- boost::detail::sp_forward( a7 )
- );
-
- pd->set_initialized();
-
- T * pt2 = static_cast< T* >( pv );
-
- boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
- return boost::shared_ptr< T >( pt, pt2 );
-}
-
-template< class T, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8 >
-typename boost::detail::sp_if_not_array< T >::type make_shared( A1 && a1, A2 && a2, A3 && a3, A4 && a4, A5 && a5, A6 && a6, A7 && a7, A8 && a8 )
-{
- boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ) );
-
- boost::detail::sp_ms_deleter< T > * pd = static_cast *>( pt._internal_get_untyped_deleter() );
-
- void * pv = pd->address();
-
- ::new( pv ) T(
- boost::detail::sp_forward( a1 ),
- boost::detail::sp_forward( a2 ),
- boost::detail::sp_forward( a3 ),
- boost::detail::sp_forward( a4 ),
- boost::detail::sp_forward( a5 ),
- boost::detail::sp_forward( a6 ),
- boost::detail::sp_forward( a7 ),
- boost::detail::sp_forward( a8 )
- );
-
- pd->set_initialized();
-
- T * pt2 = static_cast< T* >( pv );
-
- boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
- return boost::shared_ptr< T >( pt, pt2 );
-}
-
-template< class T, class A, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8 >
-typename boost::detail::sp_if_not_array< T >::type allocate_shared( A const & a, A1 && a1, A2 && a2, A3 && a3, A4 && a4, A5 && a5, A6 && a6, A7 && a7, A8 && a8 )
-{
- boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ), a );
-
- boost::detail::sp_ms_deleter< T > * pd = static_cast *>( pt._internal_get_untyped_deleter() );
-
- void * pv = pd->address();
-
- ::new( pv ) T(
- boost::detail::sp_forward( a1 ),
- boost::detail::sp_forward( a2 ),
- boost::detail::sp_forward( a3 ),
- boost::detail::sp_forward( a4 ),
- boost::detail::sp_forward( a5 ),
- boost::detail::sp_forward( a6 ),
- boost::detail::sp_forward( a7 ),
- boost::detail::sp_forward( a8 )
- );
-
- pd->set_initialized();
-
- T * pt2 = static_cast< T* >( pv );
-
- boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
- return boost::shared_ptr< T >( pt, pt2 );
-}
-
-template< class T, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9 >
-typename boost::detail::sp_if_not_array< T >::type make_shared( A1 && a1, A2 && a2, A3 && a3, A4 && a4, A5 && a5, A6 && a6, A7 && a7, A8 && a8, A9 && a9 )
-{
- boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ) );
-
- boost::detail::sp_ms_deleter< T > * pd = static_cast *>( pt._internal_get_untyped_deleter() );
-
- void * pv = pd->address();
-
- ::new( pv ) T(
- boost::detail::sp_forward( a1 ),
- boost::detail::sp_forward( a2 ),
- boost::detail::sp_forward( a3 ),
- boost::detail::sp_forward( a4 ),
- boost::detail::sp_forward( a5 ),
- boost::detail::sp_forward( a6 ),
- boost::detail::sp_forward( a7 ),
- boost::detail::sp_forward( a8 ),
- boost::detail::sp_forward( a9 )
- );
-
- pd->set_initialized();
-
- T * pt2 = static_cast< T* >( pv );
-
- boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
- return boost::shared_ptr< T >( pt, pt2 );
-}
-
-template< class T, class A, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9 >
-typename boost::detail::sp_if_not_array< T >::type allocate_shared( A const & a, A1 && a1, A2 && a2, A3 && a3, A4 && a4, A5 && a5, A6 && a6, A7 && a7, A8 && a8, A9 && a9 )
-{
- boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ), a );
-
- boost::detail::sp_ms_deleter< T > * pd = static_cast *>( pt._internal_get_untyped_deleter() );
-
- void * pv = pd->address();
-
- ::new( pv ) T(
- boost::detail::sp_forward( a1 ),
- boost::detail::sp_forward( a2 ),
- boost::detail::sp_forward( a3 ),
- boost::detail::sp_forward( a4 ),
- boost::detail::sp_forward( a5 ),
- boost::detail::sp_forward( a6 ),
- boost::detail::sp_forward( a7 ),
- boost::detail::sp_forward( a8 ),
- boost::detail::sp_forward( a9 )
- );
-
- pd->set_initialized();
-
- T * pt2 = static_cast< T* >( pv );
-
- boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
- return boost::shared_ptr< T >( pt, pt2 );
-}
-
-#else // !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
-
// C++03 version
template< class T, class A1 >
-typename boost::detail::sp_if_not_array< T >::type make_shared( A1 const & a1 )
+typename boost::detail::sp_if_not_array< T >::type make_shared( BOOST_FWD_REF(A1) a1 )
{
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ) );
@@ -805,7 +351,10 @@ typename boost::detail::sp_if_not_array< T >::type make_shared( A1 const & a1 )
void * pv = pd->address();
- ::new( pv ) T( a1 );
+ ::new( pv ) T(
+ boost::forward( a1 )
+ );
+
pd->set_initialized();
T * pt2 = static_cast< T* >( pv );
@@ -815,7 +364,7 @@ typename boost::detail::sp_if_not_array< T >::type make_shared( A1 const & a1 )
}
template< class T, class A, class A1 >
-typename boost::detail::sp_if_not_array< T >::type allocate_shared( A const & a, A1 const & a1 )
+typename boost::detail::sp_if_not_array< T >::type allocate_shared( A const & a, BOOST_FWD_REF(A1) a1 )
{
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ), a );
@@ -823,7 +372,10 @@ typename boost::detail::sp_if_not_array< T >::type allocate_shared( A const & a,
void * pv = pd->address();
- ::new( pv ) T( a1 );
+ ::new( pv ) T(
+ boost::forward( a1 )
+ );
+
pd->set_initialized();
T * pt2 = static_cast< T* >( pv );
@@ -833,7 +385,7 @@ typename boost::detail::sp_if_not_array< T >::type allocate_shared( A const & a,
}
template< class T, class A1, class A2 >
-typename boost::detail::sp_if_not_array< T >::type make_shared( A1 const & a1, A2 const & a2 )
+typename boost::detail::sp_if_not_array< T >::type make_shared( BOOST_FWD_REF(A1) a1, BOOST_FWD_REF(A2) a2 )
{
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ) );
@@ -841,7 +393,11 @@ typename boost::detail::sp_if_not_array< T >::type make_shared( A1 const & a1, A
void * pv = pd->address();
- ::new( pv ) T( a1, a2 );
+ ::new( pv ) T(
+ boost::forward( a1 ),
+ boost::forward( a2 )
+ );
+
pd->set_initialized();
T * pt2 = static_cast< T* >( pv );
@@ -851,7 +407,7 @@ typename boost::detail::sp_if_not_array< T >::type make_shared( A1 const & a1, A
}
template< class T, class A, class A1, class A2 >
-typename boost::detail::sp_if_not_array< T >::type allocate_shared( A const & a, A1 const & a1, A2 const & a2 )
+typename boost::detail::sp_if_not_array< T >::type allocate_shared( A const & a, BOOST_FWD_REF(A1) a1, BOOST_FWD_REF(A2) a2 )
{
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ), a );
@@ -859,7 +415,11 @@ typename boost::detail::sp_if_not_array< T >::type allocate_shared( A const & a,
void * pv = pd->address();
- ::new( pv ) T( a1, a2 );
+ ::new( pv ) T(
+ boost::forward( a1 ),
+ boost::forward( a2 )
+ );
+
pd->set_initialized();
T * pt2 = static_cast< T* >( pv );
@@ -869,7 +429,7 @@ typename boost::detail::sp_if_not_array< T >::type allocate_shared( A const & a,
}
template< class T, class A1, class A2, class A3 >
-typename boost::detail::sp_if_not_array< T >::type make_shared( A1 const & a1, A2 const & a2, A3 const & a3 )
+typename boost::detail::sp_if_not_array< T >::type make_shared( BOOST_FWD_REF(A1) a1, BOOST_FWD_REF(A2) a2, BOOST_FWD_REF(A3) a3 )
{
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ) );
@@ -877,7 +437,12 @@ typename boost::detail::sp_if_not_array< T >::type make_shared( A1 const & a1, A
void * pv = pd->address();
- ::new( pv ) T( a1, a2, a3 );
+ ::new( pv ) T(
+ boost::forward( a1 ),
+ boost::forward( a2 ),
+ boost::forward( a3 )
+ );
+
pd->set_initialized();
T * pt2 = static_cast< T* >( pv );
@@ -887,7 +452,7 @@ typename boost::detail::sp_if_not_array< T >::type make_shared( A1 const & a1, A
}
template< class T, class A, class A1, class A2, class A3 >
-typename boost::detail::sp_if_not_array< T >::type allocate_shared( A const & a, A1 const & a1, A2 const & a2, A3 const & a3 )
+typename boost::detail::sp_if_not_array< T >::type allocate_shared( A const & a, BOOST_FWD_REF(A1) a1, BOOST_FWD_REF(A2) a2, BOOST_FWD_REF(A3) a3 )
{
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ), a );
@@ -895,7 +460,12 @@ typename boost::detail::sp_if_not_array< T >::type allocate_shared( A const & a,
void * pv = pd->address();
- ::new( pv ) T( a1, a2, a3 );
+ ::new( pv ) T(
+ boost::forward( a1 ),
+ boost::forward( a2 ),
+ boost::forward( a3 )
+ );
+
pd->set_initialized();
T * pt2 = static_cast< T* >( pv );
@@ -905,7 +475,7 @@ typename boost::detail::sp_if_not_array< T >::type allocate_shared( A const & a,
}
template< class T, class A1, class A2, class A3, class A4 >
-typename boost::detail::sp_if_not_array< T >::type make_shared( A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4 )
+typename boost::detail::sp_if_not_array< T >::type make_shared( BOOST_FWD_REF(A1) a1, BOOST_FWD_REF(A2) a2, BOOST_FWD_REF(A3) a3, BOOST_FWD_REF(A4) a4 )
{
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ) );
@@ -913,7 +483,13 @@ typename boost::detail::sp_if_not_array< T >::type make_shared( A1 const & a1, A
void * pv = pd->address();
- ::new( pv ) T( a1, a2, a3, a4 );
+ ::new( pv ) T(
+ boost::forward( a1 ),
+ boost::forward( a2 ),
+ boost::forward( a3 ),
+ boost::forward( a4 )
+ );
+
pd->set_initialized();
T * pt2 = static_cast< T* >( pv );
@@ -923,7 +499,7 @@ typename boost::detail::sp_if_not_array< T >::type make_shared( A1 const & a1, A
}
template< class T, class A, class A1, class A2, class A3, class A4 >
-typename boost::detail::sp_if_not_array< T >::type allocate_shared( A const & a, A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4 )
+typename boost::detail::sp_if_not_array< T >::type allocate_shared( A const & a, BOOST_FWD_REF(A1) a1, BOOST_FWD_REF(A2) a2, BOOST_FWD_REF(A3) a3, BOOST_FWD_REF(A4) a4 )
{
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ), a );
@@ -931,7 +507,13 @@ typename boost::detail::sp_if_not_array< T >::type allocate_shared( A const & a,
void * pv = pd->address();
- ::new( pv ) T( a1, a2, a3, a4 );
+ ::new( pv ) T(
+ boost::forward( a1 ),
+ boost::forward( a2 ),
+ boost::forward( a3 ),
+ boost::forward( a4 )
+ );
+
pd->set_initialized();
T * pt2 = static_cast< T* >( pv );
@@ -941,7 +523,7 @@ typename boost::detail::sp_if_not_array< T >::type allocate_shared( A const & a,
}
template< class T, class A1, class A2, class A3, class A4, class A5 >
-typename boost::detail::sp_if_not_array< T >::type make_shared( A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5 )
+typename boost::detail::sp_if_not_array< T >::type make_shared( BOOST_FWD_REF(A1) a1, BOOST_FWD_REF(A2) a2, BOOST_FWD_REF(A3) a3, BOOST_FWD_REF(A4) a4, BOOST_FWD_REF(A5) a5 )
{
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ) );
@@ -949,7 +531,14 @@ typename boost::detail::sp_if_not_array< T >::type make_shared( A1 const & a1, A
void * pv = pd->address();
- ::new( pv ) T( a1, a2, a3, a4, a5 );
+ ::new( pv ) T(
+ boost::forward( a1 ),
+ boost::forward( a2 ),
+ boost::forward( a3 ),
+ boost::forward( a4 ),
+ boost::forward( a5 )
+ );
+
pd->set_initialized();
T * pt2 = static_cast< T* >( pv );
@@ -959,7 +548,7 @@ typename boost::detail::sp_if_not_array< T >::type make_shared( A1 const & a1, A
}
template< class T, class A, class A1, class A2, class A3, class A4, class A5 >
-typename boost::detail::sp_if_not_array< T >::type allocate_shared( A const & a, A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5 )
+typename boost::detail::sp_if_not_array< T >::type allocate_shared( A const & a, BOOST_FWD_REF(A1) a1, BOOST_FWD_REF(A2) a2, BOOST_FWD_REF(A3) a3, BOOST_FWD_REF(A4) a4, BOOST_FWD_REF(A5) a5 )
{
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ), a );
@@ -967,7 +556,14 @@ typename boost::detail::sp_if_not_array< T >::type allocate_shared( A const & a,
void * pv = pd->address();
- ::new( pv ) T( a1, a2, a3, a4, a5 );
+ ::new( pv ) T(
+ boost::forward( a1 ),
+ boost::forward( a2 ),
+ boost::forward( a3 ),
+ boost::forward( a4 ),
+ boost::forward( a5 )
+ );
+
pd->set_initialized();
T * pt2 = static_cast< T* >( pv );
@@ -977,7 +573,7 @@ typename boost::detail::sp_if_not_array< T >::type allocate_shared( A const & a,
}
template< class T, class A1, class A2, class A3, class A4, class A5, class A6 >
-typename boost::detail::sp_if_not_array< T >::type make_shared( A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5, A6 const & a6 )
+typename boost::detail::sp_if_not_array< T >::type make_shared( BOOST_FWD_REF(A1) a1, BOOST_FWD_REF(A2) a2, BOOST_FWD_REF(A3) a3, BOOST_FWD_REF(A4) a4, BOOST_FWD_REF(A5) a5, BOOST_FWD_REF(A6) a6 )
{
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ) );
@@ -985,7 +581,15 @@ typename boost::detail::sp_if_not_array< T >::type make_shared( A1 const & a1, A
void * pv = pd->address();
- ::new( pv ) T( a1, a2, a3, a4, a5, a6 );
+ ::new( pv ) T(
+ boost::forward( a1 ),
+ boost::forward( a2 ),
+ boost::forward( a3 ),
+ boost::forward( a4 ),
+ boost::forward( a5 ),
+ boost::forward( a6 )
+ );
+
pd->set_initialized();
T * pt2 = static_cast< T* >( pv );
@@ -995,7 +599,7 @@ typename boost::detail::sp_if_not_array< T >::type make_shared( A1 const & a1, A
}
template< class T, class A, class A1, class A2, class A3, class A4, class A5, class A6 >
-typename boost::detail::sp_if_not_array< T >::type allocate_shared( A const & a, A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5, A6 const & a6 )
+typename boost::detail::sp_if_not_array< T >::type allocate_shared( A const & a, BOOST_FWD_REF(A1) a1, BOOST_FWD_REF(A2) a2, BOOST_FWD_REF(A3) a3, BOOST_FWD_REF(A4) a4, BOOST_FWD_REF(A5) a5, BOOST_FWD_REF(A6) a6 )
{
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ), a );
@@ -1003,7 +607,15 @@ typename boost::detail::sp_if_not_array< T >::type allocate_shared( A const & a,
void * pv = pd->address();
- ::new( pv ) T( a1, a2, a3, a4, a5, a6 );
+ ::new( pv ) T(
+ boost::forward( a1 ),
+ boost::forward( a2 ),
+ boost::forward( a3 ),
+ boost::forward( a4 ),
+ boost::forward( a5 ),
+ boost::forward( a6 )
+ );
+
pd->set_initialized();
T * pt2 = static_cast< T* >( pv );
@@ -1013,7 +625,7 @@ typename boost::detail::sp_if_not_array< T >::type allocate_shared( A const & a,
}
template< class T, class A1, class A2, class A3, class A4, class A5, class A6, class A7 >
-typename boost::detail::sp_if_not_array< T >::type make_shared( A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5, A6 const & a6, A7 const & a7 )
+typename boost::detail::sp_if_not_array< T >::type make_shared( BOOST_FWD_REF(A1) a1, BOOST_FWD_REF(A2) a2, BOOST_FWD_REF(A3) a3, BOOST_FWD_REF(A4) a4, BOOST_FWD_REF(A5) a5, BOOST_FWD_REF(A6) a6, BOOST_FWD_REF(A7) a7 )
{
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ) );
@@ -1021,7 +633,16 @@ typename boost::detail::sp_if_not_array< T >::type make_shared( A1 const & a1, A
void * pv = pd->address();
- ::new( pv ) T( a1, a2, a3, a4, a5, a6, a7 );
+ ::new( pv ) T(
+ boost::forward( a1 ),
+ boost::forward( a2 ),
+ boost::forward( a3 ),
+ boost::forward( a4 ),
+ boost::forward( a5 ),
+ boost::forward( a6 ),
+ boost::forward( a7 )
+ );
+
pd->set_initialized();
T * pt2 = static_cast< T* >( pv );
@@ -1031,7 +652,7 @@ typename boost::detail::sp_if_not_array< T >::type make_shared( A1 const & a1, A
}
template< class T, class A, class A1, class A2, class A3, class A4, class A5, class A6, class A7 >
-typename boost::detail::sp_if_not_array< T >::type allocate_shared( A const & a, A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5, A6 const & a6, A7 const & a7 )
+typename boost::detail::sp_if_not_array< T >::type allocate_shared( A const & a, BOOST_FWD_REF(A1) a1, BOOST_FWD_REF(A2) a2, BOOST_FWD_REF(A3) a3, BOOST_FWD_REF(A4) a4, BOOST_FWD_REF(A5) a5, BOOST_FWD_REF(A6) a6, BOOST_FWD_REF(A7) a7 )
{
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ), a );
@@ -1039,7 +660,16 @@ typename boost::detail::sp_if_not_array< T >::type allocate_shared( A const & a,
void * pv = pd->address();
- ::new( pv ) T( a1, a2, a3, a4, a5, a6, a7 );
+ ::new( pv ) T(
+ boost::forward( a1 ),
+ boost::forward( a2 ),
+ boost::forward( a3 ),
+ boost::forward( a4 ),
+ boost::forward( a5 ),
+ boost::forward( a6 ),
+ boost::forward( a7 )
+ );
+
pd->set_initialized();
T * pt2 = static_cast< T* >( pv );
@@ -1049,7 +679,7 @@ typename boost::detail::sp_if_not_array< T >::type allocate_shared( A const & a,
}
template< class T, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8 >
-typename boost::detail::sp_if_not_array< T >::type make_shared( A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5, A6 const & a6, A7 const & a7, A8 const & a8 )
+typename boost::detail::sp_if_not_array< T >::type make_shared( BOOST_FWD_REF(A1) a1, BOOST_FWD_REF(A2) a2, BOOST_FWD_REF(A3) a3, BOOST_FWD_REF(A4) a4, BOOST_FWD_REF(A5) a5, BOOST_FWD_REF(A6) a6, BOOST_FWD_REF(A7) a7, BOOST_FWD_REF(A8) a8 )
{
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ) );
@@ -1057,7 +687,17 @@ typename boost::detail::sp_if_not_array< T >::type make_shared( A1 const & a1, A
void * pv = pd->address();
- ::new( pv ) T( a1, a2, a3, a4, a5, a6, a7, a8 );
+ ::new( pv ) T(
+ boost::forward( a1 ),
+ boost::forward( a2 ),
+ boost::forward( a3 ),
+ boost::forward( a4 ),
+ boost::forward( a5 ),
+ boost::forward( a6 ),
+ boost::forward( a7 ),
+ boost::forward( a8 )
+ );
+
pd->set_initialized();
T * pt2 = static_cast< T* >( pv );
@@ -1067,7 +707,7 @@ typename boost::detail::sp_if_not_array< T >::type make_shared( A1 const & a1, A
}
template< class T, class A, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8 >
-typename boost::detail::sp_if_not_array< T >::type allocate_shared( A const & a, A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5, A6 const & a6, A7 const & a7, A8 const & a8 )
+typename boost::detail::sp_if_not_array< T >::type allocate_shared( A const & a, BOOST_FWD_REF(A1) a1, BOOST_FWD_REF(A2) a2, BOOST_FWD_REF(A3) a3, BOOST_FWD_REF(A4) a4, BOOST_FWD_REF(A5) a5, BOOST_FWD_REF(A6) a6, BOOST_FWD_REF(A7) a7, BOOST_FWD_REF(A8) a8 )
{
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ), a );
@@ -1075,7 +715,17 @@ typename boost::detail::sp_if_not_array< T >::type allocate_shared( A const & a,
void * pv = pd->address();
- ::new( pv ) T( a1, a2, a3, a4, a5, a6, a7, a8 );
+ ::new( pv ) T(
+ boost::forward( a1 ),
+ boost::forward( a2 ),
+ boost::forward( a3 ),
+ boost::forward( a4 ),
+ boost::forward( a5 ),
+ boost::forward( a6 ),
+ boost::forward( a7 ),
+ boost::forward( a8 )
+ );
+
pd->set_initialized();
T * pt2 = static_cast< T* >( pv );
@@ -1085,7 +735,7 @@ typename boost::detail::sp_if_not_array< T >::type allocate_shared( A const & a,
}
template< class T, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9 >
-typename boost::detail::sp_if_not_array< T >::type make_shared( A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5, A6 const & a6, A7 const & a7, A8 const & a8, A9 const & a9 )
+typename boost::detail::sp_if_not_array< T >::type make_shared( BOOST_FWD_REF(A1) a1, BOOST_FWD_REF(A2) a2, BOOST_FWD_REF(A3) a3, BOOST_FWD_REF(A4) a4, BOOST_FWD_REF(A5) a5, BOOST_FWD_REF(A6) a6, BOOST_FWD_REF(A7) a7, BOOST_FWD_REF(A8) a8, BOOST_FWD_REF(A9) a9 )
{
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ) );
@@ -1093,7 +743,18 @@ typename boost::detail::sp_if_not_array< T >::type make_shared( A1 const & a1, A
void * pv = pd->address();
- ::new( pv ) T( a1, a2, a3, a4, a5, a6, a7, a8, a9 );
+ ::new( pv ) T(
+ boost::forward( a1 ),
+ boost::forward( a2 ),
+ boost::forward( a3 ),
+ boost::forward( a4 ),
+ boost::forward( a5 ),
+ boost::forward( a6 ),
+ boost::forward( a7 ),
+ boost::forward( a8 ),
+ boost::forward( a9 )
+ );
+
pd->set_initialized();
T * pt2 = static_cast< T* >( pv );
@@ -1103,7 +764,7 @@ typename boost::detail::sp_if_not_array< T >::type make_shared( A1 const & a1, A
}
template< class T, class A, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9 >
-typename boost::detail::sp_if_not_array< T >::type allocate_shared( A const & a, A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5, A6 const & a6, A7 const & a7, A8 const & a8, A9 const & a9 )
+typename boost::detail::sp_if_not_array< T >::type allocate_shared( A const & a, BOOST_FWD_REF(A1) a1, BOOST_FWD_REF(A2) a2, BOOST_FWD_REF(A3) a3, BOOST_FWD_REF(A4) a4, BOOST_FWD_REF(A5) a5, BOOST_FWD_REF(A6) a6, BOOST_FWD_REF(A7) a7, BOOST_FWD_REF(A8) a8, BOOST_FWD_REF(A9) a9 )
{
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ), a );
@@ -1111,7 +772,18 @@ typename boost::detail::sp_if_not_array< T >::type allocate_shared( A const & a,
void * pv = pd->address();
- ::new( pv ) T( a1, a2, a3, a4, a5, a6, a7, a8, a9 );
+ ::new( pv ) T(
+ boost::forward( a1 ),
+ boost::forward( a2 ),
+ boost::forward( a3 ),
+ boost::forward( a4 ),
+ boost::forward( a5 ),
+ boost::forward( a6 ),
+ boost::forward( a7 ),
+ boost::forward( a8 ),
+ boost::forward( a9 )
+ );
+
pd->set_initialized();
T * pt2 = static_cast< T* >( pv );
@@ -1120,8 +792,6 @@ typename boost::detail::sp_if_not_array< T >::type allocate_shared( A const & a,
return boost::shared_ptr< T >( pt, pt2 );
}
-#endif // !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
-
#endif // !defined( BOOST_NO_CXX11_VARIADIC_TEMPLATES ) && !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
#undef BOOST_SP_MSD
diff --git a/pointer_cast.html b/pointer_cast.html
index 2ab0859..bf63043 100644
--- a/pointer_cast.html
+++ b/pointer_cast.html
@@ -2,16 +2,16 @@
pointer_cast
-
+
pointer_cast
+ width="277" align="middle" border="0" />pointer_cast
The pointer cast functions (boost::static_pointer_cast
boost::dynamic_pointer_cast
boost::reinterpret_pointer_cast
boost::const_pointer_cast
)
- provide a way to write generic pointer castings for raw pointers. The functions
- are defined in boost/pointer_cast.hpp.
- There is test/example code in pointer_cast_test.cpp.
+ provide a way to write generic pointer castings for raw pointers, std::shared_ptr
and std::unique_ptr
. The functions
+ are defined in boost/pointer_cast.hpp.
+ There is test/example code in pointer_cast_test.cpp.
Boost smart pointers usually overload those functions to provide a mechanism to
emulate pointers casts. For example, boost::shared_ptr<...>
implements
@@ -20,15 +20,15 @@
template<class T, class U>
shared_ptr<T> static_pointer_cast(shared_ptr<U> const &r);
-
Pointer cast functions from boost/pointer_cast.hpp
+
Pointer cast functions from boost/pointer_cast.hpp
are overloads of boost::static_pointer_cast
, boost::dynamic_pointer_cast
,
boost::reinterpret_pointer_cast
and boost::const_pointer_cast
- for raw pointers. This way when developing pointer type independent classes,
- for example, memory managers or shared memory compatible classes, the same code
- can be used for raw and smart pointers.
-
-
-
+ for raw pointers, std::shared_ptr
and std::unique_ptr
. This way when developing
+ pointer type independent classes, for example, memory managers or shared memory compatible classes, the same
+ code can be used for raw and smart pointers.
+
+
+
namespace boost {
template<class T, class U>
@@ -46,15 +46,93 @@ inline T* const_pointer_cast(U *ptr)
template<class T, class U>
inline T* reinterpret_pointer_cast(U *ptr)
{ return reinterpret_cast<T*>(ptr); }
+
+template<class T, class U>
+inline std::shared_ptr<T> static_pointer_cast(std::shared_ptr<U> const& r);
+
+template<class T, class U>
+inline std::shared_ptr<T> dynamic_pointer_cast(std::shared_ptr<U> const& r);
+
+template<class T, class U>
+inline std::shared_ptr<T> const_pointer_cast(std::shared_ptr<U> const& r);
+
+template<class T, class U>
+inline std::shared_ptr<T> reinterpret_pointer_cast(std::shared_ptr<U> const& r);
+
+template<class T, class U>
+inline std::unique_ptr<T> static_pointer_cast(std::unique_ptr<U>&& r);
+
+template<class T, class U>
+inline std::unique_ptr<T> dynamic_pointer_cast(std::unique_ptr<U>&& r);
+
+template<class T, class U>
+inline std::unique_ptr<T> const_pointer_cast(std::unique_ptr<U>&& r);
+
+template<class T, class U>
+inline std::unique_ptr<T> reinterpret_pointer_cast(std::unique_ptr<U>&& r);
} // namespace boost
-
-
- As you can see from the above synopsis, the pointer cast functions are just
- wrappers around standard C++ cast operators.
-
-
-
+
+
+ As you can see from the above synopsis, the pointer cast functions for raw pointers are just
+ wrappers around standard C++ cast operators.
+
+ The pointer casts for std::shared_ptr
are aliases of the corresponding standard
+ functions with the same names and equivalent to the
+ functions taking boost::shared_ptr
.
+
+ The pointer casts for std::unique_ptr
are documented below.
+
+ static_pointer_cast
+ template<class T, class U>
+ unique_ptr<T> static_pointer_cast(unique_ptr<U>&& r); // never throws
+
+ Requires: The expression static_cast<T*>( (U*)0 )
+ must be well-formed.
+ Returns: unique_ptr<T>( static_cast<typename unique_ptr<T>::element_type*>(r.release()) )
.
+ Throws: nothing.
+ Notes: the seemingly equivalent expression
+ unique_ptr<T>(static_cast<T*>(r.get()))
+ will eventually result in undefined behavior, attempting to delete the same
+ object twice.
+
+ const_pointer_cast
+ template<class T, class U>
+ unique_ptr<T> const_pointer_cast(unique_ptr<U>&& r); // never throws
+
+ Requires: The expression const_cast<T*>( (U*)0 )
+ must be well-formed.
+ Returns: unique_ptr<T>( const_cast<typename unique_ptr<T>::element_type*>(r.release()) )
.
+ Throws: nothing.
+
+ dynamic_pointer_cast
+ template<class T, class U>
+ unique_ptr<T> dynamic_pointer_cast(unique_ptr<U>&& r);
+
+ Requires: The expression dynamic_cast<T*>( (U*)0 )
+ must be well-formed. T
must have a virtual destructor.
+ Returns:
+
+ -
+ When
dynamic_cast<typename unique_ptr<T>::element_type*>(r.get())
returns a nonzero value,
+ unique_ptr<T>(dynamic_cast<typename unique_ptr<T>::element_type*>(r.release()))
;
+ -
+ Otherwise,
unique_ptr<T>()
.
+ Throws: nothing.
+
+ reinterpret_pointer_cast
+ template<class T, class U>
+ unique_ptr<T> reinterpret_pointer_cast(unique_ptr<U>&& r); // never throws
+
+ Requires: The expression reinterpret_cast<T*>( (U*)0 )
+ must be well-formed.
+ Returns: unique_ptr<T>( reinterpret_cast<typename unique_ptr<T>::element_type*>(r.release()) )
.
+ Throws: nothing.
+
+
+
+
+
#include <boost/pointer_cast.hpp>
#include <boost/shared_ptr.hpp>
@@ -79,28 +157,27 @@ void check_if_it_is_derived(const BasePtr &ptr)
int main()
{
- // Create a raw and a shared_ptr
+ // Create a raw and a shared_ptr
base *ptr = new derived;
boost::shared_ptr<base> sptr(new derived);
- // Check that base pointer points actually to derived class
+ // Check that base pointer points actually to derived class
check_if_it_is_derived(ptr);
check_if_it_is_derived(sptr);
- // Ok!
+ // Ok!
delete ptr;
return 0;
-}
-
- The example demonstrates how the generic pointer casts help us create pointer
- independent code.
-
- $Date$
+}
+
+ The example demonstrates how the generic pointer casts help us create pointer
+ independent code.
+
Copyright 2005 Ion Gaztaņaga. Use, modification, and distribution are subject to
- the Boost Software License, Version 1.0. (See accompanying file
- LICENSE_1_0.txt or a copy at <http://www.boost.org/LICENSE_1_0.txt>.)
+ the Boost Software License, Version 1.0. (See accompanying file
+ LICENSE_1_0.txt or a copy at <http://www.boost.org/LICENSE_1_0.txt>.)
diff --git a/shared_ptr.htm b/shared_ptr.htm
index 5c756f8..1cd0bc4 100644
--- a/shared_ptr.htm
+++ b/shared_ptr.htm
@@ -222,7 +222,7 @@ void bad()
shared_ptr<T> dynamic_pointer_cast(shared_ptr<U> const & r); // never throws
template<class T, class U>
- shared_ptr<T> reinterpet_pointer_cast(shared_ptr<U> const & r); // never throws
+ shared_ptr<T> reinterpret_pointer_cast(shared_ptr<U> const & r); // never throws
template<class E, class T, class Y>
std::basic_ostream<E, T> & operator<< (std::basic_ostream<E, T> & os, shared_ptr<Y> const & p);
diff --git a/test/Jamfile.v2 b/test/Jamfile.v2
index d965bfd..7c31ce5 100644
--- a/test/Jamfile.v2
+++ b/test/Jamfile.v2
@@ -29,6 +29,7 @@ import testing ;
[ compile-fail shared_ptr_compare_fail.cpp ]
[ run shared_ptr_alloc2_test.cpp ]
[ run pointer_cast_test.cpp ]
+ [ run cpp11_pointer_cast_test.cpp ]
[ compile pointer_to_other_test.cpp ]
[ run auto_ptr_rv_test.cpp ]
[ run shared_ptr_alias_test.cpp ]
@@ -47,6 +48,7 @@ import testing ;
[ run spinlock_try_test.cpp : : : multi : spinlock_try_test.mt ]
[ run spinlock_pool_test.cpp ]
[ run make_shared_test.cpp ]
+ [ run make_shared_move_emulation_test.cpp ]
[ run make_shared_perfect_forwarding_test.cpp ]
[ run shared_ptr_convertible_test.cpp ]
[ run wp_convertible_test.cpp ]
@@ -185,5 +187,19 @@ import testing ;
[ run sp_hash_test2.cpp ]
[ run sp_hash_test3.cpp ]
+
+ [ run pointer_cast_test2.cpp ]
+
+ [ compile-fail pointer_cast_st_fail.cpp ]
+ [ compile-fail pointer_cast_st_fail2.cpp ]
+ [ compile-fail pointer_cast_st_fail3.cpp ]
+
+ [ compile-fail pointer_cast_co_fail.cpp ]
+ [ compile-fail pointer_cast_co_fail2.cpp ]
+ [ compile-fail pointer_cast_co_fail3.cpp ]
+
+ [ compile-fail pointer_cast_dy_fail.cpp ]
+ [ compile-fail pointer_cast_dy_fail2.cpp ]
+ [ compile-fail pointer_cast_dy_fail3.cpp ]
;
}
diff --git a/test/cpp11_pointer_cast_test.cpp b/test/cpp11_pointer_cast_test.cpp
new file mode 100644
index 0000000..a9361c3
--- /dev/null
+++ b/test/cpp11_pointer_cast_test.cpp
@@ -0,0 +1,224 @@
+//
+// cpp11_pointer_cast_test.cpp - a test for boost/pointer_cast.hpp with std::shared_ptr and std::unique_ptr
+//
+// Copyright (c) 2016 Karolin Varner
+//
+// 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
+
+#include
+#include
+#include
+#include
+
+#include
+#include
+#include
+
+#if defined( BOOST_NO_CXX11_RVALUE_REFERENCES ) \
+ || defined( BOOST_NO_CXX11_HDR_FUNCTIONAL ) \
+ || defined( BOOST_NO_CXX11_HDR_UTILITY ) \
+ || defined( BOOST_NO_CXX11_LAMBDAS ) \
+ || defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
+
+// We expect all the features or none of the features to be
+// available, since we should be on C++11
+int main() { return 0; }
+
+#else
+
+namespace
+{
+
+// Let's create these inheritance relationship:
+//
+// base base2
+// | |
+// derived
+// |
+// derived_derived
+//
+
+class base
+{
+ public:
+ virtual ~base(){}
+ int filler [5];
+};
+
+class base2
+{
+public:
+
+ virtual ~base2(){}
+ int filler [5];
+};
+
+class derived
+ : public base, public base2
+{
+ int filler [5];
+};
+
+class derived_derived
+ : public derived
+{
+ int filler [5];
+};
+
+// And now some simple check functions
+
+#if !defined( BOOST_NO_RTTI )
+
+template
+bool check_dynamic_pointer_cast(const BasePtr &ptr)
+{
+ //Check that dynamic_pointer_cast versus dynamic_cast
+ return
+ //Correct cast with dynamic_pointer_cast
+ boost::get_pointer(boost::dynamic_pointer_cast(ptr)) ==
+ //Correct cast with dynamic_cast
+ dynamic_cast(boost::get_pointer(ptr))
+ &&
+ //Incorrect cast with dynamic_pointer_cast
+ boost::get_pointer(boost::dynamic_pointer_cast(ptr)) ==
+ //Incorrect cast with dynamic_cast
+ dynamic_cast(boost::get_pointer(ptr));
+}
+
+#endif
+
+template
+bool check_static_pointer_cast(const BasePtr &ptr)
+{
+ return
+ //Cast base -> derived -> base2 using static_pointer_cast
+ boost::get_pointer(
+ boost::static_pointer_cast(
+ boost::static_pointer_cast(ptr))) ==
+ //Now the same with static_cast
+ static_cast(static_cast(boost::get_pointer(ptr)));
+}
+
+template
+bool check_const_pointer_cast(const BasePtr &ptr)
+{
+ return
+ //Unconst and const again using const_pointer_cast
+ boost::get_pointer(
+ boost::const_pointer_cast
+ (boost::const_pointer_cast(ptr))) ==
+ //Now the same with const_cast
+ const_cast(const_cast(boost::get_pointer(ptr)));
+}
+
+template
+void check_all_copy_casts(const BasePtr &ptr)
+{
+#if !defined( BOOST_NO_RTTI )
+ BOOST_TEST( check_dynamic_pointer_cast( ptr ) );
+#endif
+ BOOST_TEST( check_static_pointer_cast( ptr ) );
+ BOOST_TEST( check_const_pointer_cast( ptr ) );
+}
+
+
+#if !defined( BOOST_NO_RTTI )
+
+template
+bool check_dynamic_moving_pointer_cast(std::function f)
+{
+ BasePtr smart1 = f(), smart2 = f();
+ derived* expect1 = dynamic_cast(boost::get_pointer(smart1));
+ derived_derived* expect2 = dynamic_cast(boost::get_pointer(smart2));
+ //Check that dynamic_pointer_cast versus dynamic_cast
+ return
+ //Correct cast with dynamic_pointer_cast
+ boost::get_pointer(boost::dynamic_pointer_cast( std::move(smart1) )) == expect1
+ &&
+ //Incorrect cast with dynamic_pointer_cast
+ boost::get_pointer(boost::dynamic_pointer_cast( std::move(smart2) )) == expect2;
+}
+
+#endif
+
+template
+bool check_static_moving_pointer_cast(std::function f)
+{
+ BasePtr smart = f();
+ base2 *expect = static_cast(static_cast(boost::get_pointer(smart)));
+
+ return
+ //Cast base -> derived -> base2 using static_pointer_cast
+ boost::get_pointer(
+ boost::static_pointer_cast(
+ boost::static_pointer_cast( std::move(smart) ))) ==
+ //Now the same with static_cast
+ expect;
+}
+
+template
+bool check_const_moving_pointer_cast(std::function f)
+{
+ BasePtr smart = f();
+ const base *expect = const_cast(const_cast(boost::get_pointer(smart)));
+ return
+ //Unconst and const again using const_pointer_cast
+ boost::get_pointer(
+ boost::const_pointer_cast
+ (boost::const_pointer_cast( std::move(smart) ))) ==
+ //Now the same with const_cast
+ expect;
+}
+
+template
+void check_all_moving_casts(std::function f) {
+#if !defined( BOOST_NO_RTTI )
+ BOOST_TEST( check_dynamic_moving_pointer_cast( f ) );
+#endif
+ BOOST_TEST( check_static_moving_pointer_cast( f ) );
+ BOOST_TEST( check_const_moving_pointer_cast( f ) );
+}
+
+}
+
+int main()
+{
+
+ std::shared_ptr std_shared(new derived);
+ boost::shared_ptr boost_shared(new derived);
+ base *plain = boost_shared.get();
+
+ // plain & boost::shared_ptr moving pointer_cast checks; there
+ // is no specific handleing for those types at the moment; this
+ // test just makes sure they won't break when std::move() is used
+ // in generic code
+
+ check_all_moving_casts>([&boost_shared]() {
+ return boost_shared;
+ });
+
+ check_all_moving_casts([plain]() {
+ return plain;
+ });
+
+ // std::shared_ptr casts
+
+ check_all_copy_casts(std_shared);
+ check_all_moving_casts>([&std_shared]() {
+ return std_shared;
+ });
+
+ // std::unique_ptr casts
+
+ check_all_moving_casts>([]() {
+ return std::unique_ptr(new derived);
+ });
+
+ return boost::report_errors();
+}
+#endif
diff --git a/test/make_shared_move_emulation_test.cpp b/test/make_shared_move_emulation_test.cpp
new file mode 100644
index 0000000..c607e05
--- /dev/null
+++ b/test/make_shared_move_emulation_test.cpp
@@ -0,0 +1,81 @@
+// make_shared_move_emulation_test.cpp - a test of make_shared
+// semi-perfect forwarding of constructor arguments when using a C++03
+// compiler with move emulation.
+// Note the "semi": it means moving temporaries (real r-values) doesn't work.
+//
+// Copyright 2016 Giel van Schijndel
+//
+// 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
+#include
+#include
+#include
+#include
+
+class movearg
+{
+private:
+ BOOST_MOVABLE_BUT_NOT_COPYABLE(movearg)
+public:
+ movearg()
+ {}
+ movearg(BOOST_RV_REF(movearg))
+ {}
+ movearg& operator=(BOOST_RV_REF(movearg))
+ {
+ return *this;
+ }
+};
+
+class ByVal
+{
+public:
+ ByVal(movearg) {}
+};
+
+class ByRef
+{
+public:
+ enum constructor_id
+ {
+ move_constructor,
+ const_ref_constructor
+ };
+
+ ByRef(BOOST_RV_REF(movearg)): constructed_by_(move_constructor)
+ {}
+ ByRef(const movearg &arg): constructed_by_(const_ref_constructor)
+ {}
+
+ constructor_id constructed_by_;
+};
+
+int main()
+{
+ {
+ movearg a;
+ boost::shared_ptr< ByVal > x = boost::make_shared< ByVal >(boost::move(a));
+ }
+ {
+ movearg a;
+ boost::shared_ptr< ByRef > x = boost::make_shared< ByRef >(boost::move(a));
+ BOOST_TEST( x->constructed_by_ == ByRef::move_constructor);
+ }
+#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
+ {
+ boost::shared_ptr< ByVal > x = boost::make_shared< ByVal >(movearg());
+ boost::shared_ptr< ByRef > y = boost::make_shared< ByRef >(movearg());
+ BOOST_TEST( y->constructed_by_ == ByRef::move_constructor);
+ }
+#endif // !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
+ {
+ const movearg ca;
+ boost::shared_ptr< ByRef > x = boost::make_shared< ByRef >(ca);
+ BOOST_TEST( x->constructed_by_ == ByRef::const_ref_constructor);
+ }
+
+ return boost::report_errors();
+}
diff --git a/test/pointer_cast_co_fail.cpp b/test/pointer_cast_co_fail.cpp
new file mode 100644
index 0000000..d8960b2
--- /dev/null
+++ b/test/pointer_cast_co_fail.cpp
@@ -0,0 +1,18 @@
+//
+// A negative test for unique_ptr const_cast
+//
+// Copyright 2016 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
+#include
+
+int main()
+{
+ std::unique_ptr p1( new int );
+ std::unique_ptr p2 = boost::const_pointer_cast( std::move( p1 ) );
+}
diff --git a/test/pointer_cast_co_fail2.cpp b/test/pointer_cast_co_fail2.cpp
new file mode 100644
index 0000000..7fa8e18
--- /dev/null
+++ b/test/pointer_cast_co_fail2.cpp
@@ -0,0 +1,18 @@
+//
+// A negative test for unique_ptr const_cast
+//
+// Copyright 2016 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
+#include
+
+int main()
+{
+ std::unique_ptr p1( new int[ 1 ] );
+ std::unique_ptr p2 = boost::const_pointer_cast( std::move( p1 ) );
+}
diff --git a/test/pointer_cast_co_fail3.cpp b/test/pointer_cast_co_fail3.cpp
new file mode 100644
index 0000000..d8872c8
--- /dev/null
+++ b/test/pointer_cast_co_fail3.cpp
@@ -0,0 +1,29 @@
+//
+// A negative test for unique_ptr const_cast
+//
+// Copyright 2016 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
+#include
+
+struct B
+{
+ virtual ~B()
+ {
+ }
+};
+
+struct D: B
+{
+};
+
+int main()
+{
+ std::unique_ptr p1( new D[ 1 ] );
+ std::unique_ptr p2 = boost::const_pointer_cast( std::move( p1 ) );
+}
diff --git a/test/pointer_cast_dy_fail.cpp b/test/pointer_cast_dy_fail.cpp
new file mode 100644
index 0000000..c6df69d
--- /dev/null
+++ b/test/pointer_cast_dy_fail.cpp
@@ -0,0 +1,25 @@
+//
+// A negative test for unique_ptr dynamic_cast
+//
+// Copyright 2016 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
+#include
+
+struct B
+{
+ virtual ~B()
+ {
+ }
+};
+
+int main()
+{
+ std::unique_ptr p1( new B );
+ std::unique_ptr p2 = boost::dynamic_pointer_cast( std::move( p1 ) );
+}
diff --git a/test/pointer_cast_dy_fail2.cpp b/test/pointer_cast_dy_fail2.cpp
new file mode 100644
index 0000000..223977a
--- /dev/null
+++ b/test/pointer_cast_dy_fail2.cpp
@@ -0,0 +1,25 @@
+//
+// A negative test for unique_ptr dynamic_cast
+//
+// Copyright 2016 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
+#include
+
+struct B
+{
+ virtual ~B()
+ {
+ }
+};
+
+int main()
+{
+ std::unique_ptr p1( new B[ 1 ] );
+ std::unique_ptr p2 = boost::dynamic_pointer_cast( std::move( p1 ) );
+}
diff --git a/test/pointer_cast_dy_fail3.cpp b/test/pointer_cast_dy_fail3.cpp
new file mode 100644
index 0000000..1ac52e7
--- /dev/null
+++ b/test/pointer_cast_dy_fail3.cpp
@@ -0,0 +1,29 @@
+//
+// A negative test for unique_ptr dynamic_cast
+//
+// Copyright 2016 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
+#include
+
+struct B
+{
+ virtual ~B()
+ {
+ }
+};
+
+struct D: B
+{
+};
+
+int main()
+{
+ std::unique_ptr p1( new D[ 1 ] );
+ std::unique_ptr p2 = boost::dynamic_pointer_cast( std::move( p1 ) );
+}
diff --git a/test/pointer_cast_st_fail.cpp b/test/pointer_cast_st_fail.cpp
new file mode 100644
index 0000000..0fcf8c1
--- /dev/null
+++ b/test/pointer_cast_st_fail.cpp
@@ -0,0 +1,18 @@
+//
+// A negative test for unique_ptr static_cast
+//
+// Copyright 2016 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
+#include
+
+int main()
+{
+ std::unique_ptr p1( new int );
+ std::unique_ptr p2 = boost::static_pointer_cast( std::move( p1 ) );
+}
diff --git a/test/pointer_cast_st_fail2.cpp b/test/pointer_cast_st_fail2.cpp
new file mode 100644
index 0000000..3b227b9
--- /dev/null
+++ b/test/pointer_cast_st_fail2.cpp
@@ -0,0 +1,18 @@
+//
+// A negative test for unique_ptr static_cast
+//
+// Copyright 2016 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
+#include
+
+int main()
+{
+ std::unique_ptr p1( new int[ 1 ] );
+ std::unique_ptr p2 = boost::static_pointer_cast( std::move( p1 ) );
+}
diff --git a/test/pointer_cast_st_fail3.cpp b/test/pointer_cast_st_fail3.cpp
new file mode 100644
index 0000000..4ca6a89
--- /dev/null
+++ b/test/pointer_cast_st_fail3.cpp
@@ -0,0 +1,29 @@
+//
+// A negative test for unique_ptr static_cast
+//
+// Copyright 2016 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
+#include
+
+struct B
+{
+ virtual ~B()
+ {
+ }
+};
+
+struct D: B
+{
+};
+
+int main()
+{
+ std::unique_ptr p1( new D[ 1 ] );
+ std::unique_ptr p2 = boost::static_pointer_cast( std::move( p1 ) );
+}
diff --git a/test/pointer_cast_test.cpp b/test/pointer_cast_test.cpp
index bd25dd1..ae036fb 100644
--- a/test/pointer_cast_test.cpp
+++ b/test/pointer_cast_test.cpp
@@ -104,33 +104,25 @@ bool check_const_pointer_cast(const BasePtr &ptr)
const_cast(const_cast(boost::get_pointer(ptr)));
}
+template
+void check_all_casts(const BasePtr &ptr)
+{
+#if !defined( BOOST_NO_RTTI )
+ BOOST_TEST( check_dynamic_pointer_cast( ptr ) );
+#endif
+ BOOST_TEST( check_static_pointer_cast( ptr ) );
+ BOOST_TEST( check_const_pointer_cast( ptr ) );
+}
+
}
int main()
{
- {
- // Try casts with shared_ptr
+ boost::shared_ptr boost_shared(new derived);
+ base *plain = boost_shared.get();
- boost::shared_ptr ptr(new derived);
-
-#if !defined( BOOST_NO_RTTI )
- BOOST_TEST( check_dynamic_pointer_cast( ptr ) );
-#endif
- BOOST_TEST( check_static_pointer_cast( ptr ) );
- BOOST_TEST( check_const_pointer_cast( ptr ) );
- }
-
- {
- // Try casts with raw pointer
-
- boost::scoped_ptr ptr(new derived);
-
-#if !defined( BOOST_NO_RTTI )
- BOOST_TEST( check_dynamic_pointer_cast( ptr.get() ) );
-#endif
- BOOST_TEST( check_static_pointer_cast( ptr.get() ) );
- BOOST_TEST( check_const_pointer_cast( ptr.get() ) );
- }
+ check_all_casts(boost_shared);
+ check_all_casts(plain);
return boost::report_errors();
}
diff --git a/test/pointer_cast_test2.cpp b/test/pointer_cast_test2.cpp
new file mode 100644
index 0000000..eb28a5d
--- /dev/null
+++ b/test/pointer_cast_test2.cpp
@@ -0,0 +1,247 @@
+//
+// pointer_cast_test2.cpp - a test for unique_ptr casts
+//
+// Copyright 2016 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
+
+#if defined( BOOST_NO_CXX11_SMART_PTR )
+
+int main()
+{
+ return 0;
+}
+
+#else
+
+#include
+#include
+#include
+
+struct B1
+{
+};
+
+struct D1: B1
+{
+ ~D1()
+ {
+ }
+};
+
+static void test_static_cast()
+{
+ {
+ std::unique_ptr p1( new int );
+ int * q1 = p1.get();
+
+ std::unique_ptr p2 = boost::static_pointer_cast( std::move( p1 ) );
+
+ BOOST_TEST( p1.get() == 0 );
+ BOOST_TEST_EQ( p2.get(), q1 );
+ }
+
+ {
+ std::unique_ptr p1( new int );
+ int * q1 = p1.get();
+
+ std::unique_ptr p2 = boost::static_pointer_cast( std::move( p1 ) );
+
+ BOOST_TEST( p1.get() == 0 );
+ BOOST_TEST_EQ( p2.get(), q1 );
+ }
+
+ {
+ std::unique_ptr p1( new int[ 1 ] );
+ int * q1 = p1.get();
+
+ std::unique_ptr p2 = boost::static_pointer_cast( std::move( p1 ) );
+
+ BOOST_TEST( p1.get() == 0 );
+ BOOST_TEST_EQ( p2.get(), q1 );
+ }
+
+ {
+ std::unique_ptr p1( new int[ 1 ] );
+ int * q1 = p1.get();
+
+ std::unique_ptr p2 = boost::static_pointer_cast( std::move( p1 ) );
+
+ BOOST_TEST( p1.get() == 0 );
+ BOOST_TEST_EQ( p2.get(), q1 );
+ }
+
+ {
+ std::unique_ptr p1( new D1 );
+ D1 * q1 = p1.get();
+
+ std::unique_ptr p2 = boost::static_pointer_cast( std::move( p1 ) );
+
+ BOOST_TEST( p1.get() == 0 );
+ BOOST_TEST_EQ( p2.get(), q1 );
+
+ std::unique_ptr p3 = boost::static_pointer_cast( std::move( p2 ) );
+
+ BOOST_TEST( p2.get() == 0 );
+ BOOST_TEST_EQ( p3.get(), q1 );
+ }
+}
+
+static void test_const_cast()
+{
+ {
+ std::unique_ptr p1( new int );
+ int * q1 = p1.get();
+
+ std::unique_ptr p2 = boost::const_pointer_cast( std::move( p1 ) );
+
+ BOOST_TEST( p1.get() == 0 );
+ BOOST_TEST_EQ( p2.get(), q1 );
+
+ std::unique_ptr p3 = boost::const_pointer_cast( std::move( p2 ) );
+
+ BOOST_TEST( p2.get() == 0 );
+ BOOST_TEST_EQ( p3.get(), q1 );
+ }
+
+ {
+ std::unique_ptr p1( new int[ 1 ] );
+ int * q1 = p1.get();
+
+ std::unique_ptr p2 = boost::const_pointer_cast( std::move( p1 ) );
+
+ BOOST_TEST( p1.get() == 0 );
+ BOOST_TEST_EQ( p2.get(), q1 );
+
+ std::unique_ptr p3 = boost::const_pointer_cast( std::move( p2 ) );
+
+ BOOST_TEST( p2.get() == 0 );
+ BOOST_TEST_EQ( p3.get(), q1 );
+ }
+}
+
+struct B2
+{
+ virtual ~B2()
+ {
+ }
+};
+
+struct C2
+{
+ virtual ~C2()
+ {
+ }
+};
+
+struct D2: B2, C2
+{
+};
+
+static void test_dynamic_cast()
+{
+ {
+ std::unique_ptr p1( new D2 );
+ D2 * q1 = p1.get();
+
+ std::unique_ptr p2 = boost::dynamic_pointer_cast( std::move( p1 ) );
+
+ BOOST_TEST( p1.get() == 0 );
+ BOOST_TEST_EQ( p2.get(), q1 );
+ }
+
+ {
+ std::unique_ptr p1( new D2 );
+ B2 * q1 = p1.get();
+
+ std::unique_ptr p2 = boost::dynamic_pointer_cast( std::move( p1 ) );
+
+ BOOST_TEST( p1.get() == 0 );
+ BOOST_TEST_EQ( p2.get(), q1 );
+ }
+
+ {
+ std::unique_ptr p1( new B2 );
+ B2 * q1 = p1.get();
+
+ std::unique_ptr p2 = boost::dynamic_pointer_cast( std::move( p1 ) );
+
+ BOOST_TEST( p2.get() == 0 );
+ BOOST_TEST_EQ( p1.get(), q1 );
+ }
+
+ {
+ D2 * q1 = new D2;
+ std::unique_ptr p1( q1 );
+
+ std::unique_ptr p2 = boost::dynamic_pointer_cast( std::move( p1 ) );
+
+ BOOST_TEST( p1.get() == 0 );
+ BOOST_TEST_EQ( p2.get(), q1 );
+ }
+}
+
+static void test_reinterpret_cast()
+{
+ {
+ std::unique_ptr p1( new int );
+ void * q1 = p1.get();
+
+ std::unique_ptr p2 = boost::reinterpret_pointer_cast( std::move( p1 ) );
+
+ BOOST_TEST( p1.get() == 0 );
+ BOOST_TEST_EQ( p2.get(), q1 );
+
+ p1 = boost::reinterpret_pointer_cast( std::move( p2 ) );
+
+ BOOST_TEST( p2.get() == 0 );
+ BOOST_TEST_EQ( p1.get(), q1 );
+ }
+
+ {
+ std::unique_ptr p1( new int );
+ void * q1 = p1.get();
+
+ std::unique_ptr p2 = boost::reinterpret_pointer_cast( std::move( p1 ) );
+
+ BOOST_TEST( p1.get() == 0 );
+ BOOST_TEST_EQ( p2.get(), q1 );
+
+ p1 = boost::reinterpret_pointer_cast( std::move( p2 ) );
+
+ BOOST_TEST( p2.get() == 0 );
+ BOOST_TEST_EQ( p1.get(), q1 );
+ }
+
+ {
+ std::unique_ptr p1( new int[ 1 ] );
+ void * q1 = p1.get();
+
+ std::unique_ptr p2 = boost::reinterpret_pointer_cast( std::move( p1 ) );
+
+ BOOST_TEST( p1.get() == 0 );
+ BOOST_TEST_EQ( p2.get(), q1 );
+
+ p1 = boost::reinterpret_pointer_cast( std::move( p2 ) );
+
+ BOOST_TEST( p2.get() == 0 );
+ BOOST_TEST_EQ( p1.get(), q1 );
+ }
+}
+
+int main()
+{
+ test_static_cast();
+ test_const_cast();
+ test_dynamic_cast();
+ test_reinterpret_cast();
+
+ return boost::report_errors();
+}
+
+#endif