diff --git a/include/boost/smart_ptr/allocate_local_shared_array.hpp b/include/boost/smart_ptr/allocate_local_shared_array.hpp index 0890849..89d3285 100644 --- a/include/boost/smart_ptr/allocate_local_shared_array.hpp +++ b/include/boost/smart_ptr/allocate_local_shared_array.hpp @@ -21,11 +21,12 @@ public: count_ = shared_count(base); } - virtual void local_cb_destroy() BOOST_SP_NOEXCEPT { + void local_cb_destroy() BOOST_SP_NOEXCEPT BOOST_OVERRIDE { shared_count().swap(count_); } - virtual shared_count local_cb_get_shared_count() const BOOST_SP_NOEXCEPT { + shared_count local_cb_get_shared_count() const + BOOST_SP_NOEXCEPT BOOST_OVERRIDE { return count_; } diff --git a/include/boost/smart_ptr/allocate_shared_array.hpp b/include/boost/smart_ptr/allocate_shared_array.hpp index bca9865..9bf7322 100644 --- a/include/boost/smart_ptr/allocate_shared_array.hpp +++ b/include/boost/smart_ptr/allocate_shared_array.hpp @@ -206,28 +206,29 @@ public: return state_; } - virtual void dispose() BOOST_SP_NOEXCEPT { + void dispose() BOOST_SP_NOEXCEPT BOOST_OVERRIDE { boost::alloc_destroy_n(state_.allocator(), boost::first_scalar(sp_array_start(this)), state_.size() * sp_array_count::value); } - virtual void destroy() BOOST_SP_NOEXCEPT { + void destroy() BOOST_SP_NOEXCEPT BOOST_OVERRIDE { sp_array_creator other(state_.allocator(), state_.size()); this->~sp_array_base(); other.destroy(this); } - virtual void* get_deleter(const sp_typeinfo_&) BOOST_SP_NOEXCEPT { + void* get_deleter(const sp_typeinfo_&) BOOST_SP_NOEXCEPT BOOST_OVERRIDE { return 0; } - virtual void* get_local_deleter(const sp_typeinfo_&) BOOST_SP_NOEXCEPT { + void* get_local_deleter(const sp_typeinfo_&) + BOOST_SP_NOEXCEPT BOOST_OVERRIDE { return 0; } - virtual void* get_untyped_deleter() BOOST_SP_NOEXCEPT { + void* get_untyped_deleter() BOOST_SP_NOEXCEPT BOOST_OVERRIDE { return 0; } diff --git a/include/boost/smart_ptr/bad_weak_ptr.hpp b/include/boost/smart_ptr/bad_weak_ptr.hpp index d0b3ff1..0a3cfcb 100644 --- a/include/boost/smart_ptr/bad_weak_ptr.hpp +++ b/include/boost/smart_ptr/bad_weak_ptr.hpp @@ -47,7 +47,7 @@ class bad_weak_ptr: public std::exception { public: - virtual char const * what() const BOOST_NOEXCEPT_OR_NOTHROW + virtual char const * what() const BOOST_NOEXCEPT_OR_NOTHROW BOOST_OVERRIDE { return "tr1::bad_weak_ptr"; } diff --git a/include/boost/smart_ptr/detail/local_counted_base.hpp b/include/boost/smart_ptr/detail/local_counted_base.hpp index 405ef30..3914aa1 100644 --- a/include/boost/smart_ptr/detail/local_counted_base.hpp +++ b/include/boost/smart_ptr/detail/local_counted_base.hpp @@ -113,12 +113,12 @@ public: #endif - virtual void local_cb_destroy() BOOST_SP_NOEXCEPT + virtual void local_cb_destroy() BOOST_SP_NOEXCEPT BOOST_OVERRIDE { delete this; } - virtual boost::detail::shared_count local_cb_get_shared_count() const BOOST_SP_NOEXCEPT + virtual boost::detail::shared_count local_cb_get_shared_count() const BOOST_SP_NOEXCEPT BOOST_OVERRIDE { return pn_; } @@ -130,12 +130,12 @@ public: shared_count pn_; - virtual void local_cb_destroy() BOOST_SP_NOEXCEPT + virtual void local_cb_destroy() BOOST_SP_NOEXCEPT BOOST_OVERRIDE { shared_count().swap( pn_ ); } - virtual boost::detail::shared_count local_cb_get_shared_count() const BOOST_SP_NOEXCEPT + virtual boost::detail::shared_count local_cb_get_shared_count() const BOOST_SP_NOEXCEPT BOOST_OVERRIDE { return pn_; } diff --git a/include/boost/smart_ptr/detail/sp_counted_impl.hpp b/include/boost/smart_ptr/detail/sp_counted_impl.hpp index 96c9da3..23ea339 100644 --- a/include/boost/smart_ptr/detail/sp_counted_impl.hpp +++ b/include/boost/smart_ptr/detail/sp_counted_impl.hpp @@ -85,7 +85,7 @@ public: #endif } - virtual void dispose() BOOST_SP_NOEXCEPT + virtual void dispose() BOOST_SP_NOEXCEPT BOOST_OVERRIDE { #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) boost::sp_scalar_destructor_hook( px_, sizeof(X), this ); @@ -93,17 +93,17 @@ public: boost::checked_delete( px_ ); } - virtual void * get_deleter( sp_typeinfo_ const & ) BOOST_SP_NOEXCEPT + virtual void * get_deleter( sp_typeinfo_ const & ) BOOST_SP_NOEXCEPT BOOST_OVERRIDE { return 0; } - virtual void * get_local_deleter( sp_typeinfo_ const & ) BOOST_SP_NOEXCEPT + virtual void * get_local_deleter( sp_typeinfo_ const & ) BOOST_SP_NOEXCEPT BOOST_OVERRIDE { return 0; } - virtual void * get_untyped_deleter() BOOST_SP_NOEXCEPT + virtual void * get_untyped_deleter() BOOST_SP_NOEXCEPT BOOST_OVERRIDE { return 0; } @@ -168,22 +168,22 @@ public: { } - virtual void dispose() BOOST_SP_NOEXCEPT + virtual void dispose() BOOST_SP_NOEXCEPT BOOST_OVERRIDE { del( ptr ); } - virtual void * get_deleter( sp_typeinfo_ const & ti ) BOOST_SP_NOEXCEPT + virtual void * get_deleter( sp_typeinfo_ const & ti ) BOOST_SP_NOEXCEPT BOOST_OVERRIDE { return ti == BOOST_SP_TYPEID_(D)? &reinterpret_cast( del ): 0; } - virtual void * get_local_deleter( sp_typeinfo_ const & ti ) BOOST_SP_NOEXCEPT + virtual void * get_local_deleter( sp_typeinfo_ const & ti ) BOOST_SP_NOEXCEPT BOOST_OVERRIDE { return ti == BOOST_SP_TYPEID_(D)? boost::detail::get_local_deleter( boost::addressof( del ) ): 0; } - virtual void * get_untyped_deleter() BOOST_SP_NOEXCEPT + virtual void * get_untyped_deleter() BOOST_SP_NOEXCEPT BOOST_OVERRIDE { return &reinterpret_cast( del ); } diff --git a/include/boost/smart_ptr/enable_shared_from.hpp b/include/boost/smart_ptr/enable_shared_from.hpp index db347e6..be88b30 100644 --- a/include/boost/smart_ptr/enable_shared_from.hpp +++ b/include/boost/smart_ptr/enable_shared_from.hpp @@ -3,7 +3,7 @@ // enable_shared_from.hpp // -// Copyright 2019 Peter Dimov +// Copyright 2019, 2020 Peter Dimov // // Distributed under the Boost Software License, Version 1.0. // See accompanying file LICENSE_1_0.txt or copy at @@ -19,17 +19,21 @@ namespace boost class enable_shared_from: public enable_shared_from_this { +private: + + using enable_shared_from_this::shared_from_this; + using enable_shared_from_this::weak_from_this; }; template shared_ptr shared_from( T * p ) { - return shared_ptr( p->enable_shared_from::shared_from_this(), p ); + return shared_ptr( p->enable_shared_from_this::shared_from_this(), p ); } template weak_ptr weak_from( T * p ) BOOST_SP_NOEXCEPT { - return weak_ptr( p->enable_shared_from::weak_from_this(), p ); + return weak_ptr( p->enable_shared_from_this::weak_from_this(), p ); } } // namespace boost diff --git a/include/boost/smart_ptr/shared_ptr.hpp b/include/boost/smart_ptr/shared_ptr.hpp index f54bdd7..6674b15 100644 --- a/include/boost/smart_ptr/shared_ptr.hpp +++ b/include/boost/smart_ptr/shared_ptr.hpp @@ -1175,6 +1175,13 @@ template D const * basic_get_local_deleter( D const *, shared_ } // namespace detail +#if defined(__cpp_deduction_guides) + +template shared_ptr( weak_ptr ) -> shared_ptr; +template shared_ptr( std::unique_ptr ) -> shared_ptr; + +#endif + } // namespace boost #if defined( BOOST_SP_DISABLE_DEPRECATED ) diff --git a/include/boost/smart_ptr/weak_ptr.hpp b/include/boost/smart_ptr/weak_ptr.hpp index 5230f35..07ba189 100644 --- a/include/boost/smart_ptr/weak_ptr.hpp +++ b/include/boost/smart_ptr/weak_ptr.hpp @@ -264,6 +264,12 @@ template void swap(weak_ptr & a, weak_ptr & b) BOOST_SP_NOEXCEPT a.swap(b); } +#if defined(__cpp_deduction_guides) + +template weak_ptr( shared_ptr ) -> weak_ptr; + +#endif + } // namespace boost #endif // #ifndef BOOST_SMART_PTR_WEAK_PTR_HPP_INCLUDED diff --git a/test/Jamfile b/test/Jamfile index f055d21..0d31010 100644 --- a/test/Jamfile +++ b/test/Jamfile @@ -352,3 +352,12 @@ run allocate_unique_noinit_test.cpp ; run allocate_unique_test.cpp ; run allocate_unique_throws_test.cpp ; run allocate_unique_value_test.cpp ; + +run sp_guides_test.cpp ; +run sp_guides_test2.cpp ; +run wp_guides_test.cpp ; + +compile-fail shared_from_fail.cpp ; +compile-fail weak_from_fail.cpp ; + +compile sp_override_test.cpp ; diff --git a/test/shared_from_fail.cpp b/test/shared_from_fail.cpp new file mode 100644 index 0000000..5d670fa --- /dev/null +++ b/test/shared_from_fail.cpp @@ -0,0 +1,22 @@ +// Copyright 2020 Peter Dimov +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt + +#include +#include + +struct X: public boost::enable_shared_from +{ +}; + +#if defined(__clang__) && defined(_MSC_VER) +// clang-cl claims that it accepts this code for compatibility +// with msvc, but no version of msvc accepts it +# pragma clang diagnostic error "-Wmicrosoft-using-decl" +#endif + +int main() +{ + boost::shared_ptr px( new X ); + px->shared_from_this(); +} diff --git a/test/sp_guides_test.cpp b/test/sp_guides_test.cpp new file mode 100644 index 0000000..a7c6ff4 --- /dev/null +++ b/test/sp_guides_test.cpp @@ -0,0 +1,25 @@ +// Copyright 2020 Peter Dimov +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt + +#if defined(__cpp_deduction_guides) + +#include +#include + +int main() +{ + boost::shared_ptr p1( new int ); + boost::weak_ptr p2( p1 ); + boost::shared_ptr p3( p2 ); +} + +#else + +#include + +BOOST_PRAGMA_MESSAGE( "Skipping test because __cpp_deduction_guides is not defined" ) + +int main() {} + +#endif diff --git a/test/sp_guides_test2.cpp b/test/sp_guides_test2.cpp new file mode 100644 index 0000000..e7ccfbc --- /dev/null +++ b/test/sp_guides_test2.cpp @@ -0,0 +1,23 @@ +// Copyright 2020 Peter Dimov +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt + +#if defined(__cpp_deduction_guides) + +#include +#include + +int main() +{ + boost::shared_ptr p2( std::unique_ptr( new int ) ); +} + +#else + +#include + +BOOST_PRAGMA_MESSAGE( "Skipping test because __cpp_deduction_guides is not defined" ) + +int main() {} + +#endif diff --git a/test/sp_override_test.cpp b/test/sp_override_test.cpp new file mode 100644 index 0000000..8eb72dd --- /dev/null +++ b/test/sp_override_test.cpp @@ -0,0 +1,18 @@ +// Copyright 2020 Peter Dimov +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt + +#if defined(__GNUC__) && __GNUC__ >= 5 && __cplusplus >= 201103L +# pragma GCC diagnostic error "-Wsuggest-override" +#endif + +#include + +int main() +{ + boost::shared_ptr p1( new int ); + boost::shared_ptr p2( new int[1] ); + + boost::make_shared(); + boost::make_shared( 1 ); +} diff --git a/test/weak_from_fail.cpp b/test/weak_from_fail.cpp new file mode 100644 index 0000000..7503c3f --- /dev/null +++ b/test/weak_from_fail.cpp @@ -0,0 +1,22 @@ +// Copyright 2020 Peter Dimov +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt + +#include +#include + +struct X: public boost::enable_shared_from +{ +}; + +#if defined(__clang__) && defined(_MSC_VER) +// clang-cl claims that it accepts this code for compatibility +// with msvc, but no version of msvc accepts it +# pragma clang diagnostic error "-Wmicrosoft-using-decl" +#endif + +int main() +{ + boost::shared_ptr px( new X ); + px->weak_from_this(); +} diff --git a/test/wp_guides_test.cpp b/test/wp_guides_test.cpp new file mode 100644 index 0000000..92f95a0 --- /dev/null +++ b/test/wp_guides_test.cpp @@ -0,0 +1,24 @@ +// Copyright 2020 Peter Dimov +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt + +#if defined(__cpp_deduction_guides) + +#include +#include + +int main() +{ + boost::shared_ptr p1( new int ); + boost::weak_ptr p2( p1 ); +} + +#else + +#include + +BOOST_PRAGMA_MESSAGE( "Skipping test because __cpp_deduction_guides is not defined" ) + +int main() {} + +#endif