shared_from_raw_test2.cpp 3.9 KB

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