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 
11 #if (BOOST_MSVC >= 1310)
12 #pragma warning(disable: 4675)  // resolved overload found with Koenig lookup
13 #endif
14 
15 #endif
16 
17 //
18 //  weak_ptr_test.cpp
19 //
20 //  Copyright (c) 2002-2005 Peter Dimov
21 //
22 // Distributed under the Boost Software License, Version 1.0. (See
23 // accompanying file LICENSE_1_0.txt or copy at
24 // http://www.boost.org/LICENSE_1_0.txt)
25 //
26 
27 #include <boost/detail/lightweight_test.hpp>
28 
29 #include <boost/shared_ptr.hpp>
30 #include <boost/weak_ptr.hpp>
31 
32 #include <map>
33 #include <vector>
34 
35 //
36 
37 namespace n_element_type
38 {
39 
f(int &)40 void f(int &)
41 {
42 }
43 
test()44 void test()
45 {
46     typedef boost::weak_ptr<int>::element_type T;
47     T t;
48     f(t);
49 }
50 
51 } // namespace n_element_type
52 
53 class incomplete;
54 
55 boost::shared_ptr<incomplete> create_incomplete();
56 
57 struct X
58 {
59     int dummy;
60 };
61 
62 struct Y
63 {
64     int dummy2;
65 };
66 
67 struct Z: public X, public virtual Y
68 {
69 };
70 
71 namespace n_constructors
72 {
73 
default_constructor()74 void default_constructor()
75 {
76     {
77         boost::weak_ptr<int> wp;
78         BOOST_TEST(wp.use_count() == 0);
79     }
80 
81     {
82         boost::weak_ptr<void> wp;
83         BOOST_TEST(wp.use_count() == 0);
84     }
85 
86     {
87         boost::weak_ptr<incomplete> wp;
88         BOOST_TEST(wp.use_count() == 0);
89     }
90 }
91 
shared_ptr_constructor()92 void shared_ptr_constructor()
93 {
94     {
95         boost::shared_ptr<int> sp;
96 
97         boost::weak_ptr<int> wp(sp);
98         BOOST_TEST(wp.use_count() == sp.use_count());
99 
100         boost::weak_ptr<void> wp2(sp);
101         BOOST_TEST(wp2.use_count() == sp.use_count());
102     }
103 
104     {
105         boost::shared_ptr<int> sp(static_cast<int*>(0));
106 
107         {
108             boost::weak_ptr<int> wp(sp);
109             BOOST_TEST(wp.use_count() == sp.use_count());
110             BOOST_TEST(wp.use_count() == 1);
111             boost::shared_ptr<int> sp2(wp);
112             BOOST_TEST(wp.use_count() == 2);
113             BOOST_TEST(!(sp < sp2 || sp2 < sp));
114         }
115 
116         {
117             boost::weak_ptr<void> wp(sp);
118             BOOST_TEST(wp.use_count() == sp.use_count());
119             BOOST_TEST(wp.use_count() == 1);
120             boost::shared_ptr<void> sp2(wp);
121             BOOST_TEST(wp.use_count() == 2);
122             BOOST_TEST(!(sp < sp2 || sp2 < sp));
123         }
124     }
125 
126     {
127         boost::shared_ptr<int> sp(new int);
128 
129         {
130             boost::weak_ptr<int> wp(sp);
131             BOOST_TEST(wp.use_count() == sp.use_count());
132             BOOST_TEST(wp.use_count() == 1);
133             boost::shared_ptr<int> sp2(wp);
134             BOOST_TEST(wp.use_count() == 2);
135             BOOST_TEST(!(sp < sp2 || sp2 < sp));
136         }
137 
138         {
139             boost::weak_ptr<void> wp(sp);
140             BOOST_TEST(wp.use_count() == sp.use_count());
141             BOOST_TEST(wp.use_count() == 1);
142             boost::shared_ptr<void> sp2(wp);
143             BOOST_TEST(wp.use_count() == 2);
144             BOOST_TEST(!(sp < sp2 || sp2 < sp));
145         }
146     }
147 
148     {
149         boost::shared_ptr<void> sp;
150 
151         boost::weak_ptr<void> wp(sp);
152         BOOST_TEST(wp.use_count() == sp.use_count());
153     }
154 
155     {
156         boost::shared_ptr<void> sp(static_cast<int*>(0));
157 
158         boost::weak_ptr<void> wp(sp);
159         BOOST_TEST(wp.use_count() == sp.use_count());
160         BOOST_TEST(wp.use_count() == 1);
161         boost::shared_ptr<void> sp2(wp);
162         BOOST_TEST(wp.use_count() == 2);
163         BOOST_TEST(!(sp < sp2 || sp2 < sp));
164     }
165 
166     {
167         boost::shared_ptr<void> sp(new int);
168 
169         boost::weak_ptr<void> wp(sp);
170         BOOST_TEST(wp.use_count() == sp.use_count());
171         BOOST_TEST(wp.use_count() == 1);
172         boost::shared_ptr<void> sp2(wp);
173         BOOST_TEST(wp.use_count() == 2);
174         BOOST_TEST(!(sp < sp2 || sp2 < sp));
175     }
176 
177     {
178         boost::shared_ptr<incomplete> sp;
179 
180         boost::weak_ptr<incomplete> wp(sp);
181         BOOST_TEST(wp.use_count() == sp.use_count());
182 
183         boost::weak_ptr<void> wp2(sp);
184         BOOST_TEST(wp2.use_count() == sp.use_count());
185     }
186 
187     {
188         boost::shared_ptr<incomplete> sp = create_incomplete();
189 
190         {
191             boost::weak_ptr<incomplete> wp(sp);
192             BOOST_TEST(wp.use_count() == sp.use_count());
193             BOOST_TEST(wp.use_count() == 1);
194             boost::shared_ptr<incomplete> sp2(wp);
195             BOOST_TEST(wp.use_count() == 2);
196             BOOST_TEST(!(sp < sp2 || sp2 < sp));
197         }
198 
199         {
200             boost::weak_ptr<void> wp(sp);
201             BOOST_TEST(wp.use_count() == sp.use_count());
202             BOOST_TEST(wp.use_count() == 1);
203             boost::shared_ptr<void> sp2(wp);
204             BOOST_TEST(wp.use_count() == 2);
205             BOOST_TEST(!(sp < sp2 || sp2 < sp));
206         }
207     }
208 
209     {
210         boost::shared_ptr<void> sp = create_incomplete();
211 
212         boost::weak_ptr<void> wp(sp);
213         BOOST_TEST(wp.use_count() == sp.use_count());
214         BOOST_TEST(wp.use_count() == 1);
215         boost::shared_ptr<void> sp2(wp);
216         BOOST_TEST(wp.use_count() == 2);
217         BOOST_TEST(!(sp < sp2 || sp2 < sp));
218     }
219 }
220 
copy_constructor()221 void copy_constructor()
222 {
223     {
224         boost::weak_ptr<int> wp;
225         boost::weak_ptr<int> wp2(wp);
226         BOOST_TEST(wp2.use_count() == wp.use_count());
227         BOOST_TEST(wp2.use_count() == 0);
228     }
229 
230     {
231         boost::weak_ptr<void> wp;
232         boost::weak_ptr<void> wp2(wp);
233         BOOST_TEST(wp2.use_count() == wp.use_count());
234         BOOST_TEST(wp2.use_count() == 0);
235     }
236 
237     {
238         boost::weak_ptr<incomplete> wp;
239         boost::weak_ptr<incomplete> wp2(wp);
240         BOOST_TEST(wp2.use_count() == wp.use_count());
241         BOOST_TEST(wp2.use_count() == 0);
242     }
243 
244     {
245         boost::shared_ptr<int> sp(static_cast<int*>(0));
246         boost::weak_ptr<int> wp(sp);
247 
248         boost::weak_ptr<int> wp2(wp);
249         BOOST_TEST(wp2.use_count() == wp.use_count());
250         BOOST_TEST(wp2.use_count() == 1);
251         BOOST_TEST(!(wp < wp2 || wp2 < wp));
252 
253         sp.reset();
254         BOOST_TEST(!(wp < wp2 || wp2 < wp));
255 
256         boost::weak_ptr<int> wp3(wp);
257         BOOST_TEST(wp3.use_count() == wp.use_count());
258         BOOST_TEST(wp3.use_count() == 0);
259         BOOST_TEST(!(wp < wp3 || wp3 < wp));
260     }
261 
262     {
263         boost::shared_ptr<int> sp(new int);
264         boost::weak_ptr<int> wp(sp);
265 
266         boost::weak_ptr<int> wp2(wp);
267         BOOST_TEST(wp2.use_count() == wp.use_count());
268         BOOST_TEST(wp2.use_count() == 1);
269         BOOST_TEST(!(wp < wp2 || wp2 < wp));
270 
271         sp.reset();
272         BOOST_TEST(!(wp < wp2 || wp2 < wp));
273 
274         boost::weak_ptr<int> wp3(wp);
275         BOOST_TEST(wp3.use_count() == wp.use_count());
276         BOOST_TEST(wp3.use_count() == 0);
277         BOOST_TEST(!(wp < wp3 || wp3 < wp));
278     }
279 
280     {
281         boost::shared_ptr<void> sp(static_cast<int*>(0));
282         boost::weak_ptr<void> wp(sp);
283 
284         boost::weak_ptr<void> wp2(wp);
285         BOOST_TEST(wp2.use_count() == wp.use_count());
286         BOOST_TEST(wp2.use_count() == 1);
287         BOOST_TEST(!(wp < wp2 || wp2 < wp));
288 
289         sp.reset();
290         BOOST_TEST(!(wp < wp2 || wp2 < wp));
291 
292         boost::weak_ptr<void> wp3(wp);
293         BOOST_TEST(wp3.use_count() == wp.use_count());
294         BOOST_TEST(wp3.use_count() == 0);
295         BOOST_TEST(!(wp < wp3 || wp3 < wp));
296     }
297 
298     {
299         boost::shared_ptr<void> sp(new int);
300         boost::weak_ptr<void> wp(sp);
301 
302         boost::weak_ptr<void> wp2(wp);
303         BOOST_TEST(wp2.use_count() == wp.use_count());
304         BOOST_TEST(wp2.use_count() == 1);
305         BOOST_TEST(!(wp < wp2 || wp2 < wp));
306 
307         sp.reset();
308         BOOST_TEST(!(wp < wp2 || wp2 < wp));
309 
310         boost::weak_ptr<void> wp3(wp);
311         BOOST_TEST(wp3.use_count() == wp.use_count());
312         BOOST_TEST(wp3.use_count() == 0);
313         BOOST_TEST(!(wp < wp3 || wp3 < wp));
314     }
315 
316     {
317         boost::shared_ptr<incomplete> sp = create_incomplete();
318         boost::weak_ptr<incomplete> wp(sp);
319 
320         boost::weak_ptr<incomplete> wp2(wp);
321         BOOST_TEST(wp2.use_count() == wp.use_count());
322         BOOST_TEST(wp2.use_count() == 1);
323         BOOST_TEST(!(wp < wp2 || wp2 < wp));
324 
325         sp.reset();
326         BOOST_TEST(!(wp < wp2 || wp2 < wp));
327 
328         boost::weak_ptr<incomplete> wp3(wp);
329         BOOST_TEST(wp3.use_count() == wp.use_count());
330         BOOST_TEST(wp3.use_count() == 0);
331         BOOST_TEST(!(wp < wp3 || wp3 < wp));
332     }
333 }
334 
conversion_constructor()335 void conversion_constructor()
336 {
337     {
338         boost::weak_ptr<int> wp;
339         boost::weak_ptr<void> wp2(wp);
340         BOOST_TEST(wp2.use_count() == wp.use_count());
341         BOOST_TEST(wp2.use_count() == 0);
342     }
343 
344     {
345         boost::weak_ptr<incomplete> wp;
346         boost::weak_ptr<void> wp2(wp);
347         BOOST_TEST(wp2.use_count() == wp.use_count());
348         BOOST_TEST(wp2.use_count() == 0);
349     }
350 
351     {
352         boost::weak_ptr<Z> wp;
353 
354         boost::weak_ptr<X> wp2(wp);
355         BOOST_TEST(wp2.use_count() == wp.use_count());
356         BOOST_TEST(wp2.use_count() == 0);
357 
358         boost::weak_ptr<Y> wp3(wp);
359         BOOST_TEST(wp3.use_count() == wp.use_count());
360         BOOST_TEST(wp3.use_count() == 0);
361     }
362 
363     {
364         boost::shared_ptr<int> sp(static_cast<int*>(0));
365         boost::weak_ptr<int> wp(sp);
366 
367         boost::weak_ptr<void> wp2(wp);
368         BOOST_TEST(wp2.use_count() == wp.use_count());
369         BOOST_TEST(wp2.use_count() == 1);
370         BOOST_TEST(!(wp < wp2 || wp2 < wp));
371 
372         sp.reset();
373         BOOST_TEST(!(wp < wp2 || wp2 < wp));
374 
375         boost::weak_ptr<void> wp3(wp);
376         BOOST_TEST(wp3.use_count() == wp.use_count());
377         BOOST_TEST(wp3.use_count() == 0);
378         BOOST_TEST(!(wp < wp3 || wp3 < wp));
379     }
380 
381     {
382         boost::shared_ptr<int> sp(new int);
383         boost::weak_ptr<int> wp(sp);
384 
385         boost::weak_ptr<void> wp2(wp);
386         BOOST_TEST(wp2.use_count() == wp.use_count());
387         BOOST_TEST(wp2.use_count() == 1);
388         BOOST_TEST(!(wp < wp2 || wp2 < wp));
389 
390         sp.reset();
391         BOOST_TEST(!(wp < wp2 || wp2 < wp));
392 
393         boost::weak_ptr<void> wp3(wp);
394         BOOST_TEST(wp3.use_count() == wp.use_count());
395         BOOST_TEST(wp3.use_count() == 0);
396         BOOST_TEST(!(wp < wp3 || wp3 < wp));
397     }
398 
399     {
400         boost::shared_ptr<incomplete> sp = create_incomplete();
401         boost::weak_ptr<incomplete> wp(sp);
402 
403         boost::weak_ptr<void> wp2(wp);
404         BOOST_TEST(wp2.use_count() == wp.use_count());
405         BOOST_TEST(wp2.use_count() == 1);
406         BOOST_TEST(!(wp < wp2 || wp2 < wp));
407 
408         sp.reset();
409         BOOST_TEST(!(wp < wp2 || wp2 < wp));
410 
411         boost::weak_ptr<void> wp3(wp);
412         BOOST_TEST(wp3.use_count() == wp.use_count());
413         BOOST_TEST(wp3.use_count() == 0);
414         BOOST_TEST(!(wp < wp3 || wp3 < wp));
415     }
416 
417     {
418         boost::shared_ptr<Z> sp(static_cast<Z*>(0));
419         boost::weak_ptr<Z> wp(sp);
420 
421         boost::weak_ptr<X> wp2(wp);
422         BOOST_TEST(wp2.use_count() == wp.use_count());
423         BOOST_TEST(wp2.use_count() == 1);
424         BOOST_TEST(!(wp < wp2 || wp2 < wp));
425 
426         sp.reset();
427         BOOST_TEST(!(wp < wp2 || wp2 < wp));
428 
429         boost::weak_ptr<X> wp3(wp);
430         BOOST_TEST(wp3.use_count() == wp.use_count());
431         BOOST_TEST(wp3.use_count() == 0);
432         BOOST_TEST(!(wp < wp3 || wp3 < wp));
433     }
434 
435     {
436         boost::shared_ptr<Z> sp(static_cast<Z*>(0));
437         boost::weak_ptr<Z> wp(sp);
438 
439         boost::weak_ptr<Y> wp2(wp);
440         BOOST_TEST(wp2.use_count() == wp.use_count());
441         BOOST_TEST(wp2.use_count() == 1);
442         BOOST_TEST(!(wp < wp2 || wp2 < wp));
443 
444         sp.reset();
445         BOOST_TEST(!(wp < wp2 || wp2 < wp));
446 
447         boost::weak_ptr<Y> wp3(wp);
448         BOOST_TEST(wp3.use_count() == wp.use_count());
449         BOOST_TEST(wp3.use_count() == 0);
450         BOOST_TEST(!(wp < wp3 || wp3 < wp));
451     }
452 
453     {
454         boost::shared_ptr<Z> sp(new Z);
455         boost::weak_ptr<Z> wp(sp);
456 
457         boost::weak_ptr<X> wp2(wp);
458         BOOST_TEST(wp2.use_count() == wp.use_count());
459         BOOST_TEST(wp2.use_count() == 1);
460         BOOST_TEST(!(wp < wp2 || wp2 < wp));
461 
462         sp.reset();
463         BOOST_TEST(!(wp < wp2 || wp2 < wp));
464 
465         boost::weak_ptr<X> wp3(wp);
466         BOOST_TEST(wp3.use_count() == wp.use_count());
467         BOOST_TEST(wp3.use_count() == 0);
468         BOOST_TEST(!(wp < wp3 || wp3 < wp));
469     }
470 
471     {
472         boost::shared_ptr<Z> sp(new Z);
473         boost::weak_ptr<Z> wp(sp);
474 
475         boost::weak_ptr<Y> wp2(wp);
476         BOOST_TEST(wp2.use_count() == wp.use_count());
477         BOOST_TEST(wp2.use_count() == 1);
478         BOOST_TEST(!(wp < wp2 || wp2 < wp));
479 
480         sp.reset();
481         BOOST_TEST(!(wp < wp2 || wp2 < wp));
482 
483         boost::weak_ptr<Y> wp3(wp);
484         BOOST_TEST(wp3.use_count() == wp.use_count());
485         BOOST_TEST(wp3.use_count() == 0);
486         BOOST_TEST(!(wp < wp3 || wp3 < wp));
487     }
488 }
489 
test()490 void test()
491 {
492     default_constructor();
493     shared_ptr_constructor();
494     copy_constructor();
495     conversion_constructor();
496 }
497 
498 } // namespace n_constructors
499 
500 namespace n_assignment
501 {
502 
copy_assignment(boost::shared_ptr<T> & sp)503 template<class T> void copy_assignment(boost::shared_ptr<T> & sp)
504 {
505     BOOST_TEST(sp.unique());
506 
507     boost::weak_ptr<T> p1;
508 
509     p1 = p1;
510     BOOST_TEST(p1.use_count() == 0);
511 
512     boost::weak_ptr<T> p2;
513 
514     p1 = p2;
515     BOOST_TEST(p1.use_count() == 0);
516 
517     boost::weak_ptr<T> p3(p1);
518 
519     p1 = p3;
520     BOOST_TEST(p1.use_count() == 0);
521 
522     boost::weak_ptr<T> p4(sp);
523 
524     p4 = p4;
525     BOOST_TEST(p4.use_count() == 1);
526 
527     p1 = p4;
528     BOOST_TEST(p1.use_count() == 1);
529 
530     p4 = p2;
531     BOOST_TEST(p4.use_count() == 0);
532 
533     sp.reset();
534 
535     p1 = p1;
536     BOOST_TEST(p1.use_count() == 0);
537 
538     p4 = p1;
539     BOOST_TEST(p4.use_count() == 0);
540 }
541 
conversion_assignment()542 void conversion_assignment()
543 {
544     {
545         boost::weak_ptr<void> p1;
546 
547         boost::weak_ptr<incomplete> p2;
548 
549         p1 = p2;
550         BOOST_TEST(p1.use_count() == 0);
551 
552         boost::shared_ptr<incomplete> sp = create_incomplete();
553         boost::weak_ptr<incomplete> p3(sp);
554 
555         p1 = p3;
556         BOOST_TEST(p1.use_count() == 1);
557 
558         sp.reset();
559 
560         p1 = p3;
561         BOOST_TEST(p1.use_count() == 0);
562 
563         p1 = p2;
564         BOOST_TEST(p1.use_count() == 0);
565     }
566 
567     {
568         boost::weak_ptr<X> p1;
569 
570         boost::weak_ptr<Z> p2;
571 
572         p1 = p2;
573         BOOST_TEST(p1.use_count() == 0);
574 
575         boost::shared_ptr<Z> sp(new Z);
576         boost::weak_ptr<Z> p3(sp);
577 
578         p1 = p3;
579         BOOST_TEST(p1.use_count() == 1);
580 
581         sp.reset();
582 
583         p1 = p3;
584         BOOST_TEST(p1.use_count() == 0);
585 
586         p1 = p2;
587         BOOST_TEST(p1.use_count() == 0);
588     }
589 
590     {
591         boost::weak_ptr<Y> p1;
592 
593         boost::weak_ptr<Z> p2;
594 
595         p1 = p2;
596         BOOST_TEST(p1.use_count() == 0);
597 
598         boost::shared_ptr<Z> sp(new Z);
599         boost::weak_ptr<Z> p3(sp);
600 
601         p1 = p3;
602         BOOST_TEST(p1.use_count() == 1);
603 
604         sp.reset();
605 
606         p1 = p3;
607         BOOST_TEST(p1.use_count() == 0);
608 
609         p1 = p2;
610         BOOST_TEST(p1.use_count() == 0);
611     }
612 }
613 
shared_ptr_assignment(boost::shared_ptr<U> & sp,T * =0)614 template<class T, class U> void shared_ptr_assignment(boost::shared_ptr<U> & sp, T * = 0)
615 {
616     BOOST_TEST(sp.unique());
617 
618     boost::weak_ptr<T> p1;
619     boost::weak_ptr<T> p2(p1);
620     boost::weak_ptr<T> p3(sp);
621     boost::weak_ptr<T> p4(p3);
622 
623     p1 = sp;
624     BOOST_TEST(p1.use_count() == 1);
625 
626     p2 = sp;
627     BOOST_TEST(p2.use_count() == 1);
628 
629     p3 = sp;
630     BOOST_TEST(p3.use_count() == 1);
631 
632     p4 = sp;
633     BOOST_TEST(p4.use_count() == 1);
634 
635     sp.reset();
636 
637     BOOST_TEST(p1.use_count() == 0);
638     BOOST_TEST(p2.use_count() == 0);
639     BOOST_TEST(p3.use_count() == 0);
640     BOOST_TEST(p4.use_count() == 0);
641 
642     p1 = sp;
643 }
644 
test()645 void test()
646 {
647     {
648         boost::shared_ptr<int> p( new int );
649         copy_assignment( p );
650     }
651 
652     {
653         boost::shared_ptr<X> p( new X );
654         copy_assignment( p );
655     }
656 
657     {
658         boost::shared_ptr<void> p( new int );
659         copy_assignment( p );
660     }
661 
662     {
663         boost::shared_ptr<incomplete> p = create_incomplete();
664         copy_assignment( p );
665     }
666 
667     conversion_assignment();
668 
669     {
670         boost::shared_ptr<int> p( new int );
671         shared_ptr_assignment<int>( p );
672     }
673 
674     {
675         boost::shared_ptr<int> p( new int );
676         shared_ptr_assignment<void>( p );
677     }
678 
679     {
680         boost::shared_ptr<X> p( new X );
681         shared_ptr_assignment<X>( p );
682     }
683 
684     {
685         boost::shared_ptr<X> p( new X );
686         shared_ptr_assignment<void>( p );
687     }
688 
689     {
690         boost::shared_ptr<void> p( new int );
691         shared_ptr_assignment<void>( p );
692     }
693 
694     {
695         boost::shared_ptr<incomplete> p = create_incomplete();
696         shared_ptr_assignment<incomplete>( p );
697     }
698 
699     {
700         boost::shared_ptr<incomplete> p = create_incomplete();
701         shared_ptr_assignment<void>( p );
702     }
703 }
704 
705 } // namespace n_assignment
706 
707 namespace n_reset
708 {
709 
test2(boost::shared_ptr<U> & sp,T * =0)710 template<class T, class U> void test2( boost::shared_ptr<U> & sp, T * = 0 )
711 {
712     BOOST_TEST(sp.unique());
713 
714     boost::weak_ptr<T> p1;
715     boost::weak_ptr<T> p2(p1);
716     boost::weak_ptr<T> p3(sp);
717     boost::weak_ptr<T> p4(p3);
718     boost::weak_ptr<T> p5(sp);
719     boost::weak_ptr<T> p6(p5);
720 
721     p1.reset();
722     BOOST_TEST(p1.use_count() == 0);
723 
724     p2.reset();
725     BOOST_TEST(p2.use_count() == 0);
726 
727     p3.reset();
728     BOOST_TEST(p3.use_count() == 0);
729 
730     p4.reset();
731     BOOST_TEST(p4.use_count() == 0);
732 
733     sp.reset();
734 
735     p5.reset();
736     BOOST_TEST(p5.use_count() == 0);
737 
738     p6.reset();
739     BOOST_TEST(p6.use_count() == 0);
740 }
741 
test()742 void test()
743 {
744     {
745         boost::shared_ptr<int> p( new int );
746         test2<int>( p );
747     }
748 
749     {
750         boost::shared_ptr<int> p( new int );
751         test2<void>( p );
752     }
753 
754     {
755         boost::shared_ptr<X> p( new X );
756         test2<X>( p );
757     }
758 
759     {
760         boost::shared_ptr<X> p( new X );
761         test2<void>( p );
762     }
763 
764     {
765         boost::shared_ptr<void> p( new int );
766         test2<void>( p );
767     }
768 
769     {
770         boost::shared_ptr<incomplete> p = create_incomplete();
771         test2<incomplete>( p );
772     }
773 
774     {
775         boost::shared_ptr<incomplete> p = create_incomplete();
776         test2<void>( p );
777     }
778 }
779 
780 } // namespace n_reset
781 
782 namespace n_use_count
783 {
784 
test()785 void test()
786 {
787     {
788         boost::weak_ptr<X> wp;
789         BOOST_TEST(wp.use_count() == 0);
790         BOOST_TEST(wp.expired());
791 
792         boost::weak_ptr<X> wp2;
793         BOOST_TEST(wp.use_count() == 0);
794         BOOST_TEST(wp.expired());
795 
796         boost::weak_ptr<X> wp3(wp);
797         BOOST_TEST(wp.use_count() == 0);
798         BOOST_TEST(wp.expired());
799         BOOST_TEST(wp3.use_count() == 0);
800         BOOST_TEST(wp3.expired());
801     }
802 
803     {
804         boost::shared_ptr<X> sp(static_cast<X*>(0));
805 
806         boost::weak_ptr<X> wp(sp);
807         BOOST_TEST(wp.use_count() == 1);
808         BOOST_TEST(!wp.expired());
809 
810         boost::weak_ptr<X> wp2(sp);
811         BOOST_TEST(wp.use_count() == 1);
812         BOOST_TEST(!wp.expired());
813 
814         boost::weak_ptr<X> wp3(wp);
815         BOOST_TEST(wp.use_count() == 1);
816         BOOST_TEST(!wp.expired());
817         BOOST_TEST(wp3.use_count() == 1);
818         BOOST_TEST(!wp3.expired());
819 
820         boost::shared_ptr<X> sp2(sp);
821 
822         BOOST_TEST(wp.use_count() == 2);
823         BOOST_TEST(!wp.expired());
824         BOOST_TEST(wp2.use_count() == 2);
825         BOOST_TEST(!wp2.expired());
826         BOOST_TEST(wp3.use_count() == 2);
827         BOOST_TEST(!wp3.expired());
828 
829         boost::shared_ptr<void> sp3(sp);
830 
831         BOOST_TEST(wp.use_count() == 3);
832         BOOST_TEST(!wp.expired());
833         BOOST_TEST(wp2.use_count() == 3);
834         BOOST_TEST(!wp2.expired());
835         BOOST_TEST(wp3.use_count() == 3);
836         BOOST_TEST(!wp3.expired());
837 
838         sp.reset();
839 
840         BOOST_TEST(wp.use_count() == 2);
841         BOOST_TEST(!wp.expired());
842         BOOST_TEST(wp2.use_count() == 2);
843         BOOST_TEST(!wp2.expired());
844         BOOST_TEST(wp3.use_count() == 2);
845         BOOST_TEST(!wp3.expired());
846 
847         sp2.reset();
848 
849         BOOST_TEST(wp.use_count() == 1);
850         BOOST_TEST(!wp.expired());
851         BOOST_TEST(wp2.use_count() == 1);
852         BOOST_TEST(!wp2.expired());
853         BOOST_TEST(wp3.use_count() == 1);
854         BOOST_TEST(!wp3.expired());
855 
856         sp3.reset();
857 
858         BOOST_TEST(wp.use_count() == 0);
859         BOOST_TEST(wp.expired());
860         BOOST_TEST(wp2.use_count() == 0);
861         BOOST_TEST(wp2.expired());
862         BOOST_TEST(wp3.use_count() == 0);
863         BOOST_TEST(wp3.expired());
864     }
865 }
866 
867 } // namespace n_use_count
868 
869 namespace n_swap
870 {
871 
test()872 void test()
873 {
874     {
875         boost::weak_ptr<X> wp;
876         boost::weak_ptr<X> wp2;
877 
878         wp.swap(wp2);
879 
880         BOOST_TEST(wp.use_count() == 0);
881         BOOST_TEST(wp2.use_count() == 0);
882 
883         using std::swap;
884         swap(wp, wp2);
885 
886         BOOST_TEST(wp.use_count() == 0);
887         BOOST_TEST(wp2.use_count() == 0);
888     }
889 
890     {
891         boost::shared_ptr<X> sp(new X);
892         boost::weak_ptr<X> wp;
893         boost::weak_ptr<X> wp2(sp);
894         boost::weak_ptr<X> wp3(sp);
895 
896         wp.swap(wp2);
897 
898         BOOST_TEST(wp.use_count() == 1);
899         BOOST_TEST(wp2.use_count() == 0);
900         BOOST_TEST(!(wp < wp3 || wp3 < wp));
901 
902         using std::swap;
903         swap(wp, wp2);
904 
905         BOOST_TEST(wp.use_count() == 0);
906         BOOST_TEST(wp2.use_count() == 1);
907         BOOST_TEST(!(wp2 < wp3 || wp3 < wp2));
908 
909         sp.reset();
910 
911         wp.swap(wp2);
912 
913         BOOST_TEST(wp.use_count() == 0);
914         BOOST_TEST(wp2.use_count() == 0);
915         BOOST_TEST(!(wp < wp3 || wp3 < wp));
916 
917         swap(wp, wp2);
918 
919         BOOST_TEST(wp.use_count() == 0);
920         BOOST_TEST(wp2.use_count() == 0);
921         BOOST_TEST(!(wp2 < wp3 || wp3 < wp2));
922     }
923 
924     {
925         boost::shared_ptr<X> sp(new X);
926         boost::shared_ptr<X> sp2(new X);
927         boost::weak_ptr<X> wp(sp);
928         boost::weak_ptr<X> wp2(sp2);
929         boost::weak_ptr<X> wp3(sp2);
930 
931         wp.swap(wp2);
932 
933         BOOST_TEST(wp.use_count() == 1);
934         BOOST_TEST(wp2.use_count() == 1);
935         BOOST_TEST(!(wp < wp3 || wp3 < wp));
936 
937         using std::swap;
938         swap(wp, wp2);
939 
940         BOOST_TEST(wp.use_count() == 1);
941         BOOST_TEST(wp2.use_count() == 1);
942         BOOST_TEST(!(wp2 < wp3 || wp3 < wp2));
943 
944         sp.reset();
945 
946         wp.swap(wp2);
947 
948         BOOST_TEST(wp.use_count() == 1);
949         BOOST_TEST(wp2.use_count() == 0);
950         BOOST_TEST(!(wp < wp3 || wp3 < wp));
951 
952         swap(wp, wp2);
953 
954         BOOST_TEST(wp.use_count() == 0);
955         BOOST_TEST(wp2.use_count() == 1);
956         BOOST_TEST(!(wp2 < wp3 || wp3 < wp2));
957 
958         sp2.reset();
959 
960         wp.swap(wp2);
961 
962         BOOST_TEST(wp.use_count() == 0);
963         BOOST_TEST(wp2.use_count() == 0);
964         BOOST_TEST(!(wp < wp3 || wp3 < wp));
965 
966         swap(wp, wp2);
967 
968         BOOST_TEST(wp.use_count() == 0);
969         BOOST_TEST(wp2.use_count() == 0);
970         BOOST_TEST(!(wp2 < wp3 || wp3 < wp2));
971     }
972 }
973 
974 } // namespace n_swap
975 
976 namespace n_comparison
977 {
978 
test()979 void test()
980 {
981     {
982         boost::weak_ptr<X> wp;
983         BOOST_TEST(!(wp < wp));
984 
985         boost::weak_ptr<X> wp2;
986         BOOST_TEST(!(wp < wp2 && wp2 < wp));
987 
988         boost::weak_ptr<X> wp3(wp);
989         BOOST_TEST(!(wp3 < wp3));
990         BOOST_TEST(!(wp < wp3 && wp3 < wp));
991     }
992 
993     {
994         boost::shared_ptr<X> sp(new X);
995 
996         boost::weak_ptr<X> wp(sp);
997         BOOST_TEST(!(wp < wp));
998 
999         boost::weak_ptr<X> wp2;
1000         BOOST_TEST(wp < wp2 || wp2 < wp);
1001         BOOST_TEST(!(wp < wp2 && wp2 < wp));
1002 
1003         bool b1 = wp < wp2;
1004         bool b2 = wp2 < wp;
1005 
1006         {
1007             boost::weak_ptr<X> wp3(wp);
1008 
1009             BOOST_TEST(!(wp < wp3 || wp3 < wp));
1010             BOOST_TEST(!(wp < wp3 && wp3 < wp));
1011 
1012             BOOST_TEST(wp2 < wp3 || wp3 < wp2);
1013             BOOST_TEST(!(wp2 < wp3 && wp3 < wp2));
1014 
1015             boost::weak_ptr<X> wp4(wp2);
1016 
1017             BOOST_TEST(wp4 < wp3 || wp3 < wp4);
1018             BOOST_TEST(!(wp4 < wp3 && wp3 < wp4));
1019         }
1020 
1021         sp.reset();
1022 
1023         BOOST_TEST(b1 == (wp < wp2));
1024         BOOST_TEST(b2 == (wp2 < wp));
1025 
1026         {
1027             boost::weak_ptr<X> wp3(wp);
1028 
1029             BOOST_TEST(!(wp < wp3 || wp3 < wp));
1030             BOOST_TEST(!(wp < wp3 && wp3 < wp));
1031 
1032             BOOST_TEST(wp2 < wp3 || wp3 < wp2);
1033             BOOST_TEST(!(wp2 < wp3 && wp3 < wp2));
1034 
1035             boost::weak_ptr<X> wp4(wp2);
1036 
1037             BOOST_TEST(wp4 < wp3 || wp3 < wp4);
1038             BOOST_TEST(!(wp4 < wp3 && wp3 < wp4));
1039         }
1040     }
1041 
1042     {
1043         boost::shared_ptr<X> sp(new X);
1044         boost::shared_ptr<X> sp2(new X);
1045 
1046         boost::weak_ptr<X> wp(sp);
1047         boost::weak_ptr<X> wp2(sp2);
1048 
1049         BOOST_TEST(wp < wp2 || wp2 < wp);
1050         BOOST_TEST(!(wp < wp2 && wp2 < wp));
1051 
1052         bool b1 = wp < wp2;
1053         bool b2 = wp2 < wp;
1054 
1055         {
1056             boost::weak_ptr<X> wp3(wp);
1057 
1058             BOOST_TEST(!(wp < wp3 || wp3 < wp));
1059             BOOST_TEST(!(wp < wp3 && wp3 < wp));
1060 
1061             BOOST_TEST(wp2 < wp3 || wp3 < wp2);
1062             BOOST_TEST(!(wp2 < wp3 && wp3 < wp2));
1063 
1064             boost::weak_ptr<X> wp4(wp2);
1065 
1066             BOOST_TEST(wp4 < wp3 || wp3 < wp4);
1067             BOOST_TEST(!(wp4 < wp3 && wp3 < wp4));
1068         }
1069 
1070         sp.reset();
1071 
1072         BOOST_TEST(b1 == (wp < wp2));
1073         BOOST_TEST(b2 == (wp2 < wp));
1074 
1075         {
1076             boost::weak_ptr<X> wp3(wp);
1077 
1078             BOOST_TEST(!(wp < wp3 || wp3 < wp));
1079             BOOST_TEST(!(wp < wp3 && wp3 < wp));
1080 
1081             BOOST_TEST(wp2 < wp3 || wp3 < wp2);
1082             BOOST_TEST(!(wp2 < wp3 && wp3 < wp2));
1083 
1084             boost::weak_ptr<X> wp4(wp2);
1085 
1086             BOOST_TEST(wp4 < wp3 || wp3 < wp4);
1087             BOOST_TEST(!(wp4 < wp3 && wp3 < wp4));
1088         }
1089 
1090         sp2.reset();
1091 
1092         BOOST_TEST(b1 == (wp < wp2));
1093         BOOST_TEST(b2 == (wp2 < wp));
1094 
1095         {
1096             boost::weak_ptr<X> wp3(wp);
1097 
1098             BOOST_TEST(!(wp < wp3 || wp3 < wp));
1099             BOOST_TEST(!(wp < wp3 && wp3 < wp));
1100 
1101             BOOST_TEST(wp2 < wp3 || wp3 < wp2);
1102             BOOST_TEST(!(wp2 < wp3 && wp3 < wp2));
1103 
1104             boost::weak_ptr<X> wp4(wp2);
1105 
1106             BOOST_TEST(wp4 < wp3 || wp3 < wp4);
1107             BOOST_TEST(!(wp4 < wp3 && wp3 < wp4));
1108         }
1109     }
1110 
1111     {
1112         boost::shared_ptr<X> sp(new X);
1113         boost::shared_ptr<X> sp2(sp);
1114 
1115         boost::weak_ptr<X> wp(sp);
1116         boost::weak_ptr<X> wp2(sp2);
1117 
1118         BOOST_TEST(!(wp < wp2 || wp2 < wp));
1119         BOOST_TEST(!(wp < wp2 && wp2 < wp));
1120 
1121         bool b1 = wp < wp2;
1122         bool b2 = wp2 < wp;
1123 
1124         {
1125             boost::weak_ptr<X> wp3(wp);
1126 
1127             BOOST_TEST(!(wp < wp3 || wp3 < wp));
1128             BOOST_TEST(!(wp < wp3 && wp3 < wp));
1129 
1130             BOOST_TEST(!(wp2 < wp3 || wp3 < wp2));
1131             BOOST_TEST(!(wp2 < wp3 && wp3 < wp2));
1132 
1133             boost::weak_ptr<X> wp4(wp2);
1134 
1135             BOOST_TEST(!(wp4 < wp3 || wp3 < wp4));
1136             BOOST_TEST(!(wp4 < wp3 && wp3 < wp4));
1137         }
1138 
1139         sp.reset();
1140         sp2.reset();
1141 
1142         BOOST_TEST(b1 == (wp < wp2));
1143         BOOST_TEST(b2 == (wp2 < wp));
1144 
1145         {
1146             boost::weak_ptr<X> wp3(wp);
1147 
1148             BOOST_TEST(!(wp < wp3 || wp3 < wp));
1149             BOOST_TEST(!(wp < wp3 && wp3 < wp));
1150 
1151             BOOST_TEST(!(wp2 < wp3 || wp3 < wp2));
1152             BOOST_TEST(!(wp2 < wp3 && wp3 < wp2));
1153 
1154             boost::weak_ptr<X> wp4(wp2);
1155 
1156             BOOST_TEST(!(wp4 < wp3 || wp3 < wp4));
1157             BOOST_TEST(!(wp4 < wp3 && wp3 < wp4));
1158         }
1159     }
1160 
1161     {
1162         boost::shared_ptr<X> spx(new X);
1163         boost::shared_ptr<Y> spy(new Y);
1164         boost::shared_ptr<Z> spz(new Z);
1165 
1166         boost::weak_ptr<X> px(spx);
1167         boost::weak_ptr<Y> py(spy);
1168         boost::weak_ptr<Z> pz(spz);
1169 
1170         BOOST_TEST(px < py || py < px);
1171         BOOST_TEST(px < pz || pz < px);
1172         BOOST_TEST(py < pz || pz < py);
1173 
1174         BOOST_TEST(!(px < py && py < px));
1175         BOOST_TEST(!(px < pz && pz < px));
1176         BOOST_TEST(!(py < pz && pz < py));
1177 
1178         boost::weak_ptr<void> pvx(px);
1179         BOOST_TEST(!(pvx < pvx));
1180 
1181         boost::weak_ptr<void> pvy(py);
1182         BOOST_TEST(!(pvy < pvy));
1183 
1184         boost::weak_ptr<void> pvz(pz);
1185         BOOST_TEST(!(pvz < pvz));
1186 
1187         BOOST_TEST(pvx < pvy || pvy < pvx);
1188         BOOST_TEST(pvx < pvz || pvz < pvx);
1189         BOOST_TEST(pvy < pvz || pvz < pvy);
1190 
1191         BOOST_TEST(!(pvx < pvy && pvy < pvx));
1192         BOOST_TEST(!(pvx < pvz && pvz < pvx));
1193         BOOST_TEST(!(pvy < pvz && pvz < pvy));
1194 
1195         spx.reset();
1196         spy.reset();
1197         spz.reset();
1198 
1199         BOOST_TEST(px < py || py < px);
1200         BOOST_TEST(px < pz || pz < px);
1201         BOOST_TEST(py < pz || pz < py);
1202 
1203         BOOST_TEST(!(px < py && py < px));
1204         BOOST_TEST(!(px < pz && pz < px));
1205         BOOST_TEST(!(py < pz && pz < py));
1206 
1207         BOOST_TEST(!(pvx < pvx));
1208         BOOST_TEST(!(pvy < pvy));
1209         BOOST_TEST(!(pvz < pvz));
1210 
1211         BOOST_TEST(pvx < pvy || pvy < pvx);
1212         BOOST_TEST(pvx < pvz || pvz < pvx);
1213         BOOST_TEST(pvy < pvz || pvz < pvy);
1214 
1215         BOOST_TEST(!(pvx < pvy && pvy < pvx));
1216         BOOST_TEST(!(pvx < pvz && pvz < pvx));
1217         BOOST_TEST(!(pvy < pvz && pvz < pvy));
1218     }
1219 
1220     {
1221         boost::shared_ptr<Z> spz(new Z);
1222         boost::shared_ptr<X> spx(spz);
1223 
1224         boost::weak_ptr<Z> pz(spz);
1225         boost::weak_ptr<X> px(spx);
1226         boost::weak_ptr<Y> py(spz);
1227 
1228         BOOST_TEST(!(px < px));
1229         BOOST_TEST(!(py < py));
1230 
1231         BOOST_TEST(!(px < py || py < px));
1232         BOOST_TEST(!(px < pz || pz < px));
1233         BOOST_TEST(!(py < pz || pz < py));
1234 
1235         boost::weak_ptr<void> pvx(px);
1236         boost::weak_ptr<void> pvy(py);
1237         boost::weak_ptr<void> pvz(pz);
1238 
1239         BOOST_TEST(!(pvx < pvy || pvy < pvx));
1240         BOOST_TEST(!(pvx < pvz || pvz < pvx));
1241         BOOST_TEST(!(pvy < pvz || pvz < pvy));
1242 
1243         spx.reset();
1244         spz.reset();
1245 
1246         BOOST_TEST(!(px < px));
1247         BOOST_TEST(!(py < py));
1248 
1249         BOOST_TEST(!(px < py || py < px));
1250         BOOST_TEST(!(px < pz || pz < px));
1251         BOOST_TEST(!(py < pz || pz < py));
1252 
1253         BOOST_TEST(!(pvx < pvy || pvy < pvx));
1254         BOOST_TEST(!(pvx < pvz || pvz < pvx));
1255         BOOST_TEST(!(pvy < pvz || pvz < pvy));
1256     }
1257 }
1258 
1259 } // namespace n_comparison
1260 
1261 namespace n_lock
1262 {
1263 
test()1264 void test()
1265 {
1266 }
1267 
1268 } // namespace n_lock
1269 
1270 namespace n_map
1271 {
1272 
test()1273 void test()
1274 {
1275     std::vector< boost::shared_ptr<int> > vi;
1276 
1277     {
1278         boost::shared_ptr<int> pi1(new int);
1279         boost::shared_ptr<int> pi2(new int);
1280         boost::shared_ptr<int> pi3(new int);
1281 
1282         vi.push_back(pi1);
1283         vi.push_back(pi1);
1284         vi.push_back(pi1);
1285         vi.push_back(pi2);
1286         vi.push_back(pi1);
1287         vi.push_back(pi2);
1288         vi.push_back(pi1);
1289         vi.push_back(pi3);
1290         vi.push_back(pi3);
1291         vi.push_back(pi2);
1292         vi.push_back(pi1);
1293     }
1294 
1295     std::vector< boost::shared_ptr<X> > vx;
1296 
1297     {
1298         boost::shared_ptr<X> px1(new X);
1299         boost::shared_ptr<X> px2(new X);
1300         boost::shared_ptr<X> px3(new X);
1301 
1302         vx.push_back(px2);
1303         vx.push_back(px2);
1304         vx.push_back(px1);
1305         vx.push_back(px2);
1306         vx.push_back(px1);
1307         vx.push_back(px1);
1308         vx.push_back(px1);
1309         vx.push_back(px2);
1310         vx.push_back(px1);
1311         vx.push_back(px3);
1312         vx.push_back(px2);
1313     }
1314 
1315     std::map< boost::weak_ptr<void>, long > m;
1316 
1317     {
1318         for(std::vector< boost::shared_ptr<int> >::iterator i = vi.begin(); i != vi.end(); ++i)
1319         {
1320             ++m[*i];
1321         }
1322     }
1323 
1324     {
1325         for(std::vector< boost::shared_ptr<X> >::iterator i = vx.begin(); i != vx.end(); ++i)
1326         {
1327             ++m[*i];
1328         }
1329     }
1330 
1331     {
1332         for(std::map< boost::weak_ptr<void>, long >::iterator i = m.begin(); i != m.end(); ++i)
1333         {
1334             BOOST_TEST(i->first.use_count() == i->second);
1335         }
1336     }
1337 }
1338 
1339 } // namespace n_map
1340 
main()1341 int main()
1342 {
1343     n_element_type::test();
1344     n_constructors::test();
1345     n_assignment::test();
1346     n_reset::test();
1347     n_use_count::test();
1348     n_swap::test();
1349     n_comparison::test();
1350     n_lock::test();
1351 
1352     n_map::test();
1353 
1354     return boost::report_errors();
1355 }
1356 
1357 class incomplete
1358 {
1359 };
1360 
create_incomplete()1361 boost::shared_ptr<incomplete> create_incomplete()
1362 {
1363     boost::shared_ptr<incomplete> px(new incomplete);
1364     return px;
1365 }
1366