shared_from_raw_test.cpp 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. //
  2. // shared_from_raw_test - based on shared_from_this_test
  3. //
  4. // Copyright (c) 2002, 2003, 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. #if defined(__GNUC__) && __GNUC__ > 4
  12. # pragma GCC diagnostic ignored "-Wdelete-non-virtual-dtor"
  13. #endif
  14. #include <boost/smart_ptr/enable_shared_from_raw.hpp>
  15. #include <boost/shared_ptr.hpp>
  16. #include <boost/detail/lightweight_test.hpp>
  17. //
  18. class X
  19. {
  20. public:
  21. virtual void f() = 0;
  22. protected:
  23. ~X() {}
  24. };
  25. class Y
  26. {
  27. public:
  28. virtual boost::shared_ptr<X> getX() = 0;
  29. protected:
  30. ~Y() {}
  31. };
  32. boost::shared_ptr<Y> createY();
  33. void test()
  34. {
  35. boost::shared_ptr<Y> py = createY();
  36. BOOST_TEST(py.get() != 0);
  37. BOOST_TEST(py.use_count() == 1);
  38. try
  39. {
  40. boost::shared_ptr<X> px = py->getX();
  41. BOOST_TEST(px.get() != 0);
  42. BOOST_TEST(py.use_count() == 2);
  43. px->f();
  44. #if !defined( BOOST_NO_RTTI )
  45. boost::shared_ptr<Y> py2 = boost::dynamic_pointer_cast<Y>(px);
  46. BOOST_TEST(py.get() == py2.get());
  47. BOOST_TEST(!(py < py2 || py2 < py));
  48. BOOST_TEST(py.use_count() == 3);
  49. #endif
  50. }
  51. catch( boost::bad_weak_ptr const& )
  52. {
  53. BOOST_ERROR( "py->getX() failed" );
  54. }
  55. }
  56. void test2();
  57. void test3();
  58. int main()
  59. {
  60. test();
  61. test2();
  62. test3();
  63. return boost::report_errors();
  64. }
  65. // virtual inheritance to stress the implementation
  66. // (prevents Y* -> impl*, enable_shared_from_raw* -> impl* casts)
  67. class impl: public X, public virtual Y, public virtual boost::enable_shared_from_raw
  68. {
  69. public:
  70. virtual void f()
  71. {
  72. }
  73. virtual boost::shared_ptr<X> getX()
  74. {
  75. boost::shared_ptr<impl> pi = boost::shared_from_raw( this );
  76. BOOST_TEST( pi.get() == this );
  77. return pi;
  78. }
  79. };
  80. // intermediate impl2 to stress the implementation
  81. class impl2: public impl
  82. {
  83. };
  84. boost::shared_ptr<Y> createY()
  85. {
  86. boost::shared_ptr<Y> pi(new impl2);
  87. return pi;
  88. }
  89. void test2()
  90. {
  91. boost::shared_ptr<Y> pi(static_cast<impl2*>(0));
  92. }
  93. //
  94. struct V: public boost::enable_shared_from_raw
  95. {
  96. };
  97. void test3()
  98. {
  99. boost::shared_ptr<V> p( new V );
  100. try
  101. {
  102. boost::shared_ptr<V> q = boost::shared_from_raw( p.get() );
  103. BOOST_TEST( p == q );
  104. BOOST_TEST( !(p < q) && !(q < p) );
  105. }
  106. catch( boost::bad_weak_ptr const & )
  107. {
  108. BOOST_ERROR( "shared_from_this( p.get() ) failed" );
  109. }
  110. V v2( *p );
  111. try
  112. {
  113. // shared_from_raw differs from shared_from_this;
  114. // it will not throw here and will create a shared_ptr
  115. boost::shared_ptr<V> r = boost::shared_from_raw( &v2 );
  116. // check if the shared_ptr is correct and that it does
  117. // not share ownership with p
  118. BOOST_TEST( r.get() == &v2 );
  119. BOOST_TEST( p != r );
  120. BOOST_TEST( (p < r) || (r < p) );
  121. }
  122. catch( boost::bad_weak_ptr const & )
  123. {
  124. BOOST_ERROR("shared_from_raw( &v2 ) failed");
  125. }
  126. try
  127. {
  128. *p = V();
  129. boost::shared_ptr<V> r = boost::shared_from_raw( p.get() );
  130. BOOST_TEST( p == r );
  131. BOOST_TEST( !(p < r) && !(r < p) );
  132. }
  133. catch( boost::bad_weak_ptr const & )
  134. {
  135. BOOST_ERROR("shared_from_raw( p.get() ) threw bad_weak_ptr after *p = V()");
  136. }
  137. }