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_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/core/lightweight_test.hpp>
30#include <boost/intrusive_ptr.hpp>
31#include <boost/detail/atomic_count.hpp>
32#include <boost/config.hpp>
33#include <algorithm>
34#include <functional>
35
36//
37
38namespace N
39{
40
41class base
42{
43private:
44
45 mutable boost::detail::atomic_count use_count_;
46
47 base(base const &);
48 base & operator=(base const &);
49
50protected:
51
52 base(): use_count_(0)
53 {
54 ++instances;
55 }
56
57 virtual ~base()
58 {
59 --instances;
60 }
61
62public:
63
64 static long instances;
65
66 long use_count() const
67 {
68 return use_count_;
69 }
70
71#if !defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP)
72
73 inline friend void intrusive_ptr_add_ref(base const * p)
74 {
75 ++p->use_count_;
76 }
77
78 inline friend void intrusive_ptr_release(base const * p)
79 {
80 if(--p->use_count_ == 0) delete p;
81 }
82
83#else
84
85 void add_ref() const
86 {
87 ++use_count_;
88 }
89
90 void release() const
91 {
92 if(--use_count_ == 0) delete this;
93 }
94
95#endif
96};
97
98long base::instances = 0;
99
100} // namespace N
101
102#if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP)
103
104namespace boost
105{
106
107inline void intrusive_ptr_add_ref(N::base const * p)
108{
109 p->add_ref();
110}
111
112inline void intrusive_ptr_release(N::base const * p)
113{
114 p->release();
115}
116
117} // namespace boost
118
119#endif
120
121//
122
123struct X: public virtual N::base
124{
125};
126
127struct Y: public X
128{
129};
130
131//
132
133namespace n_element_type
134{
135
136void f(X &)
137{
138}
139
140void test()
141{
142 typedef boost::intrusive_ptr<X>::element_type T;
143 T t;
144 f(t);
145}
146
147} // namespace n_element_type
148
149namespace n_constructors
150{
151
152void default_constructor()
153{
154 boost::intrusive_ptr<X> px;
155 BOOST_TEST(px.get() == 0);
156}
157
158void pointer_constructor()
159{
160 {
161 boost::intrusive_ptr<X> px(0);
162 BOOST_TEST(px.get() == 0);
163 }
164
165 {
166 boost::intrusive_ptr<X> px(0, false);
167 BOOST_TEST(px.get() == 0);
168 }
169
170 BOOST_TEST( N::base::instances == 0 );
171
172 {
173 X * p = new X;
174 BOOST_TEST(p->use_count() == 0);
175
176 BOOST_TEST( N::base::instances == 1 );
177
178 boost::intrusive_ptr<X> px(p);
179 BOOST_TEST(px.get() == p);
180 BOOST_TEST(px->use_count() == 1);
181 }
182
183 BOOST_TEST( N::base::instances == 0 );
184
185 {
186 X * p = new X;
187 BOOST_TEST(p->use_count() == 0);
188
189 BOOST_TEST( N::base::instances == 1 );
190
191#if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP)
192 using boost::intrusive_ptr_add_ref;
193#endif
194 intrusive_ptr_add_ref(p);
195 BOOST_TEST(p->use_count() == 1);
196
197 boost::intrusive_ptr<X> px(p, false);
198 BOOST_TEST(px.get() == p);
199 BOOST_TEST(px->use_count() == 1);
200 }
201
202 BOOST_TEST( N::base::instances == 0 );
203}
204
205void copy_constructor()
206{
207 {
208 boost::intrusive_ptr<X> px;
209 boost::intrusive_ptr<X> px2(px);
210 BOOST_TEST(px2.get() == px.get());
211 }
212
213 {
214 boost::intrusive_ptr<Y> py;
215 boost::intrusive_ptr<X> px(py);
216 BOOST_TEST(px.get() == py.get());
217 }
218
219 {
220 boost::intrusive_ptr<X> px(0);
221 boost::intrusive_ptr<X> px2(px);
222 BOOST_TEST(px2.get() == px.get());
223 }
224
225 {
226 boost::intrusive_ptr<Y> py(0);
227 boost::intrusive_ptr<X> px(py);
228 BOOST_TEST(px.get() == py.get());
229 }
230
231 {
232 boost::intrusive_ptr<X> px(0, false);
233 boost::intrusive_ptr<X> px2(px);
234 BOOST_TEST(px2.get() == px.get());
235 }
236
237 {
238 boost::intrusive_ptr<Y> py(0, false);
239 boost::intrusive_ptr<X> px(py);
240 BOOST_TEST(px.get() == py.get());
241 }
242
243 BOOST_TEST( N::base::instances == 0 );
244
245 {
246 boost::intrusive_ptr<X> px(new X);
247 boost::intrusive_ptr<X> px2(px);
248 BOOST_TEST( px2.get() == px.get() );
249
250 BOOST_TEST( N::base::instances == 1 );
251 }
252
253 BOOST_TEST( N::base::instances == 0 );
254
255 {
256 boost::intrusive_ptr<Y> py(new Y);
257 boost::intrusive_ptr<X> px(py);
258 BOOST_TEST( px.get() == py.get() );
259
260 BOOST_TEST( N::base::instances == 1 );
261 }
262
263 BOOST_TEST( N::base::instances == 0 );
264}
265
266void test()
267{
268 default_constructor();
269 pointer_constructor();
270 copy_constructor();
271}
272
273} // namespace n_constructors
274
275namespace n_destructor
276{
277
278void test()
279{
280 BOOST_TEST( N::base::instances == 0 );
281
282 {
283 boost::intrusive_ptr<X> px(new X);
284 BOOST_TEST(px->use_count() == 1);
285
286 BOOST_TEST( N::base::instances == 1 );
287
288 {
289 boost::intrusive_ptr<X> px2(px);
290 BOOST_TEST(px->use_count() == 2);
291 }
292
293 BOOST_TEST(px->use_count() == 1);
294 }
295
296 BOOST_TEST( N::base::instances == 0 );
297}
298
299} // namespace n_destructor
300
301namespace n_assignment
302{
303
304void copy_assignment()
305{
306 BOOST_TEST( N::base::instances == 0 );
307
308 {
309 boost::intrusive_ptr<X> p1;
310
311 p1 = p1;
312
313 BOOST_TEST(p1 == p1);
314 BOOST_TEST(p1? false: true);
315 BOOST_TEST(!p1);
316 BOOST_TEST(p1.get() == 0);
317
318 boost::intrusive_ptr<X> p2;
319
320 p1 = p2;
321
322 BOOST_TEST(p1 == p2);
323 BOOST_TEST(p1? false: true);
324 BOOST_TEST(!p1);
325 BOOST_TEST(p1.get() == 0);
326
327 boost::intrusive_ptr<X> p3(p1);
328
329 p1 = p3;
330
331 BOOST_TEST(p1 == p3);
332 BOOST_TEST(p1? false: true);
333 BOOST_TEST(!p1);
334 BOOST_TEST(p1.get() == 0);
335
336 BOOST_TEST(N::base::instances == 0);
337
338 boost::intrusive_ptr<X> p4(new X);
339
340 BOOST_TEST(N::base::instances == 1);
341
342 p1 = p4;
343
344 BOOST_TEST(N::base::instances == 1);
345
346 BOOST_TEST(p1 == p4);
347
348 BOOST_TEST(p1->use_count() == 2);
349
350 p1 = p2;
351
352 BOOST_TEST(p1 == p2);
353 BOOST_TEST(N::base::instances == 1);
354
355 p4 = p3;
356
357 BOOST_TEST(p4 == p3);
358 BOOST_TEST(N::base::instances == 0);
359 }
360}
361
362void conversion_assignment()
363{
364 BOOST_TEST( N::base::instances == 0 );
365
366 {
367 boost::intrusive_ptr<X> p1;
368
369 boost::intrusive_ptr<Y> p2;
370
371 p1 = p2;
372
373 BOOST_TEST(p1 == p2);
374 BOOST_TEST(p1? false: true);
375 BOOST_TEST(!p1);
376 BOOST_TEST(p1.get() == 0);
377
378 BOOST_TEST(N::base::instances == 0);
379
380 boost::intrusive_ptr<Y> p4(new Y);
381
382 BOOST_TEST(N::base::instances == 1);
383 BOOST_TEST(p4->use_count() == 1);
384
385 boost::intrusive_ptr<X> p5(p4);
386 BOOST_TEST(p4->use_count() == 2);
387
388 p1 = p4;
389
390 BOOST_TEST(N::base::instances == 1);
391
392 BOOST_TEST(p1 == p4);
393
394 BOOST_TEST(p1->use_count() == 3);
395 BOOST_TEST(p4->use_count() == 3);
396
397 p1 = p2;
398
399 BOOST_TEST(p1 == p2);
400 BOOST_TEST(N::base::instances == 1);
401 BOOST_TEST(p4->use_count() == 2);
402
403 p4 = p2;
404 p5 = p2;
405
406 BOOST_TEST(p4 == p2);
407 BOOST_TEST(N::base::instances == 0);
408 }
409}
410
411void pointer_assignment()
412{
413 BOOST_TEST( N::base::instances == 0 );
414
415 {
416 boost::intrusive_ptr<X> p1;
417
418 p1 = p1.get();
419
420 BOOST_TEST(p1 == p1);
421 BOOST_TEST(p1? false: true);
422 BOOST_TEST(!p1);
423 BOOST_TEST(p1.get() == 0);
424
425 boost::intrusive_ptr<X> p2;
426
427 p1 = p2.get();
428
429 BOOST_TEST(p1 == p2);
430 BOOST_TEST(p1? false: true);
431 BOOST_TEST(!p1);
432 BOOST_TEST(p1.get() == 0);
433
434 boost::intrusive_ptr<X> p3(p1);
435
436 p1 = p3.get();
437
438 BOOST_TEST(p1 == p3);
439 BOOST_TEST(p1? false: true);
440 BOOST_TEST(!p1);
441 BOOST_TEST(p1.get() == 0);
442
443 BOOST_TEST(N::base::instances == 0);
444
445 boost::intrusive_ptr<X> p4(new X);
446
447 BOOST_TEST(N::base::instances == 1);
448
449 p1 = p4.get();
450
451 BOOST_TEST(N::base::instances == 1);
452
453 BOOST_TEST(p1 == p4);
454
455 BOOST_TEST(p1->use_count() == 2);
456
457 p1 = p2.get();
458
459 BOOST_TEST(p1 == p2);
460 BOOST_TEST(N::base::instances == 1);
461
462 p4 = p3.get();
463
464 BOOST_TEST(p4 == p3);
465 BOOST_TEST(N::base::instances == 0);
466 }
467
468 {
469 boost::intrusive_ptr<X> p1;
470
471 boost::intrusive_ptr<Y> p2;
472
473 p1 = p2.get();
474
475 BOOST_TEST(p1 == p2);
476 BOOST_TEST(p1? false: true);
477 BOOST_TEST(!p1);
478 BOOST_TEST(p1.get() == 0);
479
480 BOOST_TEST(N::base::instances == 0);
481
482 boost::intrusive_ptr<Y> p4(new Y);
483
484 BOOST_TEST(N::base::instances == 1);
485 BOOST_TEST(p4->use_count() == 1);
486
487 boost::intrusive_ptr<X> p5(p4);
488 BOOST_TEST(p4->use_count() == 2);
489
490 p1 = p4.get();
491
492 BOOST_TEST(N::base::instances == 1);
493
494 BOOST_TEST(p1 == p4);
495
496 BOOST_TEST(p1->use_count() == 3);
497 BOOST_TEST(p4->use_count() == 3);
498
499 p1 = p2.get();
500
501 BOOST_TEST(p1 == p2);
502 BOOST_TEST(N::base::instances == 1);
503 BOOST_TEST(p4->use_count() == 2);
504
505 p4 = p2.get();
506 p5 = p2.get();
507
508 BOOST_TEST(p4 == p2);
509 BOOST_TEST(N::base::instances == 0);
510 }
511}
512
513void test()
514{
515 copy_assignment();
516 conversion_assignment();
517 pointer_assignment();
518}
519
520} // namespace n_assignment
521
522namespace n_reset
523{
524
525void test()
526{
527 BOOST_TEST( N::base::instances == 0 );
528
529 {
530 boost::intrusive_ptr<X> px;
531 BOOST_TEST( px.get() == 0 );
532
533 px.reset();
534 BOOST_TEST( px.get() == 0 );
535
536 X * p = new X;
537 BOOST_TEST( p->use_count() == 0 );
538 BOOST_TEST( N::base::instances == 1 );
539
540 px.reset( rhs: p );
541 BOOST_TEST( px.get() == p );
542 BOOST_TEST( px->use_count() == 1 );
543
544 px.reset();
545 BOOST_TEST( px.get() == 0 );
546 }
547
548 BOOST_TEST( N::base::instances == 0 );
549
550 {
551 boost::intrusive_ptr<X> px( new X );
552 BOOST_TEST( N::base::instances == 1 );
553
554 px.reset( rhs: 0 );
555 BOOST_TEST( px.get() == 0 );
556 }
557
558 BOOST_TEST( N::base::instances == 0 );
559
560 {
561 boost::intrusive_ptr<X> px( new X );
562 BOOST_TEST( N::base::instances == 1 );
563
564 px.reset( rhs: 0, add_ref: false );
565 BOOST_TEST( px.get() == 0 );
566 }
567
568 BOOST_TEST( N::base::instances == 0 );
569
570 {
571 boost::intrusive_ptr<X> px( new X );
572 BOOST_TEST( N::base::instances == 1 );
573
574 px.reset( rhs: 0, add_ref: true );
575 BOOST_TEST( px.get() == 0 );
576 }
577
578 BOOST_TEST( N::base::instances == 0 );
579
580 {
581 X * p = new X;
582 BOOST_TEST( p->use_count() == 0 );
583
584 BOOST_TEST( N::base::instances == 1 );
585
586 boost::intrusive_ptr<X> px;
587 BOOST_TEST( px.get() == 0 );
588
589 px.reset( rhs: p, add_ref: true );
590 BOOST_TEST( px.get() == p );
591 BOOST_TEST( px->use_count() == 1 );
592 }
593
594 BOOST_TEST( N::base::instances == 0 );
595
596 {
597 X * p = new X;
598 BOOST_TEST( p->use_count() == 0 );
599
600 BOOST_TEST( N::base::instances == 1 );
601
602#if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP)
603 using boost::intrusive_ptr_add_ref;
604#endif
605 intrusive_ptr_add_ref( p );
606 BOOST_TEST( p->use_count() == 1 );
607
608 boost::intrusive_ptr<X> px;
609 BOOST_TEST( px.get() == 0 );
610
611 px.reset( rhs: p, add_ref: false );
612 BOOST_TEST( px.get() == p );
613 BOOST_TEST( px->use_count() == 1 );
614 }
615
616 BOOST_TEST( N::base::instances == 0 );
617
618 {
619 boost::intrusive_ptr<X> px( new X );
620 BOOST_TEST( px.get() != 0 );
621 BOOST_TEST( px->use_count() == 1 );
622
623 BOOST_TEST( N::base::instances == 1 );
624
625 X * p = new X;
626 BOOST_TEST( p->use_count() == 0 );
627
628 BOOST_TEST( N::base::instances == 2 );
629
630 px.reset( rhs: p );
631 BOOST_TEST( px.get() == p );
632 BOOST_TEST( px->use_count() == 1 );
633
634 BOOST_TEST( N::base::instances == 1 );
635 }
636
637 BOOST_TEST( N::base::instances == 0 );
638
639 {
640 boost::intrusive_ptr<X> px( new X );
641 BOOST_TEST( px.get() != 0 );
642 BOOST_TEST( px->use_count() == 1 );
643
644 BOOST_TEST( N::base::instances == 1 );
645
646 X * p = new X;
647 BOOST_TEST( p->use_count() == 0 );
648
649 BOOST_TEST( N::base::instances == 2 );
650
651 px.reset( rhs: p, add_ref: true );
652 BOOST_TEST( px.get() == p );
653 BOOST_TEST( px->use_count() == 1 );
654
655 BOOST_TEST( N::base::instances == 1 );
656 }
657
658 BOOST_TEST( N::base::instances == 0 );
659
660 {
661 boost::intrusive_ptr<X> px( new X );
662 BOOST_TEST( px.get() != 0 );
663 BOOST_TEST( px->use_count() == 1 );
664
665 BOOST_TEST( N::base::instances == 1 );
666
667 X * p = new X;
668 BOOST_TEST( p->use_count() == 0 );
669
670#if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP)
671 using boost::intrusive_ptr_add_ref;
672#endif
673 intrusive_ptr_add_ref( p );
674 BOOST_TEST( p->use_count() == 1 );
675
676 BOOST_TEST( N::base::instances == 2 );
677
678 px.reset( rhs: p, add_ref: false );
679 BOOST_TEST( px.get() == p );
680 BOOST_TEST( px->use_count() == 1 );
681
682 BOOST_TEST( N::base::instances == 1 );
683 }
684
685 BOOST_TEST( N::base::instances == 0 );
686}
687
688} // namespace n_reset
689
690namespace n_access
691{
692
693void test()
694{
695 {
696 boost::intrusive_ptr<X> px;
697 BOOST_TEST(px? false: true);
698 BOOST_TEST(!px);
699
700#if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP)
701 using boost::get_pointer;
702#endif
703
704 BOOST_TEST(get_pointer(px) == px.get());
705 }
706
707 {
708 boost::intrusive_ptr<X> px(0);
709 BOOST_TEST(px? false: true);
710 BOOST_TEST(!px);
711
712#if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP)
713 using boost::get_pointer;
714#endif
715
716 BOOST_TEST(get_pointer(px) == px.get());
717 }
718
719 {
720 boost::intrusive_ptr<X> px(new X);
721 BOOST_TEST(px? true: false);
722 BOOST_TEST(!!px);
723 BOOST_TEST(&*px == px.get());
724 BOOST_TEST(px.operator ->() == px.get());
725
726#if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP)
727 using boost::get_pointer;
728#endif
729
730 BOOST_TEST(get_pointer(px) == px.get());
731 }
732
733 {
734 boost::intrusive_ptr<X> px;
735 X* detached = px.detach();
736 BOOST_TEST( px.get() == 0 );
737 BOOST_TEST( detached == 0 );
738 }
739
740 {
741 X * p = new X;
742 BOOST_TEST( p->use_count() == 0 );
743
744 boost::intrusive_ptr<X> px( p );
745 BOOST_TEST( px.get() == p );
746 BOOST_TEST( px->use_count() == 1 );
747
748 X * detached = px.detach();
749 BOOST_TEST( px.get() == 0 );
750
751 BOOST_TEST( detached == p );
752 BOOST_TEST( detached->use_count() == 1 );
753
754 delete detached;
755 }
756}
757
758} // namespace n_access
759
760namespace n_swap
761{
762
763void test()
764{
765 {
766 boost::intrusive_ptr<X> px;
767 boost::intrusive_ptr<X> px2;
768
769 px.swap(rhs&: px2);
770
771 BOOST_TEST(px.get() == 0);
772 BOOST_TEST(px2.get() == 0);
773
774 using std::swap;
775 swap(lhs&: px, rhs&: px2);
776
777 BOOST_TEST(px.get() == 0);
778 BOOST_TEST(px2.get() == 0);
779 }
780
781 {
782 X * p = new X;
783 boost::intrusive_ptr<X> px;
784 boost::intrusive_ptr<X> px2(p);
785 boost::intrusive_ptr<X> px3(px2);
786
787 px.swap(rhs&: px2);
788
789 BOOST_TEST(px.get() == p);
790 BOOST_TEST(px->use_count() == 2);
791 BOOST_TEST(px2.get() == 0);
792 BOOST_TEST(px3.get() == p);
793 BOOST_TEST(px3->use_count() == 2);
794
795 using std::swap;
796 swap(lhs&: px, rhs&: px2);
797
798 BOOST_TEST(px.get() == 0);
799 BOOST_TEST(px2.get() == p);
800 BOOST_TEST(px2->use_count() == 2);
801 BOOST_TEST(px3.get() == p);
802 BOOST_TEST(px3->use_count() == 2);
803 }
804
805 {
806 X * p1 = new X;
807 X * p2 = new X;
808 boost::intrusive_ptr<X> px(p1);
809 boost::intrusive_ptr<X> px2(p2);
810 boost::intrusive_ptr<X> px3(px2);
811
812 px.swap(rhs&: px2);
813
814 BOOST_TEST(px.get() == p2);
815 BOOST_TEST(px->use_count() == 2);
816 BOOST_TEST(px2.get() == p1);
817 BOOST_TEST(px2->use_count() == 1);
818 BOOST_TEST(px3.get() == p2);
819 BOOST_TEST(px3->use_count() == 2);
820
821 using std::swap;
822 swap(lhs&: px, rhs&: px2);
823
824 BOOST_TEST(px.get() == p1);
825 BOOST_TEST(px->use_count() == 1);
826 BOOST_TEST(px2.get() == p2);
827 BOOST_TEST(px2->use_count() == 2);
828 BOOST_TEST(px3.get() == p2);
829 BOOST_TEST(px3->use_count() == 2);
830 }
831}
832
833} // namespace n_swap
834
835namespace n_comparison
836{
837
838template<class T, class U> void test2(boost::intrusive_ptr<T> const & p, boost::intrusive_ptr<U> const & q)
839{
840 BOOST_TEST((p == q) == (p.get() == q.get()));
841 BOOST_TEST((p != q) == (p.get() != q.get()));
842}
843
844template<class T> void test3(boost::intrusive_ptr<T> const & p, boost::intrusive_ptr<T> const & q)
845{
846 BOOST_TEST((p == q) == (p.get() == q.get()));
847 BOOST_TEST((p.get() == q) == (p.get() == q.get()));
848 BOOST_TEST((p == q.get()) == (p.get() == q.get()));
849 BOOST_TEST((p != q) == (p.get() != q.get()));
850 BOOST_TEST((p.get() != q) == (p.get() != q.get()));
851 BOOST_TEST((p != q.get()) == (p.get() != q.get()));
852
853 // 'less' moved here as a g++ 2.9x parse error workaround
854 std::less<T*> less;
855 BOOST_TEST((p < q) == less(p.get(), q.get()));
856}
857
858void test()
859{
860 {
861 boost::intrusive_ptr<X> px;
862 test3(p: px, q: px);
863
864 boost::intrusive_ptr<X> px2;
865 test3(p: px, q: px2);
866
867 boost::intrusive_ptr<X> px3(px);
868 test3(p: px3, q: px3);
869 test3(p: px, q: px3);
870 }
871
872 {
873 boost::intrusive_ptr<X> px;
874
875 boost::intrusive_ptr<X> px2(new X);
876 test3(p: px, q: px2);
877 test3(p: px2, q: px2);
878
879 boost::intrusive_ptr<X> px3(new X);
880 test3(p: px2, q: px3);
881
882 boost::intrusive_ptr<X> px4(px2);
883 test3(p: px2, q: px4);
884 test3(p: px4, q: px4);
885 }
886
887 {
888 boost::intrusive_ptr<X> px(new X);
889
890 boost::intrusive_ptr<Y> py(new Y);
891 test2(p: px, q: py);
892
893 boost::intrusive_ptr<X> px2(py);
894 test2(p: px2, q: py);
895 test3(p: px, q: px2);
896 test3(p: px2, q: px2);
897 }
898}
899
900} // namespace n_comparison
901
902namespace n_static_cast
903{
904
905void test()
906{
907 {
908 boost::intrusive_ptr<X> px(new Y);
909
910 boost::intrusive_ptr<Y> py = boost::static_pointer_cast<Y>(p: px);
911 BOOST_TEST(px.get() == py.get());
912 BOOST_TEST(px->use_count() == 2);
913 BOOST_TEST(py->use_count() == 2);
914
915 boost::intrusive_ptr<X> px2(py);
916 BOOST_TEST(px2.get() == px.get());
917 }
918
919 BOOST_TEST( N::base::instances == 0 );
920
921 {
922 boost::intrusive_ptr<Y> py = boost::static_pointer_cast<Y>( p: boost::intrusive_ptr<X>(new Y) );
923 BOOST_TEST(py.get() != 0);
924 BOOST_TEST(py->use_count() == 1);
925 }
926
927 BOOST_TEST( N::base::instances == 0 );
928}
929
930} // namespace n_static_cast
931
932namespace n_const_cast
933{
934
935void test()
936{
937 {
938 boost::intrusive_ptr<X const> px;
939
940 boost::intrusive_ptr<X> px2 = boost::const_pointer_cast<X>(p: px);
941 BOOST_TEST(px2.get() == 0);
942 }
943
944 {
945 boost::intrusive_ptr<X> px2 = boost::const_pointer_cast<X>( p: boost::intrusive_ptr<X const>() );
946 BOOST_TEST(px2.get() == 0);
947 }
948
949 BOOST_TEST( N::base::instances == 0 );
950
951 {
952 boost::intrusive_ptr<X const> px(new X);
953
954 boost::intrusive_ptr<X> px2 = boost::const_pointer_cast<X>(p: px);
955 BOOST_TEST(px2.get() == px.get());
956 BOOST_TEST(px2->use_count() == 2);
957 BOOST_TEST(px->use_count() == 2);
958 }
959
960 BOOST_TEST( N::base::instances == 0 );
961
962 {
963 boost::intrusive_ptr<X> px = boost::const_pointer_cast<X>( p: boost::intrusive_ptr<X const>(new X) );
964 BOOST_TEST(px.get() != 0);
965 BOOST_TEST(px->use_count() == 1);
966 }
967
968 BOOST_TEST( N::base::instances == 0 );
969}
970
971} // namespace n_const_cast
972
973namespace n_dynamic_cast
974{
975
976void test()
977{
978 {
979 boost::intrusive_ptr<X> px;
980
981 boost::intrusive_ptr<Y> py = boost::dynamic_pointer_cast<Y>(p: px);
982 BOOST_TEST(py.get() == 0);
983 }
984
985 {
986 boost::intrusive_ptr<Y> py = boost::dynamic_pointer_cast<Y>( p: boost::intrusive_ptr<X>() );
987 BOOST_TEST(py.get() == 0);
988 }
989
990 {
991 boost::intrusive_ptr<X> px(static_cast<X*>(0));
992
993 boost::intrusive_ptr<Y> py = boost::dynamic_pointer_cast<Y>(p: px);
994 BOOST_TEST(py.get() == 0);
995 }
996
997 {
998 boost::intrusive_ptr<Y> py = boost::dynamic_pointer_cast<Y>( p: boost::intrusive_ptr<X>(static_cast<X*>(0)) );
999 BOOST_TEST(py.get() == 0);
1000 }
1001
1002 {
1003 boost::intrusive_ptr<X> px(new X);
1004
1005 boost::intrusive_ptr<Y> py = boost::dynamic_pointer_cast<Y>(p: px);
1006 BOOST_TEST(py.get() == 0);
1007 }
1008
1009 BOOST_TEST( N::base::instances == 0 );
1010
1011 {
1012 boost::intrusive_ptr<Y> py = boost::dynamic_pointer_cast<Y>( p: boost::intrusive_ptr<X>(new X) );
1013 BOOST_TEST(py.get() == 0);
1014 }
1015
1016 BOOST_TEST( N::base::instances == 0 );
1017
1018 {
1019 boost::intrusive_ptr<X> px(new Y);
1020
1021 boost::intrusive_ptr<Y> py = boost::dynamic_pointer_cast<Y>(p: px);
1022 BOOST_TEST(py.get() == px.get());
1023 BOOST_TEST(py->use_count() == 2);
1024 BOOST_TEST(px->use_count() == 2);
1025 }
1026
1027 BOOST_TEST( N::base::instances == 0 );
1028
1029 {
1030 boost::intrusive_ptr<X> px(new Y);
1031
1032 boost::intrusive_ptr<Y> py = boost::dynamic_pointer_cast<Y>( p: boost::intrusive_ptr<X>(new Y) );
1033 BOOST_TEST(py.get() != 0);
1034 BOOST_TEST(py->use_count() == 1);
1035 }
1036
1037 BOOST_TEST( N::base::instances == 0 );
1038}
1039
1040} // namespace n_dynamic_cast
1041
1042namespace n_transitive
1043{
1044
1045struct X: public N::base
1046{
1047 boost::intrusive_ptr<X> next;
1048};
1049
1050void test()
1051{
1052 boost::intrusive_ptr<X> p(new X);
1053 p->next = boost::intrusive_ptr<X>(new X);
1054 BOOST_TEST(!p->next->next);
1055 p = p->next;
1056 BOOST_TEST(!p->next);
1057}
1058
1059} // namespace n_transitive
1060
1061namespace n_report_1
1062{
1063
1064class foo: public N::base
1065{
1066public:
1067
1068 foo(): m_self(this)
1069 {
1070 }
1071
1072 void suicide()
1073 {
1074 m_self = 0;
1075 }
1076
1077private:
1078
1079 boost::intrusive_ptr<foo> m_self;
1080};
1081
1082void test()
1083{
1084 foo * foo_ptr = new foo;
1085 foo_ptr->suicide();
1086}
1087
1088} // namespace n_report_1
1089
1090int main()
1091{
1092 n_element_type::test();
1093 n_constructors::test();
1094 n_destructor::test();
1095 n_assignment::test();
1096 n_reset::test();
1097 n_access::test();
1098 n_swap::test();
1099 n_comparison::test();
1100 n_static_cast::test();
1101 n_const_cast::test();
1102 n_dynamic_cast::test();
1103
1104 n_transitive::test();
1105 n_report_1::test();
1106
1107 return boost::report_errors();
1108}
1109

source code of boost/libs/smart_ptr/test/intrusive_ptr_test.cpp