Apply patch for [CVE-2012-2677][boost] ordered_malloc() overflow
[external/boost.git] / libs / smart_ptr / test / weak_ptr_test.cpp
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
40 void f(int &)
41 {
42 }
43
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
1264 void test()
1265 {
1266 }
1267
1268 } // namespace n_lock
1269
1270 namespace n_map
1271 {
1272
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
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
1361 boost::shared_ptr<incomplete> create_incomplete()
1362 {
1363     boost::shared_ptr<incomplete> px(new incomplete);
1364     return px;
1365 }