#include // shared_ptr_alloc2_test.cpp // // Copyright (c) 2005 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 #include #include // test_allocator struct test_allocator_base { int id_; static int last_global_id_; static int count_; explicit test_allocator_base( int id ): id_( id ) { } }; int test_allocator_base::last_global_id_ = 0; int test_allocator_base::count_ = 0; template class test_allocator: public test_allocator_base { public: typedef T * pointer; typedef T const * const_pointer; typedef T & reference; typedef T const & const_reference; typedef T value_type; typedef std::size_t size_type; typedef std::ptrdiff_t difference_type; private: static T * last_pointer_; static std::size_t last_n_; static int last_id_; public: template struct rebind { typedef test_allocator other; }; pointer address( reference r ) const { return &r; } const_pointer address( const_reference s ) const { return &s; } explicit test_allocator( int id = 0 ): test_allocator_base( id ) { } template test_allocator( test_allocator const & r ): test_allocator_base( r ) { } template test_allocator & operator=( test_allocator const & r ) { test_allocator_base::operator=( r ); return *this; } void deallocate( pointer p, size_type n ) { BOOST_TEST( p == last_pointer_ ); BOOST_TEST( n == last_n_ ); BOOST_TEST( id_ == last_id_ ); --count_; ::operator delete( p ); } pointer allocate( size_type n, void const * = 0 ) { T * p = static_cast< T* >( ::operator new( n * sizeof( T ) ) ); last_pointer_ = p; last_n_ = n; last_id_ = id_; last_global_id_ = id_; ++count_; return p; } void construct( pointer p, T const & t ) { ::new( p ) T( t ); } void destroy( pointer p ) { p->~T(); } size_type max_size() const { return size_type( -1 ) / sizeof( T ); } }; template T * test_allocator::last_pointer_ = 0; template std::size_t test_allocator::last_n_ = 0; template int test_allocator::last_id_ = 0; template inline bool operator==( test_allocator const & a1, test_allocator const & a2 ) { return a1.id_ == a2.id_; } template inline bool operator!=( test_allocator const & a1, test_allocator const & a2 ) { return a1.id_ != a2.id_; } template<> class test_allocator: public test_allocator_base { public: typedef void * pointer; typedef void const * const_pointer; typedef void value_type; template struct rebind { typedef test_allocator other; }; explicit test_allocator( int id = 0 ): test_allocator_base( id ) { } template test_allocator( test_allocator const & r ): test_allocator_base( r ) { } template test_allocator & operator=( test_allocator const & r ) { test_allocator_base::operator=( r ); return *this; } }; // struct X { static int instances; X() { ++instances; } ~X() { --instances; } private: X( X const & ); X & operator=( X const & ); }; int X::instances = 0; int main() { BOOST_TEST( X::instances == 0 ); boost::shared_ptr pv( new X, boost::checked_deleter(), std::allocator() ); BOOST_TEST( X::instances == 1 ); pv.reset( new X, boost::checked_deleter(), test_allocator( 42 ) ); BOOST_TEST( X::instances == 1 ); BOOST_TEST( test_allocator_base::last_global_id_ == 42 ); BOOST_TEST( test_allocator_base::count_ > 0 ); pv.reset(); BOOST_TEST( X::instances == 0 ); BOOST_TEST( test_allocator_base::count_ == 0 ); pv.reset( new X, boost::checked_deleter(), test_allocator( 43 ) ); BOOST_TEST( X::instances == 1 ); BOOST_TEST( test_allocator_base::last_global_id_ == 43 ); pv.reset( new X, boost::checked_deleter(), std::allocator() ); BOOST_TEST( X::instances == 1 ); pv.reset(); BOOST_TEST( X::instances == 0 ); return boost::report_errors(); }