esft_regtest.cpp 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226
  1. //
  2. // esft_regtest.cpp
  3. //
  4. // A regression test for enable_shared_from_this
  5. //
  6. // Copyright (c) 2008 Peter Dimov
  7. //
  8. // Distributed under the Boost Software License, Version 1.0.
  9. //
  10. // See accompanying file LICENSE_1_0.txt or copy at
  11. // http://www.boost.org/LICENSE_1_0.txt)
  12. //
  13. #include <boost/enable_shared_from_this.hpp>
  14. #include <boost/shared_ptr.hpp>
  15. #include <boost/weak_ptr.hpp>
  16. #include <boost/detail/lightweight_test.hpp>
  17. #include <boost/config.hpp>
  18. #include <memory>
  19. #include <string>
  20. class X: public boost::enable_shared_from_this< X >
  21. {
  22. private:
  23. int destroyed_;
  24. int deleted_;
  25. int expected_;
  26. private:
  27. X( X const& );
  28. X& operator=( X const& );
  29. public:
  30. static int instances;
  31. public:
  32. explicit X( int expected ): destroyed_( 0 ), deleted_( 0 ), expected_( expected )
  33. {
  34. ++instances;
  35. }
  36. ~X()
  37. {
  38. BOOST_TEST( deleted_ == expected_ );
  39. BOOST_TEST( destroyed_ == 0 );
  40. ++destroyed_;
  41. --instances;
  42. }
  43. typedef void (*deleter_type)( X* );
  44. static void deleter( X * px )
  45. {
  46. ++px->deleted_;
  47. }
  48. static void deleter2( X * px )
  49. {
  50. ++px->deleted_;
  51. delete px;
  52. }
  53. };
  54. int X::instances = 0;
  55. void test()
  56. {
  57. BOOST_TEST( X::instances == 0 );
  58. {
  59. X x( 0 );
  60. BOOST_TEST( X::instances == 1 );
  61. }
  62. BOOST_TEST( X::instances == 0 );
  63. #if !defined( BOOST_NO_AUTO_PTR )
  64. {
  65. std::auto_ptr<X> px( new X( 0 ) );
  66. BOOST_TEST( X::instances == 1 );
  67. }
  68. #endif
  69. BOOST_TEST( X::instances == 0 );
  70. {
  71. boost::shared_ptr<X> px( new X( 0 ) );
  72. BOOST_TEST( X::instances == 1 );
  73. boost::weak_ptr<X> wp( px );
  74. BOOST_TEST( !wp.expired() );
  75. px.reset();
  76. BOOST_TEST( wp.expired() );
  77. }
  78. BOOST_TEST( X::instances == 0 );
  79. {
  80. X x( 1 );
  81. boost::shared_ptr<X> px( &x, X::deleter );
  82. BOOST_TEST( X::instances == 1 );
  83. X::deleter_type * pd = boost::get_deleter<X::deleter_type>( px );
  84. BOOST_TEST( pd != 0 && *pd == X::deleter );
  85. boost::weak_ptr<X> wp( px );
  86. BOOST_TEST( !wp.expired() );
  87. px.reset();
  88. BOOST_TEST( wp.expired() );
  89. }
  90. BOOST_TEST( X::instances == 0 );
  91. {
  92. boost::shared_ptr<X> px( new X( 1 ), X::deleter2 );
  93. BOOST_TEST( X::instances == 1 );
  94. X::deleter_type * pd = boost::get_deleter<X::deleter_type>( px );
  95. BOOST_TEST( pd != 0 && *pd == X::deleter2 );
  96. boost::weak_ptr<X> wp( px );
  97. BOOST_TEST( !wp.expired() );
  98. px.reset();
  99. BOOST_TEST( wp.expired() );
  100. }
  101. BOOST_TEST( X::instances == 0 );
  102. }
  103. struct V: public boost::enable_shared_from_this<V>
  104. {
  105. virtual ~V() {}
  106. std::string m_;
  107. };
  108. struct V2
  109. {
  110. virtual ~V2() {}
  111. std::string m2_;
  112. };
  113. struct W: V2, V
  114. {
  115. };
  116. void test2()
  117. {
  118. boost::shared_ptr<W> p( new W );
  119. }
  120. void test3()
  121. {
  122. V * p = new W;
  123. boost::shared_ptr<void> pv( p );
  124. BOOST_TEST( pv.get() == p );
  125. BOOST_TEST( pv.use_count() == 1 );
  126. }
  127. struct null_deleter
  128. {
  129. void operator()( void const* ) const {}
  130. };
  131. void test4()
  132. {
  133. boost::shared_ptr<V> pv( new V );
  134. boost::shared_ptr<V> pv2( pv.get(), null_deleter() );
  135. BOOST_TEST( pv2.get() == pv.get() );
  136. BOOST_TEST( pv2.use_count() == 1 );
  137. }
  138. void test5()
  139. {
  140. V v;
  141. boost::shared_ptr<V> p1( &v, null_deleter() );
  142. BOOST_TEST( p1.get() == &v );
  143. BOOST_TEST( p1.use_count() == 1 );
  144. try
  145. {
  146. p1->shared_from_this();
  147. }
  148. catch( ... )
  149. {
  150. BOOST_ERROR( "p1->shared_from_this() failed" );
  151. }
  152. p1.reset();
  153. boost::shared_ptr<V> p2( &v, null_deleter() );
  154. BOOST_TEST( p2.get() == &v );
  155. BOOST_TEST( p2.use_count() == 1 );
  156. try
  157. {
  158. p2->shared_from_this();
  159. }
  160. catch( ... )
  161. {
  162. BOOST_ERROR( "p2->shared_from_this() failed" );
  163. }
  164. }
  165. int main()
  166. {
  167. test();
  168. test2();
  169. test3();
  170. test4();
  171. test5();
  172. return boost::report_errors();
  173. }