From a7fbb0a8415acae2a8507d697653930e31f19dd6 Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Sun, 6 Nov 2016 15:35:46 +0200 Subject: [PATCH 1/6] Do not use components removed in C++17 (auto_ptr, binary_function) --- include/boost/smart_ptr/owner_less.hpp | 45 +++++++------------------- test/auto_ptr_rv_test.cpp | 12 +++++++ test/esft_regtest.cpp | 5 +++ test/pointer_to_other_test.cpp | 7 ++++ test/shared_from_raw_test2.cpp | 5 +++ test/shared_ptr_test.cpp | 8 +++++ 6 files changed, 48 insertions(+), 34 deletions(-) diff --git a/include/boost/smart_ptr/owner_less.hpp b/include/boost/smart_ptr/owner_less.hpp index 6899325..75d182c 100644 --- a/include/boost/smart_ptr/owner_less.hpp +++ b/include/boost/smart_ptr/owner_less.hpp @@ -5,6 +5,7 @@ // owner_less.hpp // // Copyright (c) 2008 Frank Mori Hess +// Copyright (c) 2016 Peter Dimov // // Distributed under the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at @@ -13,44 +14,20 @@ // See http://www.boost.org/libs/smart_ptr/smart_ptr.htm for documentation. // -#include - namespace boost { - template class shared_ptr; - template class weak_ptr; - namespace detail - { - template - struct generic_owner_less : public std::binary_function +template struct owner_less +{ + typedef bool result_type; + typedef T first_argument_type; + typedef T second_argument_type; + + template bool operator()( U const & u, V const & v ) const { - bool operator()(const T &lhs, const T &rhs) const - { - return lhs.owner_before(rhs); - } - bool operator()(const T &lhs, const U &rhs) const - { - return lhs.owner_before(rhs); - } - bool operator()(const U &lhs, const T &rhs) const - { - return lhs.owner_before(rhs); - } - }; - } // namespace detail - - template struct owner_less; - - template - struct owner_less >: - public detail::generic_owner_less, weak_ptr > - {}; - - template - struct owner_less >: - public detail::generic_owner_less, shared_ptr > - {}; + return u.owner_before( v ); + } +}; } // namespace boost diff --git a/test/auto_ptr_rv_test.cpp b/test/auto_ptr_rv_test.cpp index d13b6ab..5123439 100644 --- a/test/auto_ptr_rv_test.cpp +++ b/test/auto_ptr_rv_test.cpp @@ -1,3 +1,5 @@ +#include + // // auto_ptr_rv_test.cpp // @@ -8,6 +10,14 @@ // http://www.boost.org/LICENSE_1_0.txt // +#if defined( BOOST_NO_AUTO_PTR ) + +int main() +{ +} + +#else + #include #include #include @@ -109,3 +119,5 @@ int main() return boost::report_errors(); } + +#endif // #if defined( BOOST_NO_AUTO_PTR ) diff --git a/test/esft_regtest.cpp b/test/esft_regtest.cpp index cc180a2..baa5ef2 100644 --- a/test/esft_regtest.cpp +++ b/test/esft_regtest.cpp @@ -15,6 +15,7 @@ #include #include #include +#include #include #include @@ -77,11 +78,15 @@ void test() BOOST_TEST( X::instances == 0 ); +#if !defined( BOOST_NO_AUTO_PTR ) + { std::auto_ptr px( new X( 0 ) ); BOOST_TEST( X::instances == 1 ); } +#endif + BOOST_TEST( X::instances == 0 ); { diff --git a/test/pointer_to_other_test.cpp b/test/pointer_to_other_test.cpp index c2ee187..f1c6091 100644 --- a/test/pointer_to_other_test.cpp +++ b/test/pointer_to_other_test.cpp @@ -16,8 +16,11 @@ #include #include +#include + #include + template void assert_same_type( T** pt = 0, U** pu = 0 ) { pt = pu; @@ -58,12 +61,16 @@ int main() assert_same_type< boost::pointer_to_other< boost::intrusive_ptr, void >::type, boost::intrusive_ptr >(); assert_same_type< boost::pointer_to_other< boost::intrusive_ptr, Y >::type, boost::intrusive_ptr >(); +#if !defined( BOOST_NO_AUTO_PTR ) + // auto_ptr assert_same_type< boost::pointer_to_other< std::auto_ptr, Y >::type, std::auto_ptr >(); assert_same_type< boost::pointer_to_other< std::auto_ptr, void >::type, std::auto_ptr >(); assert_same_type< boost::pointer_to_other< std::auto_ptr, Y >::type, std::auto_ptr >(); +#endif + // raw pointer assert_same_type< boost::pointer_to_other< X *, Y >::type, Y * >(); diff --git a/test/shared_from_raw_test2.cpp b/test/shared_from_raw_test2.cpp index 8148a6b..2a33637 100644 --- a/test/shared_from_raw_test2.cpp +++ b/test/shared_from_raw_test2.cpp @@ -13,6 +13,7 @@ #include #include #include +#include #include #include @@ -75,11 +76,15 @@ void test() BOOST_TEST( X::instances == 0 ); +#if !defined( BOOST_NO_AUTO_PTR ) + { std::auto_ptr px( new X( 0 ) ); BOOST_TEST( X::instances == 1 ); } +#endif + BOOST_TEST( X::instances == 0 ); { diff --git a/test/shared_ptr_test.cpp b/test/shared_ptr_test.cpp index 60ed906..fdfb215 100644 --- a/test/shared_ptr_test.cpp +++ b/test/shared_ptr_test.cpp @@ -850,6 +850,8 @@ void weak_ptr_constructor() void auto_ptr_constructor() { +#if !defined( BOOST_NO_AUTO_PTR ) + { std::auto_ptr p; boost::shared_ptr pi(p); @@ -1136,6 +1138,8 @@ void auto_ptr_constructor() BOOST_TEST(X::instances == 0); BOOST_TEST(Y::instances == 0); + +#endif // #if !defined( BOOST_NO_AUTO_PTR ) } void test() @@ -1420,6 +1424,8 @@ void conversion_assignment() void auto_ptr_assignment() { +#if !defined( BOOST_NO_AUTO_PTR ) + { boost::shared_ptr p1; @@ -1516,6 +1522,8 @@ void auto_ptr_assignment() BOOST_TEST(X::instances == 0); BOOST_TEST(Y::instances == 0); } + +#endif // #if !defined( BOOST_NO_AUTO_PTR ) } void test() From 3e61a63f60fe14f867eb4579c369e53d875ec0f9 Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Tue, 8 Nov 2016 18:42:51 +0200 Subject: [PATCH 2/6] Use throw() in place of noexcept on msvc-11.0,12.0 for the standard nothrow traits --- .../boost/smart_ptr/detail/sp_noexcept.hpp | 30 ++++++ .../smart_ptr/enable_shared_from_this.hpp | 9 +- include/boost/smart_ptr/intrusive_ptr.hpp | 7 +- include/boost/smart_ptr/scoped_array.hpp | 3 +- include/boost/smart_ptr/scoped_ptr.hpp | 3 +- include/boost/smart_ptr/shared_array.hpp | 13 +-- include/boost/smart_ptr/shared_ptr.hpp | 13 +-- include/boost/smart_ptr/weak_ptr.hpp | 11 ++- test/Jamfile.v2 | 2 + test/sp_nothrow_test.cpp | 96 +++++++++++++++++++ 10 files changed, 161 insertions(+), 26 deletions(-) create mode 100644 include/boost/smart_ptr/detail/sp_noexcept.hpp create mode 100644 test/sp_nothrow_test.cpp diff --git a/include/boost/smart_ptr/detail/sp_noexcept.hpp b/include/boost/smart_ptr/detail/sp_noexcept.hpp new file mode 100644 index 0000000..6818dce --- /dev/null +++ b/include/boost/smart_ptr/detail/sp_noexcept.hpp @@ -0,0 +1,30 @@ +#ifndef BOOST_SMART_PTR_DETAIL_SP_NOEXCEPT_HPP_INCLUDED +#define BOOST_SMART_PTR_DETAIL_SP_NOEXCEPT_HPP_INCLUDED + +// MS compatible compilers support #pragma once + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +// detail/sp_noexcept.hpp +// +// 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_MSVC ) && BOOST_MSVC >= 1700 && BOOST_MSVC < 1900 + +#define BOOST_SP_NOEXCEPT BOOST_NOEXCEPT_OR_NOTHROW + +#else + +#define BOOST_SP_NOEXCEPT BOOST_NOEXCEPT + +#endif + +#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_NOEXCEPT_HPP_INCLUDED diff --git a/include/boost/smart_ptr/enable_shared_from_this.hpp b/include/boost/smart_ptr/enable_shared_from_this.hpp index 4e3f243..642403a 100644 --- a/include/boost/smart_ptr/enable_shared_from_this.hpp +++ b/include/boost/smart_ptr/enable_shared_from_this.hpp @@ -15,6 +15,7 @@ #include #include +#include #include #include @@ -25,20 +26,20 @@ template class enable_shared_from_this { protected: - enable_shared_from_this() BOOST_NOEXCEPT + enable_shared_from_this() BOOST_SP_NOEXCEPT { } - enable_shared_from_this(enable_shared_from_this const &) BOOST_NOEXCEPT + enable_shared_from_this(enable_shared_from_this const &) BOOST_SP_NOEXCEPT { } - enable_shared_from_this & operator=(enable_shared_from_this const &) BOOST_NOEXCEPT + enable_shared_from_this & operator=(enable_shared_from_this const &) BOOST_SP_NOEXCEPT { return *this; } - ~enable_shared_from_this() BOOST_NOEXCEPT // ~weak_ptr newer throws, so this call also must not throw + ~enable_shared_from_this() BOOST_SP_NOEXCEPT // ~weak_ptr newer throws, so this call also must not throw { } diff --git a/include/boost/smart_ptr/intrusive_ptr.hpp b/include/boost/smart_ptr/intrusive_ptr.hpp index 1e93397..0e46212 100644 --- a/include/boost/smart_ptr/intrusive_ptr.hpp +++ b/include/boost/smart_ptr/intrusive_ptr.hpp @@ -19,6 +19,7 @@ #include #include #include +#include #include // for std::less @@ -59,7 +60,7 @@ public: typedef T element_type; - BOOST_CONSTEXPR intrusive_ptr() BOOST_NOEXCEPT : px( 0 ) + BOOST_CONSTEXPR intrusive_ptr() BOOST_SP_NOEXCEPT : px( 0 ) { } @@ -111,12 +112,12 @@ public: #if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES ) - intrusive_ptr(intrusive_ptr && rhs) BOOST_NOEXCEPT : px( rhs.px ) + intrusive_ptr(intrusive_ptr && rhs) BOOST_SP_NOEXCEPT : px( rhs.px ) { rhs.px = 0; } - intrusive_ptr & operator=(intrusive_ptr && rhs) BOOST_NOEXCEPT + intrusive_ptr & operator=(intrusive_ptr && rhs) BOOST_SP_NOEXCEPT { this_type( static_cast< intrusive_ptr && >( rhs ) ).swap(*this); return *this; diff --git a/include/boost/smart_ptr/scoped_array.hpp b/include/boost/smart_ptr/scoped_array.hpp index e395e28..f847c09 100644 --- a/include/boost/smart_ptr/scoped_array.hpp +++ b/include/boost/smart_ptr/scoped_array.hpp @@ -15,6 +15,7 @@ #include #include #include +#include #include @@ -54,7 +55,7 @@ public: typedef T element_type; - explicit scoped_array( T * p = 0 ) BOOST_NOEXCEPT : px( p ) + explicit scoped_array( T * p = 0 ) BOOST_SP_NOEXCEPT : px( p ) { #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) boost::sp_array_constructor_hook( px ); diff --git a/include/boost/smart_ptr/scoped_ptr.hpp b/include/boost/smart_ptr/scoped_ptr.hpp index d5d8720..8fd8a18 100644 --- a/include/boost/smart_ptr/scoped_ptr.hpp +++ b/include/boost/smart_ptr/scoped_ptr.hpp @@ -16,6 +16,7 @@ #include #include #include +#include #include #ifndef BOOST_NO_AUTO_PTR @@ -62,7 +63,7 @@ public: typedef T element_type; - explicit scoped_ptr( T * p = 0 ): px( p ) // never throws + explicit scoped_ptr( T * p = 0 ) BOOST_SP_NOEXCEPT : px( p ) // never throws { #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) boost::sp_scalar_constructor_hook( px ); diff --git a/include/boost/smart_ptr/shared_array.hpp b/include/boost/smart_ptr/shared_array.hpp index fd58071..2e5cb13 100644 --- a/include/boost/smart_ptr/shared_array.hpp +++ b/include/boost/smart_ptr/shared_array.hpp @@ -24,6 +24,7 @@ #include #include #include +#include #include #include // for std::ptrdiff_t @@ -53,13 +54,13 @@ public: typedef T element_type; - shared_array() BOOST_NOEXCEPT : px( 0 ), pn() + shared_array() BOOST_SP_NOEXCEPT : px( 0 ), pn() { } #if !defined( BOOST_NO_CXX11_NULLPTR ) - shared_array( boost::detail::sp_nullptr_t ) BOOST_NOEXCEPT : px( 0 ), pn() + shared_array( boost::detail::sp_nullptr_t ) BOOST_SP_NOEXCEPT : px( 0 ), pn() { } @@ -95,11 +96,11 @@ public: // ... except in C++0x, move disables the implicit copy - shared_array( shared_array const & r ) BOOST_NOEXCEPT : px( r.px ), pn( r.pn ) + shared_array( shared_array const & r ) BOOST_SP_NOEXCEPT : px( r.px ), pn( r.pn ) { } - shared_array( shared_array && r ) BOOST_NOEXCEPT : px( r.px ), pn() + shared_array( shared_array && r ) BOOST_SP_NOEXCEPT : px( r.px ), pn() { pn.swap( r.pn ); r.px = 0; @@ -133,7 +134,7 @@ public: // assignment - shared_array & operator=( shared_array const & r ) BOOST_NOEXCEPT + shared_array & operator=( shared_array const & r ) BOOST_SP_NOEXCEPT { this_type( r ).swap( *this ); return *this; @@ -152,7 +153,7 @@ public: #if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES ) - shared_array & operator=( shared_array && r ) BOOST_NOEXCEPT + shared_array & operator=( shared_array && r ) BOOST_SP_NOEXCEPT { this_type( static_cast< shared_array && >( r ) ).swap( *this ); return *this; diff --git a/include/boost/smart_ptr/shared_ptr.hpp b/include/boost/smart_ptr/shared_ptr.hpp index 77f68be..deb3fec 100644 --- a/include/boost/smart_ptr/shared_ptr.hpp +++ b/include/boost/smart_ptr/shared_ptr.hpp @@ -30,6 +30,7 @@ #include #include #include +#include #if !defined(BOOST_SP_NO_ATOMIC_ACCESS) #include @@ -344,13 +345,13 @@ public: typedef typename boost::detail::sp_element< T >::type element_type; - shared_ptr() BOOST_NOEXCEPT : px( 0 ), pn() // never throws in 1.30+ + shared_ptr() BOOST_SP_NOEXCEPT : px( 0 ), pn() // never throws in 1.30+ { } #if !defined( BOOST_NO_CXX11_NULLPTR ) - shared_ptr( boost::detail::sp_nullptr_t ) BOOST_NOEXCEPT : px( 0 ), pn() // never throws + shared_ptr( boost::detail::sp_nullptr_t ) BOOST_SP_NOEXCEPT : px( 0 ), pn() // never throws { } @@ -402,7 +403,7 @@ public: // ... except in C++0x, move disables the implicit copy - shared_ptr( shared_ptr const & r ) BOOST_NOEXCEPT : px( r.px ), pn( r.pn ) + shared_ptr( shared_ptr const & r ) BOOST_SP_NOEXCEPT : px( r.px ), pn( r.pn ) { } @@ -521,7 +522,7 @@ public: // assignment - shared_ptr & operator=( shared_ptr const & r ) BOOST_NOEXCEPT + shared_ptr & operator=( shared_ptr const & r ) BOOST_SP_NOEXCEPT { this_type(r).swap(*this); return *this; @@ -605,7 +606,7 @@ public: #if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES ) - shared_ptr( shared_ptr && r ) BOOST_NOEXCEPT : px( r.px ), pn() + shared_ptr( shared_ptr && r ) BOOST_SP_NOEXCEPT : px( r.px ), pn() { pn.swap( r.pn ); r.px = 0; @@ -629,7 +630,7 @@ public: r.px = 0; } - shared_ptr & operator=( shared_ptr && r ) BOOST_NOEXCEPT + shared_ptr & operator=( shared_ptr && r ) BOOST_SP_NOEXCEPT { this_type( static_cast< shared_ptr && >( r ) ).swap( *this ); return *this; diff --git a/include/boost/smart_ptr/weak_ptr.hpp b/include/boost/smart_ptr/weak_ptr.hpp index e3e9ad9..f3411f7 100644 --- a/include/boost/smart_ptr/weak_ptr.hpp +++ b/include/boost/smart_ptr/weak_ptr.hpp @@ -16,6 +16,7 @@ #include // boost.TR1 include order fix #include #include +#include namespace boost { @@ -31,7 +32,7 @@ public: typedef typename boost::detail::sp_element< T >::type element_type; - weak_ptr() BOOST_NOEXCEPT : px(0), pn() // never throws in 1.30+ + weak_ptr() BOOST_SP_NOEXCEPT : px(0), pn() // never throws in 1.30+ { } @@ -41,11 +42,11 @@ public: // ... except in C++0x, move disables the implicit copy - weak_ptr( weak_ptr const & r ) BOOST_NOEXCEPT : px( r.px ), pn( r.pn ) + weak_ptr( weak_ptr const & r ) BOOST_SP_NOEXCEPT : px( r.px ), pn( r.pn ) { } - weak_ptr & operator=( weak_ptr const & r ) BOOST_NOEXCEPT + weak_ptr & operator=( weak_ptr const & r ) BOOST_SP_NOEXCEPT { px = r.px; pn = r.pn; @@ -106,13 +107,13 @@ public: // for better efficiency in the T == Y case weak_ptr( weak_ptr && r ) - BOOST_NOEXCEPT : px( r.px ), pn( static_cast< boost::detail::weak_count && >( r.pn ) ) + BOOST_SP_NOEXCEPT : px( r.px ), pn( static_cast< boost::detail::weak_count && >( r.pn ) ) { r.px = 0; } // for better efficiency in the T == Y case - weak_ptr & operator=( weak_ptr && r ) BOOST_NOEXCEPT + weak_ptr & operator=( weak_ptr && r ) BOOST_SP_NOEXCEPT { this_type( static_cast< weak_ptr && >( r ) ).swap( *this ); return *this; diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index 7c31ce5..a9546db 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -201,5 +201,7 @@ import testing ; [ compile-fail pointer_cast_dy_fail.cpp ] [ compile-fail pointer_cast_dy_fail2.cpp ] [ compile-fail pointer_cast_dy_fail3.cpp ] + + [ run sp_nothrow_test.cpp ] ; } diff --git a/test/sp_nothrow_test.cpp b/test/sp_nothrow_test.cpp new file mode 100644 index 0000000..156e72e --- /dev/null +++ b/test/sp_nothrow_test.cpp @@ -0,0 +1,96 @@ +// +// sp_nothrow_test.cpp +// +// 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_HDR_TYPE_TRAITS ) + +int main() +{ +} + +#else + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +template void test_copy() +{ + BOOST_TEST_TRAIT_TRUE(( std::is_nothrow_copy_constructible )); + BOOST_TEST_TRAIT_TRUE(( std::is_nothrow_copy_assignable )); +} + +template void test_move() +{ + BOOST_TEST_TRAIT_TRUE(( std::is_nothrow_move_constructible )); + BOOST_TEST_TRAIT_TRUE(( std::is_nothrow_move_assignable )); +} + +template void test_default() +{ + BOOST_TEST_TRAIT_TRUE(( std::is_nothrow_default_constructible )); +} + +template void test_destroy() +{ + BOOST_TEST_TRAIT_TRUE(( std::is_nothrow_destructible )); +} + +template void test_cmd() +{ + test_copy(); + test_move(); + test_default(); +} + +struct X +{ +}; + +struct Y: public boost::enable_shared_from_this +{ +}; + +int main() +{ + test_cmd< boost::shared_ptr >(); + test_cmd< boost::shared_array >(); + test_cmd< boost::weak_ptr >(); + + test_copy< Y >(); + test_default< Y >(); + test_destroy< Y >(); + + // test_move< Y >(); + BOOST_TEST_TRAIT_TRUE(( std::is_nothrow_move_constructible )); + +#if !( defined( BOOST_MSVC ) && BOOST_MSVC == 1700 ) + + BOOST_TEST_TRAIT_TRUE(( std::is_nothrow_move_assignable )); + +#endif + + test_default< boost::scoped_ptr >(); + test_default< boost::scoped_array >(); + + test_move< boost::intrusive_ptr >(); + test_default< boost::intrusive_ptr >(); + + return boost::report_errors(); +} + +#endif // #if defined( BOOST_NO_CXX11_HDR_TYPE_TRAITS ) From 61075bb9df4ebeb13013882e1e5b0cf429beedfc Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Thu, 10 Nov 2016 15:04:21 +0200 Subject: [PATCH 3/6] Move extra files to extras/ as the src/ and test/ directories are scanned for dependencies --- {src => extras/src}/sp_collector.cpp | 0 {src => extras/src}/sp_debug_hooks.cpp | 0 {test => extras/test}/shared_ptr_mt_test.cpp | 0 {test => extras/test}/shared_ptr_timing_test.cpp | 0 {test => extras/test}/sp_atomic_mt2_test.cpp | 0 {test => extras/test}/sp_atomic_mt_test.cpp | 0 {test => extras/test}/weak_ptr_mt_test.cpp | 0 {test => extras/test}/weak_ptr_timing_test.cpp | 0 8 files changed, 0 insertions(+), 0 deletions(-) rename {src => extras/src}/sp_collector.cpp (100%) rename {src => extras/src}/sp_debug_hooks.cpp (100%) rename {test => extras/test}/shared_ptr_mt_test.cpp (100%) rename {test => extras/test}/shared_ptr_timing_test.cpp (100%) rename {test => extras/test}/sp_atomic_mt2_test.cpp (100%) rename {test => extras/test}/sp_atomic_mt_test.cpp (100%) rename {test => extras/test}/weak_ptr_mt_test.cpp (100%) rename {test => extras/test}/weak_ptr_timing_test.cpp (100%) diff --git a/src/sp_collector.cpp b/extras/src/sp_collector.cpp similarity index 100% rename from src/sp_collector.cpp rename to extras/src/sp_collector.cpp diff --git a/src/sp_debug_hooks.cpp b/extras/src/sp_debug_hooks.cpp similarity index 100% rename from src/sp_debug_hooks.cpp rename to extras/src/sp_debug_hooks.cpp diff --git a/test/shared_ptr_mt_test.cpp b/extras/test/shared_ptr_mt_test.cpp similarity index 100% rename from test/shared_ptr_mt_test.cpp rename to extras/test/shared_ptr_mt_test.cpp diff --git a/test/shared_ptr_timing_test.cpp b/extras/test/shared_ptr_timing_test.cpp similarity index 100% rename from test/shared_ptr_timing_test.cpp rename to extras/test/shared_ptr_timing_test.cpp diff --git a/test/sp_atomic_mt2_test.cpp b/extras/test/sp_atomic_mt2_test.cpp similarity index 100% rename from test/sp_atomic_mt2_test.cpp rename to extras/test/sp_atomic_mt2_test.cpp diff --git a/test/sp_atomic_mt_test.cpp b/extras/test/sp_atomic_mt_test.cpp similarity index 100% rename from test/sp_atomic_mt_test.cpp rename to extras/test/sp_atomic_mt_test.cpp diff --git a/test/weak_ptr_mt_test.cpp b/extras/test/weak_ptr_mt_test.cpp similarity index 100% rename from test/weak_ptr_mt_test.cpp rename to extras/test/weak_ptr_mt_test.cpp diff --git a/test/weak_ptr_timing_test.cpp b/extras/test/weak_ptr_timing_test.cpp similarity index 100% rename from test/weak_ptr_timing_test.cpp rename to extras/test/weak_ptr_timing_test.cpp From 3e2ac10e94c7bc8d54915072676226371ef2b0a7 Mon Sep 17 00:00:00 2001 From: Chris Glover Date: Sun, 11 Dec 2016 15:38:34 -0500 Subject: [PATCH 4/6] Add rvalue versions of static_pointer_cast, const_pointer_cast, dynamic_pointer_cast, reinterpret_pointer_cast. Aligns with proposed addition to std:: here: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0390r0.htm --- include/boost/smart_ptr/shared_ptr.hpp | 44 +++++++++++ test/Jamfile.v2 | 1 + test/shared_ptr_rv_pointer_cast_test.cpp | 96 ++++++++++++++++++++++++ 3 files changed, 141 insertions(+) create mode 100644 test/shared_ptr_rv_pointer_cast_test.cpp diff --git a/include/boost/smart_ptr/shared_ptr.hpp b/include/boost/smart_ptr/shared_ptr.hpp index deb3fec..e33707b 100644 --- a/include/boost/smart_ptr/shared_ptr.hpp +++ b/include/boost/smart_ptr/shared_ptr.hpp @@ -883,6 +883,50 @@ template shared_ptr reinterpret_pointer_cast( shared_ptr return shared_ptr( r, p ); } +#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES ) + +template shared_ptr static_pointer_cast( shared_ptr && r ) BOOST_NOEXCEPT +{ + (void) static_cast< T* >( static_cast< U* >( 0 ) ); + + typedef typename shared_ptr::element_type E; + + E * p = static_cast< E* >( r.get() ); + return shared_ptr( std::move(r), p ); +} + +template shared_ptr const_pointer_cast( shared_ptr && r ) BOOST_NOEXCEPT +{ + (void) const_cast< T* >( static_cast< U* >( 0 ) ); + + typedef typename shared_ptr::element_type E; + + E * p = const_cast< E* >( r.get() ); + return shared_ptr( std::move(r), p ); +} + +template shared_ptr dynamic_pointer_cast( shared_ptr && r ) BOOST_NOEXCEPT +{ + (void) dynamic_cast< T* >( static_cast< U* >( 0 ) ); + + typedef typename shared_ptr::element_type E; + + E * p = dynamic_cast< E* >( r.get() ); + return p? shared_ptr( std::move(r), p ): shared_ptr(); +} + +template shared_ptr reinterpret_pointer_cast( shared_ptr && r ) BOOST_NOEXCEPT +{ + (void) reinterpret_cast< T* >( static_cast< U* >( 0 ) ); + + typedef typename shared_ptr::element_type E; + + E * p = reinterpret_cast< E* >( r.get() ); + return shared_ptr( std::move(r), p ); +} + +#endif // !defined( BOOST_NO_CXX11_RVALUE_REFERENCES ) + // get_pointer() enables boost::mem_fn to recognize shared_ptr template inline typename shared_ptr::element_type * get_pointer(shared_ptr const & p) BOOST_NOEXCEPT diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index a9546db..b30eead 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -34,6 +34,7 @@ import testing ; [ run auto_ptr_rv_test.cpp ] [ run shared_ptr_alias_test.cpp ] [ run shared_ptr_rv_test.cpp ] + [ run shared_ptr_rv_pointer_cast_test.cpp ] [ run shared_ptr_move_test.cpp ] [ run shared_ptr_alias_move_test.cpp ] [ compile-fail shared_ptr_pv_fail.cpp ] diff --git a/test/shared_ptr_rv_pointer_cast_test.cpp b/test/shared_ptr_rv_pointer_cast_test.cpp new file mode 100644 index 0000000..0c4ea8b --- /dev/null +++ b/test/shared_ptr_rv_pointer_cast_test.cpp @@ -0,0 +1,96 @@ +// +// shared_ptr_rv_pointer_cast_test.cpp +// +// Copyright (c) 2016 Chris Glover +// +// 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 + +#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES ) + +struct X +{}; + +struct Y: public X +{}; + +struct U +{ + virtual ~U() {} +}; + +struct V: public U +{}; + +struct W : public U +{}; + +int main() +{ + { + boost::shared_ptr px(new Y); + + boost::shared_ptr py1 = boost::static_pointer_cast(px); + boost::shared_ptr py2 = boost::static_pointer_cast(std::move(px)); + BOOST_TEST(!px); + BOOST_TEST(px.use_count() == 0); + BOOST_TEST(py1.get() == py2.get()); + BOOST_TEST(!(py1 < py2 || py2 < py1)); + BOOST_TEST(py1.use_count() == 2); + BOOST_TEST(py2.use_count() == 2); + } + + { + boost::shared_ptr px(new int); + + boost::shared_ptr px2 = boost::const_pointer_cast(px); + boost::shared_ptr px3 = boost::const_pointer_cast(std::move(px)); + BOOST_TEST(!px); + BOOST_TEST(px.use_count() == 0); + BOOST_TEST(px2.get() == px3.get()); + BOOST_TEST(!(px2 < px3 || px2 < px3)); + BOOST_TEST(px2.use_count() == 2); + BOOST_TEST(px3.use_count() == 2); + } + +#if !defined( BOOST_NO_RTTI ) + { + boost::shared_ptr pu(new V); + + boost::shared_ptr pv1 = boost::dynamic_pointer_cast(pu); + boost::shared_ptr pv2 = boost::dynamic_pointer_cast(std::move(pu)); + BOOST_TEST(!pu); + BOOST_TEST(pu.use_count() == 0); + BOOST_TEST(pv1.get() == pv2.get()); + BOOST_TEST(!(pv1 < pv2 || pv2 < pv1)); + BOOST_TEST(pv1.use_count() == 2); + BOOST_TEST(pv2.use_count() == 2); + } + + { + boost::shared_ptr pu(new V); + boost::shared_ptr pw = boost::dynamic_pointer_cast(std::move(pu)); + BOOST_TEST(!pw); + BOOST_TEST(pu); + } +#endif // !defined( BOOST_NO_RTTI ) + + return boost::report_errors(); +} + +#else // !defined( BOOST_NO_CXX11_RVALUE_REFERENCES ) + +int main() +{ + return 0; +} + + +#endif // !defined( BOOST_NO_CXX11_RVALUE_REFERENCES ) + + From ebd1788f2cd6f8861823ad32e29ba1d2f4262030 Mon Sep 17 00:00:00 2001 From: Chris Glover Date: Sun, 11 Dec 2016 21:18:18 -0500 Subject: [PATCH 5/6] Add test for rvalue reinterpret_pointer_cast. --- test/shared_ptr_rv_pointer_cast_test.cpp | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/test/shared_ptr_rv_pointer_cast_test.cpp b/test/shared_ptr_rv_pointer_cast_test.cpp index 0c4ea8b..c471bda 100644 --- a/test/shared_ptr_rv_pointer_cast_test.cpp +++ b/test/shared_ptr_rv_pointer_cast_test.cpp @@ -58,6 +58,19 @@ int main() BOOST_TEST(px3.use_count() == 2); } + { + boost::shared_ptr pv(reinterpret_cast(new Y)); + + boost::shared_ptr py1 = boost::reinterpret_pointer_cast(pv); + boost::shared_ptr py2 = boost::reinterpret_pointer_cast(std::move(pv)); + BOOST_TEST(!pv); + BOOST_TEST(pv.use_count() == 0); + BOOST_TEST(py1.get() == py2.get()); + BOOST_TEST(!(py1 < py2 || py2 < py1)); + BOOST_TEST(py1.use_count() == 2); + BOOST_TEST(py2.use_count() == 2); + } + #if !defined( BOOST_NO_RTTI ) { boost::shared_ptr pu(new V); @@ -90,7 +103,4 @@ int main() return 0; } - #endif // !defined( BOOST_NO_CXX11_RVALUE_REFERENCES ) - - From 9e568dad6e8f042b43b0a0b1f938dfe15aeff040 Mon Sep 17 00:00:00 2001 From: Chris Glover Date: Sun, 11 Dec 2016 22:18:57 -0500 Subject: [PATCH 6/6] Add explicit tests for reinterpret_pointer_cast. Based on existing pointer_cast tests in shared_ptr_test.cpp --- test/Jamfile.v2 | 1 + ...ared_ptr_reinterpret_pointer_cast_test.cpp | 55 +++++++++++++++++++ 2 files changed, 56 insertions(+) create mode 100644 test/shared_ptr_reinterpret_pointer_cast_test.cpp diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index a9546db..8b1ee4f 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -36,6 +36,7 @@ import testing ; [ run shared_ptr_rv_test.cpp ] [ run shared_ptr_move_test.cpp ] [ run shared_ptr_alias_move_test.cpp ] + [ run shared_ptr_reinterpret_pointer_cast_test.cpp ] [ compile-fail shared_ptr_pv_fail.cpp ] [ run sp_unary_addr_test.cpp ] [ compile-fail scoped_ptr_eq_fail.cpp ] diff --git a/test/shared_ptr_reinterpret_pointer_cast_test.cpp b/test/shared_ptr_reinterpret_pointer_cast_test.cpp new file mode 100644 index 0000000..e7076df --- /dev/null +++ b/test/shared_ptr_reinterpret_pointer_cast_test.cpp @@ -0,0 +1,55 @@ +// +// shared_pointer_reinterpret_pointer_cast_test.cpp +// +// Copyright (c) 2016 Chris Glover +// +// 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 X +{}; + +int main() +{ + { + boost::shared_ptr pc; + + boost::shared_ptr pi = boost::reinterpret_pointer_cast(pc); + BOOST_TEST(pi.get() == 0); + + boost::shared_ptr px = boost::reinterpret_pointer_cast(pc); + BOOST_TEST(px.get() == 0); + } + + { + boost::shared_ptr pi(new int); + boost::shared_ptr pc = boost::reinterpret_pointer_cast(pi); + + boost::shared_ptr pi2 = boost::reinterpret_pointer_cast(pc); + BOOST_TEST(pi.get() == pi2.get()); + BOOST_TEST(!(pi < pi2 || pi2 < pi)); + BOOST_TEST(pi.use_count() == 3); + BOOST_TEST(pc.use_count() == 3); + BOOST_TEST(pi2.use_count() == 3); + } + + { + boost::shared_ptr px(new X); + boost::shared_ptr pc = boost::reinterpret_pointer_cast(px); + + boost::shared_ptr px2 = boost::reinterpret_pointer_cast(pc); + BOOST_TEST(px.get() == px2.get()); + BOOST_TEST(!(px < px2 || px2 < px)); + BOOST_TEST(px.use_count() == 3); + BOOST_TEST(pc.use_count() == 3); + BOOST_TEST(px2.use_count() == 3); + } + + return boost::report_errors(); +} +