shared_ptr_alloc2_test.cpp 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224
  1. #include <boost/config.hpp>
  2. // shared_ptr_alloc2_test.cpp
  3. //
  4. // Copyright (c) 2005 Peter Dimov
  5. //
  6. // Distributed under the Boost Software License, Version 1.0. (See
  7. // accompanying file LICENSE_1_0.txt or copy at
  8. // http://www.boost.org/LICENSE_1_0.txt)
  9. #include <boost/detail/lightweight_test.hpp>
  10. #include <boost/shared_ptr.hpp>
  11. #include <memory>
  12. #include <cstddef>
  13. // test_allocator
  14. struct test_allocator_base
  15. {
  16. int id_;
  17. static int last_global_id_;
  18. static int count_;
  19. explicit test_allocator_base( int id ): id_( id )
  20. {
  21. }
  22. };
  23. int test_allocator_base::last_global_id_ = 0;
  24. int test_allocator_base::count_ = 0;
  25. template<class T> class test_allocator: public test_allocator_base
  26. {
  27. public:
  28. typedef T * pointer;
  29. typedef T const * const_pointer;
  30. typedef T & reference;
  31. typedef T const & const_reference;
  32. typedef T value_type;
  33. typedef std::size_t size_type;
  34. typedef std::ptrdiff_t difference_type;
  35. private:
  36. static T * last_pointer_;
  37. static std::size_t last_n_;
  38. static int last_id_;
  39. public:
  40. template<class U> struct rebind
  41. {
  42. typedef test_allocator<U> other;
  43. };
  44. pointer address( reference r ) const
  45. {
  46. return &r;
  47. }
  48. const_pointer address( const_reference s ) const
  49. {
  50. return &s;
  51. }
  52. explicit test_allocator( int id = 0 ): test_allocator_base( id )
  53. {
  54. }
  55. template<class U> test_allocator( test_allocator<U> const & r ): test_allocator_base( r )
  56. {
  57. }
  58. template<class U> test_allocator & operator=( test_allocator<U> const & r )
  59. {
  60. test_allocator_base::operator=( r );
  61. return *this;
  62. }
  63. void deallocate( pointer p, size_type n )
  64. {
  65. BOOST_TEST( p == last_pointer_ );
  66. BOOST_TEST( n == last_n_ );
  67. BOOST_TEST( id_ == last_id_ );
  68. --count_;
  69. ::operator delete( p );
  70. }
  71. pointer allocate( size_type n, void const * = 0 )
  72. {
  73. T * p = static_cast< T* >( ::operator new( n * sizeof( T ) ) );
  74. last_pointer_ = p;
  75. last_n_ = n;
  76. last_id_ = id_;
  77. last_global_id_ = id_;
  78. ++count_;
  79. return p;
  80. }
  81. void construct( pointer p, T const & t )
  82. {
  83. ::new( p ) T( t );
  84. }
  85. void destroy( pointer p )
  86. {
  87. p->~T();
  88. }
  89. size_type max_size() const
  90. {
  91. return size_type( -1 ) / sizeof( T );
  92. }
  93. };
  94. template<class T> T * test_allocator<T>::last_pointer_ = 0;
  95. template<class T> std::size_t test_allocator<T>::last_n_ = 0;
  96. template<class T> int test_allocator<T>::last_id_ = 0;
  97. template<class T, class U> inline bool operator==( test_allocator<T> const & a1, test_allocator<U> const & a2 )
  98. {
  99. return a1.id_ == a2.id_;
  100. }
  101. template<class T, class U> inline bool operator!=( test_allocator<T> const & a1, test_allocator<U> const & a2 )
  102. {
  103. return a1.id_ != a2.id_;
  104. }
  105. template<> class test_allocator<void>: public test_allocator_base
  106. {
  107. public:
  108. typedef void * pointer;
  109. typedef void const * const_pointer;
  110. typedef void value_type;
  111. template<class U> struct rebind
  112. {
  113. typedef test_allocator<U> other;
  114. };
  115. explicit test_allocator( int id = 0 ): test_allocator_base( id )
  116. {
  117. }
  118. template<class U> test_allocator( test_allocator<U> const & r ): test_allocator_base( r )
  119. {
  120. }
  121. template<class U> test_allocator & operator=( test_allocator<U> const & r )
  122. {
  123. test_allocator_base::operator=( r );
  124. return *this;
  125. }
  126. };
  127. //
  128. struct X
  129. {
  130. static int instances;
  131. X()
  132. {
  133. ++instances;
  134. }
  135. ~X()
  136. {
  137. --instances;
  138. }
  139. private:
  140. X( X const & );
  141. X & operator=( X const & );
  142. };
  143. int X::instances = 0;
  144. int main()
  145. {
  146. BOOST_TEST( X::instances == 0 );
  147. boost::shared_ptr<void> pv( new X, boost::checked_deleter<X>(), std::allocator<X>() );
  148. BOOST_TEST( X::instances == 1 );
  149. pv.reset( new X, boost::checked_deleter<X>(), test_allocator<float>( 42 ) );
  150. BOOST_TEST( X::instances == 1 );
  151. BOOST_TEST( test_allocator_base::last_global_id_ == 42 );
  152. BOOST_TEST( test_allocator_base::count_ > 0 );
  153. pv.reset();
  154. BOOST_TEST( X::instances == 0 );
  155. BOOST_TEST( test_allocator_base::count_ == 0 );
  156. pv.reset( new X, boost::checked_deleter<X>(), test_allocator<void>( 43 ) );
  157. BOOST_TEST( X::instances == 1 );
  158. BOOST_TEST( test_allocator_base::last_global_id_ == 43 );
  159. pv.reset( new X, boost::checked_deleter<X>(), std::allocator<void>() );
  160. BOOST_TEST( X::instances == 1 );
  161. pv.reset();
  162. BOOST_TEST( X::instances == 0 );
  163. return boost::report_errors();
  164. }