1 #include <boost/config.hpp> 2 3 #if defined(BOOST_MSVC) 4 5 #pragma warning(disable: 4786) // identifier truncated in debug info 6 #pragma warning(disable: 4710) // function not inlined 7 #pragma warning(disable: 4711) // function selected for automatic inline expansion 8 #pragma warning(disable: 4514) // unreferenced inline removed 9 #pragma warning(disable: 4355) // 'this' : used in base member initializer list 10 #pragma warning(disable: 4511) // copy constructor could not be generated 11 #pragma warning(disable: 4512) // assignment operator could not be generated 12 13 #if (BOOST_MSVC >= 1310) 14 #pragma warning(disable: 4675) // resolved overload found with Koenig lookup 15 #endif 16 17 #endif 18 19 // 20 // intrusive_ptr_move_test.cpp 21 // 22 // Copyright (c) 2002-2005 Peter Dimov 23 // 24 // Distributed under the Boost Software License, Version 1.0. (See 25 // accompanying file LICENSE_1_0.txt or copy at 26 // http://www.boost.org/LICENSE_1_0.txt) 27 // 28 29 #include <boost/detail/lightweight_test.hpp> 30 #include <boost/intrusive_ptr.hpp> 31 #include <boost/detail/atomic_count.hpp> 32 #include <boost/config.hpp> 33 #include <utility> 34 35 #if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES ) 36 37 namespace N 38 { 39 40 class base 41 { 42 private: 43 44 mutable boost::detail::atomic_count use_count_; 45 46 base(base const &); 47 base & operator=(base const &); 48 49 protected: 50 base()51 base(): use_count_(0) 52 { 53 ++instances; 54 } 55 ~base()56 virtual ~base() 57 { 58 --instances; 59 } 60 61 public: 62 63 static long instances; 64 use_count() const65 long use_count() const 66 { 67 return use_count_; 68 } 69 70 #if !defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP) 71 intrusive_ptr_add_ref(base const * p)72 inline friend void intrusive_ptr_add_ref(base const * p) 73 { 74 ++p->use_count_; 75 } 76 intrusive_ptr_release(base const * p)77 inline friend void intrusive_ptr_release(base const * p) 78 { 79 if(--p->use_count_ == 0) delete p; 80 } 81 82 #else 83 add_ref() const84 void add_ref() const 85 { 86 ++use_count_; 87 } 88 release() const89 void release() const 90 { 91 if(--use_count_ == 0) delete this; 92 } 93 94 #endif 95 }; 96 97 long base::instances = 0; 98 99 } // namespace N 100 101 #if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP) 102 103 namespace boost 104 { 105 intrusive_ptr_add_ref(N::base const * p)106inline void intrusive_ptr_add_ref(N::base const * p) 107 { 108 p->add_ref(); 109 } 110 intrusive_ptr_release(N::base const * p)111inline void intrusive_ptr_release(N::base const * p) 112 { 113 p->release(); 114 } 115 116 } // namespace boost 117 118 #endif 119 120 // 121 122 struct X: public virtual N::base 123 { 124 }; 125 126 struct Y: public X 127 { 128 }; 129 main()130int main() 131 { 132 BOOST_TEST( N::base::instances == 0 ); 133 134 { 135 boost::intrusive_ptr<X> p( new X ); 136 BOOST_TEST( N::base::instances == 1 ); 137 138 boost::intrusive_ptr<X> p2( std::move( p ) ); 139 BOOST_TEST( N::base::instances == 1 ); 140 BOOST_TEST( p.get() == 0 ); 141 142 p2.reset(); 143 BOOST_TEST( N::base::instances == 0 ); 144 } 145 146 { 147 boost::intrusive_ptr<Y> p( new Y ); 148 BOOST_TEST( N::base::instances == 1 ); 149 150 boost::intrusive_ptr<X> p2( std::move( p ) ); 151 BOOST_TEST( N::base::instances == 1 ); 152 BOOST_TEST( p.get() == 0 ); 153 154 p2.reset(); 155 BOOST_TEST( N::base::instances == 0 ); 156 } 157 158 { 159 boost::intrusive_ptr<X> p( new X ); 160 BOOST_TEST( N::base::instances == 1 ); 161 162 boost::intrusive_ptr<X> p2; 163 p2 = std::move( p ); 164 BOOST_TEST( N::base::instances == 1 ); 165 BOOST_TEST( p.get() == 0 ); 166 167 p2.reset(); 168 BOOST_TEST( N::base::instances == 0 ); 169 } 170 171 { 172 boost::intrusive_ptr<X> p( new X ); 173 BOOST_TEST( N::base::instances == 1 ); 174 175 boost::intrusive_ptr<X> p2( new X ); 176 BOOST_TEST( N::base::instances == 2 ); 177 p2 = std::move( p ); 178 BOOST_TEST( N::base::instances == 1 ); 179 BOOST_TEST( p.get() == 0 ); 180 181 p2.reset(); 182 BOOST_TEST( N::base::instances == 0 ); 183 } 184 185 { 186 boost::intrusive_ptr<Y> p( new Y ); 187 BOOST_TEST( N::base::instances == 1 ); 188 189 boost::intrusive_ptr<X> p2; 190 p2 = std::move( p ); 191 BOOST_TEST( N::base::instances == 1 ); 192 BOOST_TEST( p.get() == 0 ); 193 194 p2.reset(); 195 BOOST_TEST( N::base::instances == 0 ); 196 } 197 198 { 199 boost::intrusive_ptr<Y> p( new Y ); 200 BOOST_TEST( N::base::instances == 1 ); 201 202 boost::intrusive_ptr<X> p2( new X ); 203 BOOST_TEST( N::base::instances == 2 ); 204 p2 = std::move( p ); 205 BOOST_TEST( N::base::instances == 1 ); 206 BOOST_TEST( p.get() == 0 ); 207 208 p2.reset(); 209 BOOST_TEST( N::base::instances == 0 ); 210 } 211 212 { 213 boost::intrusive_ptr<X> px( new Y ); 214 215 X * px2 = px.get(); 216 217 boost::intrusive_ptr<Y> py = boost::static_pointer_cast<Y>( std::move( px ) ); 218 BOOST_TEST( py.get() == px2 ); 219 BOOST_TEST( px.get() == 0 ); 220 BOOST_TEST( py->use_count() == 1 ); 221 } 222 223 BOOST_TEST( N::base::instances == 0 ); 224 225 { 226 boost::intrusive_ptr<X const> px( new X ); 227 228 X const * px2 = px.get(); 229 230 boost::intrusive_ptr<X> px3 = boost::const_pointer_cast<X>( std::move( px ) ); 231 BOOST_TEST( px3.get() == px2 ); 232 BOOST_TEST( px.get() == 0 ); 233 BOOST_TEST( px3->use_count() == 1 ); 234 } 235 236 BOOST_TEST( N::base::instances == 0 ); 237 238 { 239 boost::intrusive_ptr<X> px( new Y ); 240 241 X * px2 = px.get(); 242 243 boost::intrusive_ptr<Y> py = boost::dynamic_pointer_cast<Y>( std::move( px ) ); 244 BOOST_TEST( py.get() == px2 ); 245 BOOST_TEST( px.get() == 0 ); 246 BOOST_TEST( py->use_count() == 1 ); 247 } 248 249 BOOST_TEST( N::base::instances == 0 ); 250 251 { 252 boost::intrusive_ptr<X> px( new X ); 253 254 X * px2 = px.get(); 255 256 boost::intrusive_ptr<Y> py = boost::dynamic_pointer_cast<Y>( std::move( px ) ); 257 BOOST_TEST( py.get() == 0 ); 258 BOOST_TEST( px.get() == px2 ); 259 BOOST_TEST( px->use_count() == 1 ); 260 } 261 262 BOOST_TEST( N::base::instances == 0 ); 263 264 return boost::report_errors(); 265 } 266 267 #else // defined( BOOST_NO_CXX11_RVALUE_REFERENCES ) 268 main()269int main() 270 { 271 return 0; 272 } 273 274 #endif 275