1 #include <boost/config.hpp> 2 3 #if defined(BOOST_MSVC) 4 #pragma warning(disable: 4786) // identifier truncated in debug info 5 #pragma warning(disable: 4710) // function not inlined 6 #pragma warning(disable: 4711) // function selected for automatic inline expansion 7 #pragma warning(disable: 4514) // unreferenced inline removed 8 #endif 9 10 #if defined(__GNUC__) && __GNUC__ > 4 11 # pragma GCC diagnostic ignored "-Wdelete-non-virtual-dtor" 12 #endif 13 14 // 15 // shared_from_this_test.cpp 16 // 17 // Copyright (c) 2002, 2003 Peter Dimov 18 // 19 // Distributed under the Boost Software License, Version 1.0. (See 20 // accompanying file LICENSE_1_0.txt or copy at 21 // http://www.boost.org/LICENSE_1_0.txt) 22 // 23 24 25 #include <boost/enable_shared_from_this.hpp> 26 #include <boost/shared_ptr.hpp> 27 28 #include <boost/detail/lightweight_test.hpp> 29 30 // 31 32 class X 33 { 34 public: 35 36 virtual void f() = 0; 37 38 protected: 39 ~X()40 ~X() {} 41 }; 42 43 class Y 44 { 45 public: 46 47 virtual boost::shared_ptr<X> getX() = 0; 48 49 protected: 50 ~Y()51 ~Y() {} 52 }; 53 54 boost::shared_ptr<Y> createY(); 55 test()56void test() 57 { 58 boost::shared_ptr<Y> py = createY(); 59 BOOST_TEST(py.get() != 0); 60 BOOST_TEST(py.use_count() == 1); 61 62 try 63 { 64 boost::shared_ptr<X> px = py->getX(); 65 BOOST_TEST(px.get() != 0); 66 BOOST_TEST(py.use_count() == 2); 67 68 px->f(); 69 70 #if !defined( BOOST_NO_RTTI ) 71 boost::shared_ptr<Y> py2 = boost::dynamic_pointer_cast<Y>(px); 72 BOOST_TEST(py.get() == py2.get()); 73 BOOST_TEST(!(py < py2 || py2 < py)); 74 BOOST_TEST(py.use_count() == 3); 75 #endif 76 } 77 catch( boost::bad_weak_ptr const& ) 78 { 79 BOOST_ERROR( "py->getX() failed" ); 80 } 81 } 82 83 void test2(); 84 void test3(); 85 main()86int main() 87 { 88 test(); 89 test2(); 90 test3(); 91 return boost::report_errors(); 92 } 93 94 // virtual inheritance to stress the implementation 95 // (prevents Y* -> impl*, enable_shared_from_this<impl>* -> impl* casts) 96 97 class impl: public X, public virtual Y, public virtual boost::enable_shared_from_this<impl> 98 { 99 public: 100 f()101 virtual void f() 102 { 103 } 104 getX()105 virtual boost::shared_ptr<X> getX() 106 { 107 boost::shared_ptr<impl> pi = shared_from_this(); 108 BOOST_TEST(pi.get() == this); 109 return pi; 110 } 111 }; 112 113 // intermediate impl2 to stress the implementation 114 115 class impl2: public impl 116 { 117 }; 118 createY()119boost::shared_ptr<Y> createY() 120 { 121 boost::shared_ptr<Y> pi(new impl2); 122 return pi; 123 } 124 test2()125void test2() 126 { 127 boost::shared_ptr<Y> pi(static_cast<impl2*>(0)); 128 } 129 130 // 131 132 struct V: public boost::enable_shared_from_this<V> 133 { 134 }; 135 test3()136void test3() 137 { 138 boost::shared_ptr<V> p(new V); 139 140 try 141 { 142 boost::shared_ptr<V> q = p->shared_from_this(); 143 BOOST_TEST(p == q); 144 BOOST_TEST(!(p < q) && !(q < p)); 145 } 146 catch( boost::bad_weak_ptr const & ) 147 { 148 BOOST_ERROR( "p->shared_from_this() failed" ); 149 } 150 151 V v2(*p); 152 153 try 154 { 155 boost::shared_ptr<V> r = v2.shared_from_this(); 156 BOOST_ERROR("v2.shared_from_this() failed to throw"); 157 } 158 catch( boost::bad_weak_ptr const & ) 159 { 160 } 161 162 try 163 { 164 *p = V(); 165 boost::shared_ptr<V> r = p->shared_from_this(); 166 BOOST_TEST(p == r); 167 BOOST_TEST(!(p < r) && !(r < p)); 168 } 169 catch( boost::bad_weak_ptr const & ) 170 { 171 BOOST_ERROR("p->shared_from_this() threw bad_weak_ptr after *p = V()"); 172 } 173 } 174