1 #include <boost/config.hpp>
3 #if defined(BOOST_MSVC)
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
13 #if (BOOST_MSVC >= 1310)
14 #pragma warning(disable: 4675) // resolved overload found with Koenig lookup
20 // intrusive_ptr_test.cpp
22 // Copyright (c) 2002-2005 Peter Dimov
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)
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>
45 boost::detail::atomic_count use_count_;
48 base & operator=(base const &);
62 long use_count() const
67 #if !defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP)
69 inline friend void intrusive_ptr_add_ref(base * p)
74 inline friend void intrusive_ptr_release(base * p)
76 if(--p->use_count_ == 0) delete p;
88 if(--use_count_ == 0) delete this;
96 #if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP)
101 inline void intrusive_ptr_add_ref(N::base * p)
106 inline void intrusive_ptr_release(N::base * p)
117 struct X: public virtual N::base
127 namespace n_element_type
136 typedef boost::intrusive_ptr<X>::element_type T;
141 } // namespace n_element_type
143 namespace n_constructors
146 void default_constructor()
148 boost::intrusive_ptr<X> px;
149 BOOST_TEST(px.get() == 0);
152 void pointer_constructor()
155 boost::intrusive_ptr<X> px(0);
156 BOOST_TEST(px.get() == 0);
160 boost::intrusive_ptr<X> px(0, false);
161 BOOST_TEST(px.get() == 0);
166 BOOST_TEST(p->use_count() == 0);
168 boost::intrusive_ptr<X> px(p);
169 BOOST_TEST(px.get() == p);
170 BOOST_TEST(px->use_count() == 1);
175 BOOST_TEST(p->use_count() == 0);
177 #if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP)
178 using boost::intrusive_ptr_add_ref;
180 intrusive_ptr_add_ref(p);
181 BOOST_TEST(p->use_count() == 1);
183 boost::intrusive_ptr<X> px(p, false);
184 BOOST_TEST(px.get() == p);
185 BOOST_TEST(px->use_count() == 1);
189 void copy_constructor()
192 boost::intrusive_ptr<X> px;
193 boost::intrusive_ptr<X> px2(px);
194 BOOST_TEST(px2.get() == px.get());
198 boost::intrusive_ptr<Y> py;
199 boost::intrusive_ptr<X> px(py);
200 BOOST_TEST(px.get() == py.get());
204 boost::intrusive_ptr<X> px(0);
205 boost::intrusive_ptr<X> px2(px);
206 BOOST_TEST(px2.get() == px.get());
210 boost::intrusive_ptr<Y> py(0);
211 boost::intrusive_ptr<X> px(py);
212 BOOST_TEST(px.get() == py.get());
216 boost::intrusive_ptr<X> px(0, false);
217 boost::intrusive_ptr<X> px2(px);
218 BOOST_TEST(px2.get() == px.get());
222 boost::intrusive_ptr<Y> py(0, false);
223 boost::intrusive_ptr<X> px(py);
224 BOOST_TEST(px.get() == py.get());
228 boost::intrusive_ptr<X> px(new X);
229 boost::intrusive_ptr<X> px2(px);
230 BOOST_TEST(px2.get() == px.get());
234 boost::intrusive_ptr<Y> py(new Y);
235 boost::intrusive_ptr<X> px(py);
236 BOOST_TEST(px.get() == py.get());
242 default_constructor();
243 pointer_constructor();
247 } // namespace n_constructors
249 namespace n_destructor
254 boost::intrusive_ptr<X> px(new X);
255 BOOST_TEST(px->use_count() == 1);
258 boost::intrusive_ptr<X> px2(px);
259 BOOST_TEST(px->use_count() == 2);
262 BOOST_TEST(px->use_count() == 1);
265 } // namespace n_destructor
267 namespace n_assignment
270 void copy_assignment()
274 void conversion_assignment()
278 void pointer_assignment()
285 conversion_assignment();
286 pointer_assignment();
289 } // namespace n_assignment
297 boost::intrusive_ptr<X> px;
298 BOOST_TEST(px? false: true);
301 #if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP)
302 using boost::get_pointer;
305 BOOST_TEST(get_pointer(px) == px.get());
309 boost::intrusive_ptr<X> px(0);
310 BOOST_TEST(px? false: true);
313 #if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP)
314 using boost::get_pointer;
317 BOOST_TEST(get_pointer(px) == px.get());
321 boost::intrusive_ptr<X> px(new X);
322 BOOST_TEST(px? true: false);
324 BOOST_TEST(&*px == px.get());
325 BOOST_TEST(px.operator ->() == px.get());
327 #if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP)
328 using boost::get_pointer;
331 BOOST_TEST(get_pointer(px) == px.get());
335 } // namespace n_access
343 boost::intrusive_ptr<X> px;
344 boost::intrusive_ptr<X> px2;
348 BOOST_TEST(px.get() == 0);
349 BOOST_TEST(px2.get() == 0);
354 BOOST_TEST(px.get() == 0);
355 BOOST_TEST(px2.get() == 0);
360 boost::intrusive_ptr<X> px;
361 boost::intrusive_ptr<X> px2(p);
362 boost::intrusive_ptr<X> px3(px2);
366 BOOST_TEST(px.get() == p);
367 BOOST_TEST(px->use_count() == 2);
368 BOOST_TEST(px2.get() == 0);
369 BOOST_TEST(px3.get() == p);
370 BOOST_TEST(px3->use_count() == 2);
375 BOOST_TEST(px.get() == 0);
376 BOOST_TEST(px2.get() == p);
377 BOOST_TEST(px2->use_count() == 2);
378 BOOST_TEST(px3.get() == p);
379 BOOST_TEST(px3->use_count() == 2);
385 boost::intrusive_ptr<X> px(p1);
386 boost::intrusive_ptr<X> px2(p2);
387 boost::intrusive_ptr<X> px3(px2);
391 BOOST_TEST(px.get() == p2);
392 BOOST_TEST(px->use_count() == 2);
393 BOOST_TEST(px2.get() == p1);
394 BOOST_TEST(px2->use_count() == 1);
395 BOOST_TEST(px3.get() == p2);
396 BOOST_TEST(px3->use_count() == 2);
401 BOOST_TEST(px.get() == p1);
402 BOOST_TEST(px->use_count() == 1);
403 BOOST_TEST(px2.get() == p2);
404 BOOST_TEST(px2->use_count() == 2);
405 BOOST_TEST(px3.get() == p2);
406 BOOST_TEST(px3->use_count() == 2);
410 } // namespace n_swap
412 namespace n_comparison
415 template<class T, class U> void test2(boost::intrusive_ptr<T> const & p, boost::intrusive_ptr<U> const & q)
417 BOOST_TEST((p == q) == (p.get() == q.get()));
418 BOOST_TEST((p != q) == (p.get() != q.get()));
421 template<class T> void test3(boost::intrusive_ptr<T> const & p, boost::intrusive_ptr<T> const & q)
423 BOOST_TEST((p == q) == (p.get() == q.get()));
424 BOOST_TEST((p.get() == q) == (p.get() == q.get()));
425 BOOST_TEST((p == q.get()) == (p.get() == q.get()));
426 BOOST_TEST((p != q) == (p.get() != q.get()));
427 BOOST_TEST((p.get() != q) == (p.get() != q.get()));
428 BOOST_TEST((p != q.get()) == (p.get() != q.get()));
430 // 'less' moved here as a g++ 2.9x parse error workaround
432 BOOST_TEST((p < q) == less(p.get(), q.get()));
438 boost::intrusive_ptr<X> px;
441 boost::intrusive_ptr<X> px2;
444 boost::intrusive_ptr<X> px3(px);
450 boost::intrusive_ptr<X> px;
452 boost::intrusive_ptr<X> px2(new X);
456 boost::intrusive_ptr<X> px3(new X);
459 boost::intrusive_ptr<X> px4(px2);
465 boost::intrusive_ptr<X> px(new X);
467 boost::intrusive_ptr<Y> py(new Y);
470 boost::intrusive_ptr<X> px2(py);
477 } // namespace n_comparison
479 namespace n_static_cast
486 } // namespace n_static_cast
488 namespace n_dynamic_cast
495 } // namespace n_dynamic_cast
497 namespace n_transitive
500 struct X: public N::base
502 boost::intrusive_ptr<X> next;
507 boost::intrusive_ptr<X> p(new X);
508 p->next = boost::intrusive_ptr<X>(new X);
509 BOOST_TEST(!p->next->next);
511 BOOST_TEST(!p->next);
514 } // namespace n_transitive
519 class foo: public N::base
534 boost::intrusive_ptr<foo> m_self;
539 foo * foo_ptr = new foo;
543 } // namespace n_report_1
547 n_element_type::test();
548 n_constructors::test();
549 n_destructor::test();
550 n_assignment::test();
553 n_comparison::test();
554 n_static_cast::test();
555 n_dynamic_cast::test();
557 n_transitive::test();
560 return boost::report_errors();