--- shared_ptr.hpp.orig 2016-11-12 13:46:50.000000000 -0500 +++ shared_ptr.hpp 2018-12-19 10:33:00.022538689 -0500 @@ -53,6 +53,13 @@ #pragma GCC diagnostic ignored "-Wdeprecated-declarations" #endif +#ifdef BOOST_SP_ENABLE_DEBUG_HOOKS +void boost_debug_shared_ptr_operator_equals (void const *, void const *, int, void const*, int); +void boost_debug_shared_ptr_reset (void const *, void const *, int, void const*, int); +void boost_debug_shared_ptr_destructor (void const *, volatile void const *, int); +void boost_debug_shared_ptr_constructor (void const *, volatile void const *, int); +#endif + namespace boost { @@ -283,20 +290,29 @@ { boost::detail::shared_count( p ).swap( pn ); boost::detail::sp_enable_shared_from_this( ppx, p, p ); +#ifdef BOOST_SP_ENABLE_DEBUG_HOOKS + boost_debug_shared_ptr_constructor (ppx, ppx->get(), ppx->use_count()); +#endif } #if !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION ) -template< class T, class Y > inline void sp_pointer_construct( boost::shared_ptr< T[] > * /*ppx*/, Y * p, boost::detail::shared_count & pn ) +template< class T, class Y > inline void sp_pointer_construct( boost::shared_ptr< T[] > * ppx, Y * p, boost::detail::shared_count & pn ) { sp_assert_convertible< Y[], T[] >(); boost::detail::shared_count( p, boost::checked_array_deleter< T >() ).swap( pn ); +#ifdef BOOST_SP_ENABLE_DEBUG_HOOKS + /* no code for this yet - shared_ptr to array of T */ +#endif } template< class T, std::size_t N, class Y > inline void sp_pointer_construct( boost::shared_ptr< T[N] > * /*ppx*/, Y * p, boost::detail::shared_count & pn ) { sp_assert_convertible< Y[N], T[N] >(); boost::detail::shared_count( p, boost::checked_array_deleter< T >() ).swap( pn ); +#ifdef BOOST_SP_ENABLE_DEBUG_HOOKS + /* no code for this yet - shared_ptr to array of T */ +#endif } #endif // !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION ) @@ -306,6 +322,9 @@ template< class T, class Y > inline void sp_deleter_construct( boost::shared_ptr< T > * ppx, Y * p ) { boost::detail::sp_enable_shared_from_this( ppx, p, p ); +#ifdef BOOST_SP_ENABLE_DEBUG_HOOKS + boost_debug_shared_ptr_constructor (ppx, ppx->get(), ppx->use_count()); +#endif } #if !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION ) @@ -313,11 +332,17 @@ template< class T, class Y > inline void sp_deleter_construct( boost::shared_ptr< T[] > * /*ppx*/, Y * /*p*/ ) { sp_assert_convertible< Y[], T[] >(); +#ifdef BOOST_SP_ENABLE_DEBUG_HOOKS + /* no code for this yet - shared_ptr to array of T */ +#endif } template< class T, std::size_t N, class Y > inline void sp_deleter_construct( boost::shared_ptr< T[N] > * /*ppx*/, Y * /*p*/ ) { sp_assert_convertible< Y[N], T[N] >(); +#ifdef BOOST_SP_ENABLE_DEBUG_HOOKS + /* no code for this yet - shared_ptr to array of T */ +#endif } #endif // !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION ) @@ -346,12 +371,20 @@ shared_ptr() BOOST_NOEXCEPT : px( 0 ), pn() // never throws in 1.30+ { +#ifdef BOOST_SP_ENABLE_DEBUG_HOOKS + /* default constructor case */ + boost_debug_shared_ptr_constructor (this, px, use_count()); +#endif } #if !defined( BOOST_NO_CXX11_NULLPTR ) shared_ptr( boost::detail::sp_nullptr_t ) BOOST_NOEXCEPT : px( 0 ), pn() // never throws { +#ifdef BOOST_SP_ENABLE_DEBUG_HOOKS + /* explicit nullptr constructor case */ + boost_debug_shared_ptr_constructor (this, px, use_count()); +#endif } #endif @@ -392,11 +425,20 @@ template shared_ptr( boost::detail::sp_nullptr_t p, D d, A a ): px( p ), pn( p, d, a ) { +#ifdef BOOST_SP_ENABLE_DEBUG_HOOKS + boost_debug_shared_ptr_constructor (this, px, use_count()); +#endif } #endif +#ifdef BOOST_SP_ENABLE_DEBUG_HOOKS + ~shared_ptr() { + boost_debug_shared_ptr_destructor (this, get(), use_count()); + } +#else // generated copy constructor, destructor are fine... +#endif /* BOOST_SP_ENABLE_DEBUG_HOOKS */ #if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES ) @@ -404,6 +446,9 @@ shared_ptr( shared_ptr const & r ) BOOST_NOEXCEPT : px( r.px ), pn( r.pn ) { +#ifdef BOOST_SP_ENABLE_DEBUG_HOOKS + boost_debug_shared_ptr_operator_equals (this, get(), use_count(), r.get(), r.use_count()); +#endif } #endif @@ -413,6 +458,9 @@ { boost::detail::sp_assert_convertible< Y, T >(); +#ifdef BOOST_SP_ENABLE_DEBUG_HOOKS + boost_debug_shared_ptr_operator_equals (this, get(), use_count(), r.px, -1); +#endif // it is now safe to copy r.px, as pn(r.pn) did not throw px = r.px; } @@ -423,6 +471,9 @@ { if( !pn.empty() ) { +#ifdef BOOST_SP_ENABLE_DEBUG_HOOKS + boost_debug_shared_ptr_operator_equals (this, get(), use_count(), r.px, -1); +#endif px = r.px; } } @@ -440,6 +491,9 @@ BOOST_NOEXCEPT : px( r.px ), pn( r.pn ) { boost::detail::sp_assert_convertible< Y, T >(); +#ifdef BOOST_SP_ENABLE_DEBUG_HOOKS + boost_debug_shared_ptr_operator_equals (this, get(), use_count(), r.get(), r.use_count()); +#endif } // aliasing @@ -532,6 +586,9 @@ template shared_ptr & operator=(shared_ptr const & r) BOOST_NOEXCEPT { +#ifdef BOOST_SP_ENABLE_DEBUG_HOOKS + boost_debug_shared_ptr_operator_equals (this, get(), use_count(), r.get(), r.use_count()); +#endif this_type(r).swap(*this); return *this; } @@ -543,6 +600,9 @@ template shared_ptr & operator=( std::auto_ptr & r ) { +#ifdef BOOST_SP_ENABLE_DEBUG_HOOKS + boost_debug_shared_ptr_operator_equals (this, get(), use_count(), r.get(), r.use_count()); +#endif this_type( r ).swap( *this ); return *this; } @@ -552,6 +612,9 @@ template shared_ptr & operator=( std::auto_ptr && r ) { +#ifdef BOOST_SP_ENABLE_DEBUG_HOOKS + boost_debug_shared_ptr_operator_equals (this, get(), use_count(), r.get(), r.use_count()); +#endif this_type( static_cast< std::auto_ptr && >( r ) ).swap( *this ); return *this; } @@ -574,6 +637,9 @@ template shared_ptr & operator=( std::unique_ptr && r ) { +#ifdef BOOST_SP_ENABLE_DEBUG_HOOKS + boost_debug_shared_ptr_operator_equals (this, get(), use_count(), r.get(), r.use_count()); +#endif this_type( static_cast< std::unique_ptr && >( r ) ).swap(*this); return *this; } @@ -607,6 +673,9 @@ shared_ptr( shared_ptr && r ) BOOST_NOEXCEPT : px( r.px ), pn() { +#ifdef BOOST_SP_ENABLE_DEBUG_HOOKS + boost_debug_shared_ptr_operator_equals (this, get(), use_count(), r.get(), r.use_count()); +#endif pn.swap( r.pn ); r.px = 0; } @@ -625,12 +694,18 @@ { boost::detail::sp_assert_convertible< Y, T >(); +#ifdef BOOST_SP_ENABLE_DEBUG_HOOKS + boost_debug_shared_ptr_operator_equals (this, get(), use_count(), r.get(), r.use_count()); +#endif pn.swap( r.pn ); r.px = 0; } shared_ptr & operator=( shared_ptr && r ) BOOST_NOEXCEPT { +#ifdef BOOST_SP_ENABLE_DEBUG_HOOKS + boost_debug_shared_ptr_operator_equals (this, get(), use_count(), r.get(), r.use_count()); +#endif this_type( static_cast< shared_ptr && >( r ) ).swap( *this ); return *this; } @@ -638,6 +713,9 @@ template shared_ptr & operator=( shared_ptr && r ) BOOST_NOEXCEPT { +#ifdef BOOST_SP_ENABLE_DEBUG_HOOKS + boost_debug_shared_ptr_operator_equals (this, get(), use_count(), r.get(), r.use_count()); +#endif this_type( static_cast< shared_ptr && >( r ) ).swap( *this ); return *this; } @@ -656,6 +734,9 @@ shared_ptr & operator=( boost::detail::sp_nullptr_t ) BOOST_NOEXCEPT // never throws { +#ifdef BOOST_SP_ENABLE_DEBUG_HOOKS + boost_debug_shared_ptr_operator_reset (this, get(), use_count(), 0, 0); +#endif this_type().swap(*this); return *this; } @@ -664,27 +745,42 @@ void reset() BOOST_NOEXCEPT // never throws in 1.30+ { +#ifdef BOOST_SP_ENABLE_DEBUG_HOOKS + boost_debug_shared_ptr_reset (this, get(), use_count(), 0, 0); +#endif this_type().swap(*this); } template void reset( Y * p ) // Y must be complete { BOOST_ASSERT( p == 0 || p != px ); // catch self-reset errors +#ifdef BOOST_SP_ENABLE_DEBUG_HOOKS + boost_debug_shared_ptr_reset (this, get(), use_count(), p, 0); +#endif this_type( p ).swap( *this ); } template void reset( Y * p, D d ) { +#ifdef BOOST_SP_ENABLE_DEBUG_HOOKS + boost_debug_shared_ptr_reset (this, get(), use_count(), p, 0); +#endif this_type( p, d ).swap( *this ); } template void reset( Y * p, D d, A a ) { +#ifdef BOOST_SP_ENABLE_DEBUG_HOOKS + boost_debug_shared_ptr_reset (this, get(), use_count(), p, 0); +#endif this_type( p, d, a ).swap( *this ); } template void reset( shared_ptr const & r, element_type * p ) { +#ifdef BOOST_SP_ENABLE_DEBUG_HOOKS + boost_debug_shared_ptr_reset (this, get(), use_count(), p, 0); +#endif this_type( r, p ).swap( *this ); }