From 6e5a382b6b84b4ef9d23fefe48bdfcc24acd7305 Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Tue, 20 Jun 2017 19:01:16 +0300 Subject: [PATCH] Start work on get_deleter for local_shared_ptr --- .../smart_ptr/detail/local_counted_base.hpp | 1 - .../smart_ptr/detail/local_sp_deleter.hpp | 82 ++++++++++++++++ .../boost/smart_ptr/detail/shared_count.hpp | 5 + .../detail/sp_counted_base_acc_ia64.hpp | 1 + .../smart_ptr/detail/sp_counted_base_aix.hpp | 1 + .../detail/sp_counted_base_clang.hpp | 1 + .../detail/sp_counted_base_cw_ppc.hpp | 1 + .../detail/sp_counted_base_cw_x86.hpp | 1 + .../detail/sp_counted_base_gcc_ia64.hpp | 1 + .../detail/sp_counted_base_gcc_mips.hpp | 1 + .../detail/sp_counted_base_gcc_ppc.hpp | 1 + .../detail/sp_counted_base_gcc_sparc.hpp | 1 + .../detail/sp_counted_base_gcc_x86.hpp | 1 + .../smart_ptr/detail/sp_counted_base_nt.hpp | 1 + .../smart_ptr/detail/sp_counted_base_pt.hpp | 1 + .../detail/sp_counted_base_snc_ps3.hpp | 1 + .../detail/sp_counted_base_solaris.hpp | 1 + .../smart_ptr/detail/sp_counted_base_spin.hpp | 1 + .../detail/sp_counted_base_std_atomic.hpp | 1 + .../smart_ptr/detail/sp_counted_base_sync.hpp | 1 + .../detail/sp_counted_base_vacpp_ppc.hpp | 1 + .../smart_ptr/detail/sp_counted_base_w32.hpp | 1 + .../smart_ptr/detail/sp_counted_impl.hpp | 28 ++++++ include/boost/smart_ptr/local_shared_ptr.hpp | 57 +++-------- .../smart_ptr/make_local_shared_object.hpp | 1 - include/boost/smart_ptr/shared_ptr.hpp | 58 +++++++---- test/Jamfile.v2 | 5 +- test/get_local_deleter_test.cpp | 95 +++++++++++++++++++ test/get_local_deleter_test2.cpp | 43 +++++++++ 29 files changed, 326 insertions(+), 68 deletions(-) create mode 100644 include/boost/smart_ptr/detail/local_sp_deleter.hpp create mode 100644 test/get_local_deleter_test.cpp create mode 100644 test/get_local_deleter_test2.cpp diff --git a/include/boost/smart_ptr/detail/local_counted_base.hpp b/include/boost/smart_ptr/detail/local_counted_base.hpp index f5a5244..b9a3911 100644 --- a/include/boost/smart_ptr/detail/local_counted_base.hpp +++ b/include/boost/smart_ptr/detail/local_counted_base.hpp @@ -17,7 +17,6 @@ // // See http://www.boost.org/libs/smart_ptr/ for documentation. -#include #include #include #include diff --git a/include/boost/smart_ptr/detail/local_sp_deleter.hpp b/include/boost/smart_ptr/detail/local_sp_deleter.hpp new file mode 100644 index 0000000..3dd62fa --- /dev/null +++ b/include/boost/smart_ptr/detail/local_sp_deleter.hpp @@ -0,0 +1,82 @@ +#ifndef BOOST_SMART_PTR_DETAIL_LOCAL_SP_DELETER_HPP_INCLUDED +#define BOOST_SMART_PTR_DETAIL_LOCAL_SP_DELETER_HPP_INCLUDED + +// MS compatible compilers support #pragma once + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +// detail/local_sp_deleter.hpp +// +// Copyright 2017 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) +// +// See http://www.boost.org/libs/smart_ptr/ for documentation. + +#include +#include + +namespace boost +{ + +namespace detail +{ + +template class local_sp_deleter: public local_counted_impl_em +{ +private: + + D d_; + +public: + + local_sp_deleter(): d_() + { + } + + explicit local_sp_deleter( D const& d ) BOOST_SP_NOEXCEPT: d_( d ) + { + } + +#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES ) + + explicit local_sp_deleter( D&& d ) BOOST_SP_NOEXCEPT: d_( std::move(d) ) + { + } + +#endif + + D& deleter() + { + return d_; + } + + template void operator()( Y* p ) BOOST_SP_NOEXCEPT + { + d_( p ); + } + +#if !defined( BOOST_NO_CXX11_NULLPTR ) + + void operator()( boost::detail::sp_nullptr_t p ) BOOST_SP_NOEXCEPT + { + d_( p ); + } + +#endif +}; + +template D * get_local_deleter( local_sp_deleter * p ) +{ + return &p->deleter(); +} + +} // namespace detail + +} // namespace boost + +#endif // #ifndef BOOST_SMART_PTR_DETAIL_LOCAL_SP_DELETER_HPP_INCLUDED diff --git a/include/boost/smart_ptr/detail/shared_count.hpp b/include/boost/smart_ptr/detail/shared_count.hpp index 7f375e8..1fc1433 100644 --- a/include/boost/smart_ptr/detail/shared_count.hpp +++ b/include/boost/smart_ptr/detail/shared_count.hpp @@ -496,6 +496,11 @@ public: return pi_? pi_->get_deleter( ti ): 0; } + void * get_local_deleter( sp_typeinfo const & ti ) const + { + return pi_? pi_->get_local_deleter( ti ): 0; + } + void * get_untyped_deleter() const { return pi_? pi_->get_untyped_deleter(): 0; diff --git a/include/boost/smart_ptr/detail/sp_counted_base_acc_ia64.hpp b/include/boost/smart_ptr/detail/sp_counted_base_acc_ia64.hpp index cebc243..ec6f6ee 100644 --- a/include/boost/smart_ptr/detail/sp_counted_base_acc_ia64.hpp +++ b/include/boost/smart_ptr/detail/sp_counted_base_acc_ia64.hpp @@ -104,6 +104,7 @@ public: } virtual void * get_deleter( sp_typeinfo const & ti ) = 0; + virtual void * get_local_deleter( sp_typeinfo const & ti ) = 0; virtual void * get_untyped_deleter() = 0; void add_ref_copy() diff --git a/include/boost/smart_ptr/detail/sp_counted_base_aix.hpp b/include/boost/smart_ptr/detail/sp_counted_base_aix.hpp index fe6c727..ce8ee68 100644 --- a/include/boost/smart_ptr/detail/sp_counted_base_aix.hpp +++ b/include/boost/smart_ptr/detail/sp_counted_base_aix.hpp @@ -96,6 +96,7 @@ public: } virtual void * get_deleter( sp_typeinfo const & ti ) = 0; + virtual void * get_local_deleter( sp_typeinfo const & ti ) = 0; virtual void * get_untyped_deleter() = 0; void add_ref_copy() 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 7598495..8b3bfad 100644 --- a/include/boost/smart_ptr/detail/sp_counted_base_clang.hpp +++ b/include/boost/smart_ptr/detail/sp_counted_base_clang.hpp @@ -98,6 +98,7 @@ public: } virtual void * get_deleter( sp_typeinfo const & ti ) = 0; + virtual void * get_local_deleter( sp_typeinfo const & ti ) = 0; virtual void * get_untyped_deleter() = 0; void add_ref_copy() diff --git a/include/boost/smart_ptr/detail/sp_counted_base_cw_ppc.hpp b/include/boost/smart_ptr/detail/sp_counted_base_cw_ppc.hpp index 6c268e8..065f7c3 100644 --- a/include/boost/smart_ptr/detail/sp_counted_base_cw_ppc.hpp +++ b/include/boost/smart_ptr/detail/sp_counted_base_cw_ppc.hpp @@ -124,6 +124,7 @@ public: } virtual void * get_deleter( sp_typeinfo const & ti ) = 0; + virtual void * get_local_deleter( sp_typeinfo const & ti ) = 0; virtual void * get_untyped_deleter() = 0; void add_ref_copy() diff --git a/include/boost/smart_ptr/detail/sp_counted_base_cw_x86.hpp b/include/boost/smart_ptr/detail/sp_counted_base_cw_x86.hpp index 81eba6f..3a3d4d4 100644 --- a/include/boost/smart_ptr/detail/sp_counted_base_cw_x86.hpp +++ b/include/boost/smart_ptr/detail/sp_counted_base_cw_x86.hpp @@ -112,6 +112,7 @@ public: } virtual void * get_deleter( sp_typeinfo const & ti ) = 0; + virtual void * get_local_deleter( sp_typeinfo const & ti ) = 0; virtual void * get_untyped_deleter() = 0; void add_ref_copy() diff --git a/include/boost/smart_ptr/detail/sp_counted_base_gcc_ia64.hpp b/include/boost/smart_ptr/detail/sp_counted_base_gcc_ia64.hpp index f6e3904..6c3cce8 100644 --- a/include/boost/smart_ptr/detail/sp_counted_base_gcc_ia64.hpp +++ b/include/boost/smart_ptr/detail/sp_counted_base_gcc_ia64.hpp @@ -111,6 +111,7 @@ public: } virtual void * get_deleter( sp_typeinfo const & ti ) = 0; + virtual void * get_local_deleter( sp_typeinfo const & ti ) = 0; virtual void * get_untyped_deleter() = 0; void add_ref_copy() diff --git a/include/boost/smart_ptr/detail/sp_counted_base_gcc_mips.hpp b/include/boost/smart_ptr/detail/sp_counted_base_gcc_mips.hpp index 545c8ae..76ac2a6 100644 --- a/include/boost/smart_ptr/detail/sp_counted_base_gcc_mips.hpp +++ b/include/boost/smart_ptr/detail/sp_counted_base_gcc_mips.hpp @@ -135,6 +135,7 @@ public: } virtual void * get_deleter( sp_typeinfo const & ti ) = 0; + virtual void * get_local_deleter( sp_typeinfo const & ti ) = 0; virtual void * get_untyped_deleter() = 0; void add_ref_copy() diff --git a/include/boost/smart_ptr/detail/sp_counted_base_gcc_ppc.hpp b/include/boost/smart_ptr/detail/sp_counted_base_gcc_ppc.hpp index 2e5bc0e..0fb8074 100644 --- a/include/boost/smart_ptr/detail/sp_counted_base_gcc_ppc.hpp +++ b/include/boost/smart_ptr/detail/sp_counted_base_gcc_ppc.hpp @@ -135,6 +135,7 @@ public: } virtual void * get_deleter( sp_typeinfo const & ti ) = 0; + virtual void * get_local_deleter( sp_typeinfo const & ti ) = 0; virtual void * get_untyped_deleter() = 0; void add_ref_copy() diff --git a/include/boost/smart_ptr/detail/sp_counted_base_gcc_sparc.hpp b/include/boost/smart_ptr/detail/sp_counted_base_gcc_sparc.hpp index c6d20ce..b8bb707 100644 --- a/include/boost/smart_ptr/detail/sp_counted_base_gcc_sparc.hpp +++ b/include/boost/smart_ptr/detail/sp_counted_base_gcc_sparc.hpp @@ -120,6 +120,7 @@ public: } virtual void * get_deleter( sp_typeinfo const & ti ) = 0; + virtual void * get_local_deleter( sp_typeinfo const & ti ) = 0; virtual void * get_untyped_deleter() = 0; void add_ref_copy() diff --git a/include/boost/smart_ptr/detail/sp_counted_base_gcc_x86.hpp b/include/boost/smart_ptr/detail/sp_counted_base_gcc_x86.hpp index 173dce5..3d2dd61 100644 --- a/include/boost/smart_ptr/detail/sp_counted_base_gcc_x86.hpp +++ b/include/boost/smart_ptr/detail/sp_counted_base_gcc_x86.hpp @@ -127,6 +127,7 @@ public: } virtual void * get_deleter( sp_typeinfo const & ti ) = 0; + virtual void * get_local_deleter( sp_typeinfo const & ti ) = 0; virtual void * get_untyped_deleter() = 0; void add_ref_copy() diff --git a/include/boost/smart_ptr/detail/sp_counted_base_nt.hpp b/include/boost/smart_ptr/detail/sp_counted_base_nt.hpp index 5c901f9..dea905c 100644 --- a/include/boost/smart_ptr/detail/sp_counted_base_nt.hpp +++ b/include/boost/smart_ptr/detail/sp_counted_base_nt.hpp @@ -59,6 +59,7 @@ public: } virtual void * get_deleter( sp_typeinfo const & ti ) = 0; + virtual void * get_local_deleter( sp_typeinfo const & ti ) = 0; virtual void * get_untyped_deleter() = 0; void add_ref_copy() diff --git a/include/boost/smart_ptr/detail/sp_counted_base_pt.hpp b/include/boost/smart_ptr/detail/sp_counted_base_pt.hpp index a16d2d8..85f2563 100644 --- a/include/boost/smart_ptr/detail/sp_counted_base_pt.hpp +++ b/include/boost/smart_ptr/detail/sp_counted_base_pt.hpp @@ -71,6 +71,7 @@ public: } virtual void * get_deleter( sp_typeinfo const & ti ) = 0; + virtual void * get_local_deleter( sp_typeinfo const & ti ) = 0; virtual void * get_untyped_deleter() = 0; void add_ref_copy() diff --git a/include/boost/smart_ptr/detail/sp_counted_base_snc_ps3.hpp b/include/boost/smart_ptr/detail/sp_counted_base_snc_ps3.hpp index 56ed79f..7b5f917 100644 --- a/include/boost/smart_ptr/detail/sp_counted_base_snc_ps3.hpp +++ b/include/boost/smart_ptr/detail/sp_counted_base_snc_ps3.hpp @@ -115,6 +115,7 @@ public: } virtual void * get_deleter( sp_typeinfo const & ti ) = 0; + virtual void * get_local_deleter( sp_typeinfo const & ti ) = 0; virtual void * get_untyped_deleter() = 0; void add_ref_copy() diff --git a/include/boost/smart_ptr/detail/sp_counted_base_solaris.hpp b/include/boost/smart_ptr/detail/sp_counted_base_solaris.hpp index 0e05fef..0db9c6c 100644 --- a/include/boost/smart_ptr/detail/sp_counted_base_solaris.hpp +++ b/include/boost/smart_ptr/detail/sp_counted_base_solaris.hpp @@ -62,6 +62,7 @@ public: } virtual void * get_deleter( sp_typeinfo const & ti ) = 0; + virtual void * get_local_deleter( sp_typeinfo const & ti ) = 0; virtual void * get_untyped_deleter() = 0; void add_ref_copy() diff --git a/include/boost/smart_ptr/detail/sp_counted_base_spin.hpp b/include/boost/smart_ptr/detail/sp_counted_base_spin.hpp index 77734e7..faf503a 100644 --- a/include/boost/smart_ptr/detail/sp_counted_base_spin.hpp +++ b/include/boost/smart_ptr/detail/sp_counted_base_spin.hpp @@ -84,6 +84,7 @@ public: } virtual void * get_deleter( sp_typeinfo const & ti ) = 0; + virtual void * get_local_deleter( sp_typeinfo const & ti ) = 0; virtual void * get_untyped_deleter() = 0; void add_ref_copy() diff --git a/include/boost/smart_ptr/detail/sp_counted_base_std_atomic.hpp b/include/boost/smart_ptr/detail/sp_counted_base_std_atomic.hpp index cab8453..7a188f8 100644 --- a/include/boost/smart_ptr/detail/sp_counted_base_std_atomic.hpp +++ b/include/boost/smart_ptr/detail/sp_counted_base_std_atomic.hpp @@ -90,6 +90,7 @@ public: } virtual void * get_deleter( sp_typeinfo const & ti ) = 0; + virtual void * get_local_deleter( sp_typeinfo const & ti ) = 0; virtual void * get_untyped_deleter() = 0; void add_ref_copy() diff --git a/include/boost/smart_ptr/detail/sp_counted_base_sync.hpp b/include/boost/smart_ptr/detail/sp_counted_base_sync.hpp index fafed0e..d2138e7 100644 --- a/include/boost/smart_ptr/detail/sp_counted_base_sync.hpp +++ b/include/boost/smart_ptr/detail/sp_counted_base_sync.hpp @@ -109,6 +109,7 @@ public: } virtual void * get_deleter( sp_typeinfo const & ti ) = 0; + virtual void * get_local_deleter( sp_typeinfo const & ti ) = 0; virtual void * get_untyped_deleter() = 0; void add_ref_copy() diff --git a/include/boost/smart_ptr/detail/sp_counted_base_vacpp_ppc.hpp b/include/boost/smart_ptr/detail/sp_counted_base_vacpp_ppc.hpp index 162f309..f2de3b0 100644 --- a/include/boost/smart_ptr/detail/sp_counted_base_vacpp_ppc.hpp +++ b/include/boost/smart_ptr/detail/sp_counted_base_vacpp_ppc.hpp @@ -104,6 +104,7 @@ public: } virtual void * get_deleter( sp_typeinfo const & ti ) = 0; + virtual void * get_local_deleter( sp_typeinfo const & ti ) = 0; virtual void * get_untyped_deleter() = 0; void add_ref_copy() diff --git a/include/boost/smart_ptr/detail/sp_counted_base_w32.hpp b/include/boost/smart_ptr/detail/sp_counted_base_w32.hpp index 4ba509c..960e42e 100644 --- a/include/boost/smart_ptr/detail/sp_counted_base_w32.hpp +++ b/include/boost/smart_ptr/detail/sp_counted_base_w32.hpp @@ -67,6 +67,7 @@ public: } virtual void * get_deleter( sp_typeinfo const & ti ) = 0; + virtual void * get_local_deleter( sp_typeinfo const & ti ) = 0; virtual void * get_untyped_deleter() = 0; void add_ref_copy() diff --git a/include/boost/smart_ptr/detail/sp_counted_impl.hpp b/include/boost/smart_ptr/detail/sp_counted_impl.hpp index b29769e..ad5d254 100644 --- a/include/boost/smart_ptr/detail/sp_counted_impl.hpp +++ b/include/boost/smart_ptr/detail/sp_counted_impl.hpp @@ -50,6 +50,19 @@ void sp_scalar_destructor_hook( void * px, std::size_t size, void * pn ); namespace detail { +// get_local_deleter + +template class local_sp_deleter; + +template D * get_local_deleter( D * p ) +{ + return 0; +} + +template D * get_local_deleter( local_sp_deleter * p ); + +// + template class sp_counted_impl_p: public sp_counted_base { private: @@ -83,6 +96,11 @@ public: return 0; } + virtual void * get_local_deleter( sp_typeinfo const & ) + { + return 0; + } + virtual void * get_untyped_deleter() { return 0; @@ -158,6 +176,11 @@ public: return ti == BOOST_SP_TYPEID(D)? &reinterpret_cast( del ): 0; } + virtual void * get_local_deleter( sp_typeinfo const & ti ) + { + return ti == BOOST_SP_TYPEID(D)? boost::detail::get_local_deleter( &reinterpret_cast( del ) ): 0; + } + virtual void * get_untyped_deleter() { return &reinterpret_cast( del ); @@ -246,6 +269,11 @@ public: return ti == BOOST_SP_TYPEID( D )? &reinterpret_cast( d_ ): 0; } + virtual void * get_local_deleter( sp_typeinfo const & ti ) + { + return ti == BOOST_SP_TYPEID(D)? boost::detail::get_local_deleter( &reinterpret_cast( d_ ) ): 0; + } + virtual void * get_untyped_deleter() { return &reinterpret_cast( d_ ); diff --git a/include/boost/smart_ptr/local_shared_ptr.hpp b/include/boost/smart_ptr/local_shared_ptr.hpp index d7a1278..2c0d2ab 100644 --- a/include/boost/smart_ptr/local_shared_ptr.hpp +++ b/include/boost/smart_ptr/local_shared_ptr.hpp @@ -11,7 +11,6 @@ // // See http://www.boost.org/libs/smart_ptr/ for documentation. -#include #include namespace boost @@ -22,46 +21,7 @@ template class local_shared_ptr; namespace detail { -template class local_sp_deleter: public local_counted_impl_em -{ -private: - - D d_; - -public: - - local_sp_deleter(): d_() - { - } - - explicit local_sp_deleter( D const& d ) BOOST_SP_NOEXCEPT: d_( d ) - { - } - -#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES ) - - explicit local_sp_deleter( D&& d ) BOOST_SP_NOEXCEPT: d_( std::move(d) ) - { - } - -#endif - - template void operator()( Y* p ) BOOST_SP_NOEXCEPT - { - d_( p ); - } - -#if !defined( BOOST_NO_CXX11_NULLPTR ) - - void operator()( boost::detail::sp_nullptr_t p ) BOOST_SP_NOEXCEPT - { - d_( p ); - } - -#endif -}; - -template< class E, class Y > inline void lsp_pointer_construct( boost::local_shared_ptr< E > * ppx, Y * p, boost::detail::local_counted_base * & pn ) +template< class E, class Y > inline void lsp_pointer_construct( boost::local_shared_ptr< E > * /*ppx*/, Y * p, boost::detail::local_counted_base * & pn ) { boost::detail::sp_assert_convertible< Y, E >(); @@ -76,7 +36,7 @@ template< class E, class Y > inline void lsp_pointer_construct( boost::local_sha pn = pd; } -template< class E, class Y > inline void lsp_pointer_construct( boost::local_shared_ptr< E[] > * ppx, Y * p, boost::detail::local_counted_base * & pn ) +template< class E, class Y > inline void lsp_pointer_construct( boost::local_shared_ptr< E[] > * /*ppx*/, Y * p, boost::detail::local_counted_base * & pn ) { boost::detail::sp_assert_convertible< Y[], E[] >(); @@ -91,7 +51,7 @@ template< class E, class Y > inline void lsp_pointer_construct( boost::local_sha pn = pd; } -template< class E, std::size_t N, class Y > inline void lsp_pointer_construct( boost::local_shared_ptr< E[N] > * ppx, Y * p, boost::detail::local_counted_base * & pn ) +template< class E, std::size_t N, class Y > inline void lsp_pointer_construct( boost::local_shared_ptr< E[N] > * /*ppx*/, Y * p, boost::detail::local_counted_base * & pn ) { boost::detail::sp_assert_convertible< Y[N], E[N] >(); @@ -106,7 +66,7 @@ template< class E, std::size_t N, class Y > inline void lsp_pointer_construct( b pn = pd; } -template< class E, class P, class D > inline void lsp_deleter_construct( boost::local_shared_ptr< E > * ppx, P p, D const& d, boost::detail::local_counted_base * & pn ) +template< class E, class P, class D > inline void lsp_deleter_construct( boost::local_shared_ptr< E > * /*ppx*/, P p, D const& d, boost::detail::local_counted_base * & pn ) { typedef boost::detail::local_sp_deleter D2; @@ -119,7 +79,7 @@ template< class E, class P, class D > inline void lsp_deleter_construct( boost:: pn = pd; } -template< class E, class P, class D, class A > inline void lsp_allocator_construct( boost::local_shared_ptr< E > * ppx, P p, D const& d, A const& a, boost::detail::local_counted_base * & pn ) +template< class E, class P, class D, class A > inline void lsp_allocator_construct( boost::local_shared_ptr< E > * /*ppx*/, P p, D const& d, A const& a, boost::detail::local_counted_base * & pn ) { typedef boost::detail::local_sp_deleter D2; @@ -702,6 +662,13 @@ template std::basic_ostream & operator<< ( std: #endif // !defined(BOOST_NO_IOSTREAM) +// get_deleter + +template D * get_deleter( local_shared_ptr const & p ) BOOST_SP_NOEXCEPT +{ + return get_deleter( shared_ptr( p ) ); +} + // hash_value template< class T > struct hash; diff --git a/include/boost/smart_ptr/make_local_shared_object.hpp b/include/boost/smart_ptr/make_local_shared_object.hpp index 4d76e29..46426b5 100644 --- a/include/boost/smart_ptr/make_local_shared_object.hpp +++ b/include/boost/smart_ptr/make_local_shared_object.hpp @@ -12,7 +12,6 @@ // See http://www.boost.org/libs/smart_ptr/ for documentation. #include -#include #include #include #include diff --git a/include/boost/smart_ptr/shared_ptr.hpp b/include/boost/smart_ptr/shared_ptr.hpp index c87901a..a735062 100644 --- a/include/boost/smart_ptr/shared_ptr.hpp +++ b/include/boost/smart_ptr/shared_ptr.hpp @@ -766,6 +766,11 @@ public: return pn.get_deleter( ti ); } + void * _internal_get_local_deleter( boost::detail::sp_typeinfo const & ti ) const BOOST_SP_NOEXCEPT + { + return pn.get_local_deleter( ti ); + } + void * _internal_get_untyped_deleter() const BOOST_SP_NOEXCEPT { return pn.get_untyped_deleter(); @@ -980,27 +985,13 @@ template std::basic_ostream & operator<< (std:: namespace detail { -#if ( defined(__GNUC__) && BOOST_WORKAROUND(__GNUC__, < 3) ) || \ - ( defined(__EDG_VERSION__) && BOOST_WORKAROUND(__EDG_VERSION__, <= 238) ) || \ - ( defined(__HP_aCC) && BOOST_WORKAROUND(__HP_aCC, <= 33500) ) - -// g++ 2.9x doesn't allow static_cast(void *) -// apparently EDG 2.38 and HP aCC A.03.35 also don't accept it - -template D * basic_get_deleter(shared_ptr const & p) -{ - void const * q = p._internal_get_deleter(BOOST_SP_TYPEID(D)); - return const_cast(static_cast(q)); -} - -#else - template D * basic_get_deleter( shared_ptr const & p ) BOOST_SP_NOEXCEPT { return static_cast( p._internal_get_deleter(BOOST_SP_TYPEID(D)) ); } -#endif +template D * basic_get_local_deleter( D *, shared_ptr const & p ) BOOST_SP_NOEXCEPT; +template D const * basic_get_local_deleter( D const *, shared_ptr const & p ) BOOST_SP_NOEXCEPT; class esft2_deleter_wrapper { @@ -1035,17 +1026,22 @@ public: template D * get_deleter( shared_ptr const & p ) BOOST_SP_NOEXCEPT { - D *del = boost::detail::basic_get_deleter(p); + D * d = boost::detail::basic_get_deleter( p ); - if(del == 0) + if( d == 0 ) + { + d = boost::detail::basic_get_local_deleter( d, p ); + } + + if( d == 0 ) { boost::detail::esft2_deleter_wrapper *del_wrapper = boost::detail::basic_get_deleter(p); // The following get_deleter method call is fully qualified because // older versions of gcc (2.95, 3.2.3) fail to compile it when written del_wrapper->get_deleter() - if(del_wrapper) del = del_wrapper->::boost::detail::esft2_deleter_wrapper::get_deleter(); + if(del_wrapper) d = del_wrapper->::boost::detail::esft2_deleter_wrapper::get_deleter(); } - return del; + return d; } // atomic access @@ -1138,6 +1134,28 @@ template< class T > std::size_t hash_value( boost::shared_ptr const & p ) BOO } // namespace boost +#include + +namespace boost +{ + +namespace detail +{ + +template D * basic_get_local_deleter( D *, shared_ptr const & p ) BOOST_SP_NOEXCEPT +{ + return static_cast( p._internal_get_local_deleter( BOOST_SP_TYPEID(local_sp_deleter) ) ); +} + +template D const * basic_get_local_deleter( D const *, shared_ptr const & p ) BOOST_SP_NOEXCEPT +{ + return static_cast( p._internal_get_local_deleter( BOOST_SP_TYPEID(local_sp_deleter) ) ); +} + +} // namespace detail + +} // namespace boost + #if defined( BOOST_SP_DISABLE_DEPRECATED ) #pragma GCC diagnostic pop #endif diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index 2c95d3b..89da83e 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -225,7 +225,10 @@ import testing ; [ run lsp_array_n_test.cpp ] [ run lsp_array_cv_test.cpp ] [ run lsp_array_cast_test.cpp ] - + + [ run get_local_deleter_test.cpp ] + [ run get_local_deleter_test2.cpp ] + [ run make_local_shared_test.cpp ] [ run make_local_shared_esft_test.cpp ] [ run allocate_local_shared_test.cpp ] diff --git a/test/get_local_deleter_test.cpp b/test/get_local_deleter_test.cpp new file mode 100644 index 0000000..8c45af7 --- /dev/null +++ b/test/get_local_deleter_test.cpp @@ -0,0 +1,95 @@ +// +// get_local_deleter_test.cpp +// +// Copyright 2002, 2017 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 deleter +{ + int data; + + deleter(): data(0) + { + } + + void operator()(void *) + { + BOOST_TEST(data == 17041); + } +}; + +struct deleter2 +{ +}; + +struct X +{ +}; + +int main() +{ + { + boost::local_shared_ptr p; + + BOOST_TEST(boost::get_deleter(p) == 0); + BOOST_TEST(boost::get_deleter(p) == 0); + BOOST_TEST(boost::get_deleter(p) == 0); + BOOST_TEST(boost::get_deleter(p) == 0); + BOOST_TEST(boost::get_deleter(p) == 0); + BOOST_TEST(boost::get_deleter(p) == 0); + BOOST_TEST(boost::get_deleter(p) == 0); + BOOST_TEST(boost::get_deleter(p) == 0); + BOOST_TEST(boost::get_deleter(p) == 0); + BOOST_TEST(boost::get_deleter(p) == 0); + } + + { + boost::local_shared_ptr p(new X); + + BOOST_TEST(boost::get_deleter(p) == 0); + BOOST_TEST(boost::get_deleter(p) == 0); + BOOST_TEST(boost::get_deleter(p) == 0); + BOOST_TEST(boost::get_deleter(p) == 0); + BOOST_TEST(boost::get_deleter(p) == 0); + BOOST_TEST(boost::get_deleter(p) == 0); + BOOST_TEST(boost::get_deleter(p) == 0); + BOOST_TEST(boost::get_deleter(p) == 0); + BOOST_TEST(boost::get_deleter(p) == 0); + BOOST_TEST(boost::get_deleter(p) == 0); + } + + { + X x; + boost::local_shared_ptr p(&x, deleter()); + + BOOST_TEST(boost::get_deleter(p) == 0); + BOOST_TEST(boost::get_deleter(p) == 0); + BOOST_TEST(boost::get_deleter(p) == 0); + BOOST_TEST(boost::get_deleter(p) == 0); + BOOST_TEST(boost::get_deleter(p) == 0); + BOOST_TEST(boost::get_deleter(p) == 0); + BOOST_TEST(boost::get_deleter(p) == 0); + BOOST_TEST(boost::get_deleter(p) == 0); + + deleter * q = boost::get_deleter(p); + + BOOST_TEST(q != 0); + BOOST_TEST(q->data == 0); + + q->data = 17041; + + deleter const * r = boost::get_deleter(p); + + BOOST_TEST(r == q); + BOOST_TEST(r->data == 17041); + } + + return boost::report_errors(); +} diff --git a/test/get_local_deleter_test2.cpp b/test/get_local_deleter_test2.cpp new file mode 100644 index 0000000..a0023a9 --- /dev/null +++ b/test/get_local_deleter_test2.cpp @@ -0,0 +1,43 @@ +// +// get_local_deleter_test2.cpp +// +// Copyright 2017 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 deleter; + +struct X +{ +}; + +static void test_lsp_get_deleter( boost::local_shared_ptr const & p ) +{ + BOOST_TEST( boost::get_deleter( p ) != 0 ); +} + +static void test_sp_get_deleter( boost::shared_ptr const & p ) +{ + BOOST_TEST( boost::get_deleter( p ) != 0 ); +} + +struct deleter +{ + void operator()( X const * p ) { delete p; } +}; + +int main() +{ + boost::local_shared_ptr p( new X, deleter() ); + + test_lsp_get_deleter( p ); + test_sp_get_deleter( p ); + + return boost::report_errors(); +}