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 //  shared_ptr_test.cpp
19 //
20 //  Copyright (c) 2002, 2003 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::shared_ptr<int>::element_type T;
47     T t;
48     f(t);
49 }
50 
51 } // namespace n_element_type
52 
53 namespace n_constructors
54 {
55 
56 class incomplete;
57 
default_constructor()58 void default_constructor()
59 {
60     {
61         boost::shared_ptr<int> pi;
62         BOOST_TEST(pi? false: true);
63         BOOST_TEST(!pi);
64         BOOST_TEST(pi.get() == 0);
65         BOOST_TEST(pi.use_count() == 0);
66     }
67 
68     {
69         boost::shared_ptr<void> pv;
70         BOOST_TEST(pv? false: true);
71         BOOST_TEST(!pv);
72         BOOST_TEST(pv.get() == 0);
73         BOOST_TEST(pv.use_count() == 0);
74     }
75 
76     {
77         boost::shared_ptr<incomplete> px;
78         BOOST_TEST(px? false: true);
79         BOOST_TEST(!px);
80         BOOST_TEST(px.get() == 0);
81         BOOST_TEST(px.use_count() == 0);
82     }
83 }
84 
85 struct A
86 {
87     int dummy;
88 };
89 
90 struct X
91 {
92     static long instances;
93 
Xn_constructors::X94     X()
95     {
96         ++instances;
97     }
98 
~Xn_constructors::X99     ~X()
100     {
101         --instances;
102     }
103 
104 private:
105 
106     X(X const &);
107     X & operator= (X const &);
108 };
109 
110 long X::instances = 0;
111 
112 // virtual inheritance stresses the implementation
113 
114 struct Y: public A, public virtual X
115 {
116     static long instances;
117 
Yn_constructors::Y118     Y()
119     {
120         ++instances;
121     }
122 
~Yn_constructors::Y123     ~Y()
124     {
125         --instances;
126     }
127 
128 private:
129 
130     Y(Y const &);
131     Y & operator= (Y const &);
132 };
133 
134 long Y::instances = 0;
135 
pc0_test(T * p)136 template<class T> void pc0_test(T * p)
137 {
138     BOOST_TEST(p == 0);
139     boost::shared_ptr<T> pt(p);
140     BOOST_TEST(pt? false: true);
141     BOOST_TEST(!pt);
142     BOOST_TEST(pt.get() == 0);
143     BOOST_TEST(pt.use_count() == 1);
144     BOOST_TEST(pt.unique());
145 }
146 
pointer_constructor()147 void pointer_constructor()
148 {
149     pc0_test(static_cast<int*>(0));
150 
151 #if !defined(BOOST_MSVC) || (BOOST_MSVC > 1300)
152 
153     pc0_test(static_cast<int const*>(0));
154     pc0_test(static_cast<int volatile*>(0));
155     pc0_test(static_cast<int const volatile*>(0));
156 
157 #endif
158 
159     {
160         boost::shared_ptr<int const> pi(static_cast<int*>(0));
161         BOOST_TEST(pi? false: true);
162         BOOST_TEST(!pi);
163         BOOST_TEST(pi.get() == 0);
164         BOOST_TEST(pi.use_count() == 1);
165         BOOST_TEST(pi.unique());
166     }
167 
168     {
169         boost::shared_ptr<int volatile> pi(static_cast<int*>(0));
170         BOOST_TEST(pi? false: true);
171         BOOST_TEST(!pi);
172         BOOST_TEST(pi.get() == 0);
173         BOOST_TEST(pi.use_count() == 1);
174         BOOST_TEST(pi.unique());
175     }
176 
177     {
178         boost::shared_ptr<void> pv(static_cast<int*>(0));
179         BOOST_TEST(pv? false: true);
180         BOOST_TEST(!pv);
181         BOOST_TEST(pv.get() == 0);
182         BOOST_TEST(pv.use_count() == 1);
183         BOOST_TEST(pv.unique());
184     }
185 
186     {
187         boost::shared_ptr<void const> pv(static_cast<int*>(0));
188         BOOST_TEST(pv? false: true);
189         BOOST_TEST(!pv);
190         BOOST_TEST(pv.get() == 0);
191         BOOST_TEST(pv.use_count() == 1);
192         BOOST_TEST(pv.unique());
193     }
194 
195     pc0_test(static_cast<X*>(0));
196     pc0_test(static_cast<X const*>(0));
197     pc0_test(static_cast<X volatile*>(0));
198     pc0_test(static_cast<X const volatile*>(0));
199 
200     {
201         boost::shared_ptr<X const> px(static_cast<X*>(0));
202         BOOST_TEST(px? false: true);
203         BOOST_TEST(!px);
204         BOOST_TEST(px.get() == 0);
205         BOOST_TEST(px.use_count() == 1);
206         BOOST_TEST(px.unique());
207     }
208 
209     {
210         boost::shared_ptr<X> px(static_cast<Y*>(0));
211         BOOST_TEST(px? false: true);
212         BOOST_TEST(!px);
213         BOOST_TEST(px.get() == 0);
214         BOOST_TEST(px.use_count() == 1);
215         BOOST_TEST(px.unique());
216     }
217 
218     {
219         boost::shared_ptr<X const> px(static_cast<Y*>(0));
220         BOOST_TEST(px? false: true);
221         BOOST_TEST(!px);
222         BOOST_TEST(px.get() == 0);
223         BOOST_TEST(px.use_count() == 1);
224         BOOST_TEST(px.unique());
225     }
226 
227     {
228         boost::shared_ptr<void> pv(static_cast<X*>(0));
229         BOOST_TEST(pv? false: true);
230         BOOST_TEST(!pv);
231         BOOST_TEST(pv.get() == 0);
232         BOOST_TEST(pv.use_count() == 1);
233         BOOST_TEST(pv.unique());
234     }
235 
236     {
237         boost::shared_ptr<void const> pv(static_cast<X*>(0));
238         BOOST_TEST(pv? false: true);
239         BOOST_TEST(!pv);
240         BOOST_TEST(pv.get() == 0);
241         BOOST_TEST(pv.use_count() == 1);
242         BOOST_TEST(pv.unique());
243     }
244 
245     {
246         int * p = new int(7);
247         boost::shared_ptr<int> pi(p);
248         BOOST_TEST(pi? true: false);
249         BOOST_TEST(!!pi);
250         BOOST_TEST(pi.get() == p);
251         BOOST_TEST(pi.use_count() == 1);
252         BOOST_TEST(pi.unique());
253         BOOST_TEST(*pi == 7);
254     }
255 
256     {
257         int * p = new int(7);
258         boost::shared_ptr<int const> pi(p);
259         BOOST_TEST(pi? true: false);
260         BOOST_TEST(!!pi);
261         BOOST_TEST(pi.get() == p);
262         BOOST_TEST(pi.use_count() == 1);
263         BOOST_TEST(pi.unique());
264         BOOST_TEST(*pi == 7);
265     }
266 
267     {
268         int * p = new int(7);
269         boost::shared_ptr<void> pv(p);
270         BOOST_TEST(pv? true: false);
271         BOOST_TEST(!!pv);
272         BOOST_TEST(pv.get() == p);
273         BOOST_TEST(pv.use_count() == 1);
274         BOOST_TEST(pv.unique());
275     }
276 
277     {
278         int * p = new int(7);
279         boost::shared_ptr<void const> pv(p);
280         BOOST_TEST(pv? true: false);
281         BOOST_TEST(!!pv);
282         BOOST_TEST(pv.get() == p);
283         BOOST_TEST(pv.use_count() == 1);
284         BOOST_TEST(pv.unique());
285     }
286 
287     BOOST_TEST(X::instances == 0);
288 
289     {
290         X * p = new X;
291         boost::shared_ptr<X> px(p);
292         BOOST_TEST(px? true: false);
293         BOOST_TEST(!!px);
294         BOOST_TEST(px.get() == p);
295         BOOST_TEST(px.use_count() == 1);
296         BOOST_TEST(px.unique());
297         BOOST_TEST(X::instances == 1);
298     }
299 
300     BOOST_TEST(X::instances == 0);
301 
302     {
303         X * p = new X;
304         boost::shared_ptr<X const> px(p);
305         BOOST_TEST(px? true: false);
306         BOOST_TEST(!!px);
307         BOOST_TEST(px.get() == p);
308         BOOST_TEST(px.use_count() == 1);
309         BOOST_TEST(px.unique());
310         BOOST_TEST(X::instances == 1);
311     }
312 
313     BOOST_TEST(X::instances == 0);
314 
315     {
316         X * p = new X;
317         boost::shared_ptr<void> pv(p);
318         BOOST_TEST(pv? true: false);
319         BOOST_TEST(!!pv);
320         BOOST_TEST(pv.get() == p);
321         BOOST_TEST(pv.use_count() == 1);
322         BOOST_TEST(pv.unique());
323         BOOST_TEST(X::instances == 1);
324     }
325 
326     BOOST_TEST(X::instances == 0);
327 
328     {
329         X * p = new X;
330         boost::shared_ptr<void const> pv(p);
331         BOOST_TEST(pv? true: false);
332         BOOST_TEST(!!pv);
333         BOOST_TEST(pv.get() == p);
334         BOOST_TEST(pv.use_count() == 1);
335         BOOST_TEST(pv.unique());
336         BOOST_TEST(X::instances == 1);
337     }
338 
339     BOOST_TEST(X::instances == 0);
340     BOOST_TEST(Y::instances == 0);
341 
342     {
343         Y * p = new Y;
344         boost::shared_ptr<X> px(p);
345         BOOST_TEST(px? true: false);
346         BOOST_TEST(!!px);
347         BOOST_TEST(px.get() == p);
348         BOOST_TEST(px.use_count() == 1);
349         BOOST_TEST(px.unique());
350         BOOST_TEST(X::instances == 1);
351         BOOST_TEST(Y::instances == 1);
352     }
353 
354     BOOST_TEST(X::instances == 0);
355     BOOST_TEST(Y::instances == 0);
356 
357     {
358         Y * p = new Y;
359         boost::shared_ptr<X const> px(p);
360         BOOST_TEST(px? true: false);
361         BOOST_TEST(!!px);
362         BOOST_TEST(px.get() == p);
363         BOOST_TEST(px.use_count() == 1);
364         BOOST_TEST(px.unique());
365         BOOST_TEST(X::instances == 1);
366         BOOST_TEST(Y::instances == 1);
367     }
368 
369     BOOST_TEST(X::instances == 0);
370     BOOST_TEST(Y::instances == 0);
371 }
372 
373 int m = 0;
374 
deleter(int * p)375 void deleter(int * p)
376 {
377     BOOST_TEST(p == 0);
378 }
379 
deleter2(int * p)380 void deleter2(int * p)
381 {
382     BOOST_TEST(p == &m);
383     ++*p;
384 }
385 
386 struct deleter3
387 {
operator ()n_constructors::deleter3388     void operator()(incomplete * p)
389     {
390         BOOST_TEST(p == 0);
391     }
392 };
393 
394 // Borland C++ 5.5.1 fails on static_cast<incomplete*>(0)
395 
396 incomplete * p0 = 0;
397 
deleter_constructor()398 void deleter_constructor()
399 {
400     {
401         boost::shared_ptr<int> pi(static_cast<int*>(0), deleter);
402         BOOST_TEST(pi? false: true);
403         BOOST_TEST(!pi);
404         BOOST_TEST(pi.get() == 0);
405         BOOST_TEST(pi.use_count() == 1);
406         BOOST_TEST(pi.unique());
407     }
408 
409     {
410         boost::shared_ptr<void> pv(static_cast<int*>(0), &deleter);
411         BOOST_TEST(pv? false: true);
412         BOOST_TEST(!pv);
413         BOOST_TEST(pv.get() == 0);
414         BOOST_TEST(pv.use_count() == 1);
415         BOOST_TEST(pv.unique());
416     }
417 
418     {
419         boost::shared_ptr<void const> pv(static_cast<int*>(0), deleter);
420         BOOST_TEST(pv? false: true);
421         BOOST_TEST(!pv);
422         BOOST_TEST(pv.get() == 0);
423         BOOST_TEST(pv.use_count() == 1);
424         BOOST_TEST(pv.unique());
425     }
426 
427     {
428         boost::shared_ptr<incomplete> px(p0, deleter3());
429         BOOST_TEST(px? false: true);
430         BOOST_TEST(!px);
431         BOOST_TEST(px.get() == 0);
432         BOOST_TEST(px.use_count() == 1);
433         BOOST_TEST(px.unique());
434     }
435 
436     {
437         boost::shared_ptr<void> pv(p0, deleter3());
438         BOOST_TEST(pv? false: true);
439         BOOST_TEST(!pv);
440         BOOST_TEST(pv.get() == 0);
441         BOOST_TEST(pv.use_count() == 1);
442         BOOST_TEST(pv.unique());
443     }
444 
445     {
446         boost::shared_ptr<void const> pv(p0, deleter3());
447         BOOST_TEST(pv? false: true);
448         BOOST_TEST(!pv);
449         BOOST_TEST(pv.get() == 0);
450         BOOST_TEST(pv.use_count() == 1);
451         BOOST_TEST(pv.unique());
452     }
453 
454     BOOST_TEST(m == 0);
455 
456     {
457         boost::shared_ptr<int> pi(&m, deleter2);
458         BOOST_TEST(pi? true: false);
459         BOOST_TEST(!!pi);
460         BOOST_TEST(pi.get() == &m);
461         BOOST_TEST(pi.use_count() == 1);
462         BOOST_TEST(pi.unique());
463     }
464 
465     BOOST_TEST(m == 1);
466 
467     {
468         boost::shared_ptr<int const> pi(&m, &deleter2);
469         BOOST_TEST(pi? true: false);
470         BOOST_TEST(!!pi);
471         BOOST_TEST(pi.get() == &m);
472         BOOST_TEST(pi.use_count() == 1);
473         BOOST_TEST(pi.unique());
474     }
475 
476     BOOST_TEST(m == 2);
477 
478     {
479         boost::shared_ptr<void> pv(&m, deleter2);
480         BOOST_TEST(pv? true: false);
481         BOOST_TEST(!!pv);
482         BOOST_TEST(pv.get() == &m);
483         BOOST_TEST(pv.use_count() == 1);
484         BOOST_TEST(pv.unique());
485     }
486 
487     BOOST_TEST(m == 3);
488 
489     {
490         boost::shared_ptr<void const> pv(&m, &deleter2);
491         BOOST_TEST(pv? true: false);
492         BOOST_TEST(!!pv);
493         BOOST_TEST(pv.get() == &m);
494         BOOST_TEST(pv.use_count() == 1);
495         BOOST_TEST(pv.unique());
496     }
497 
498     BOOST_TEST(m == 4);
499 }
500 
copy_constructor()501 void copy_constructor()
502 {
503     {
504         boost::shared_ptr<int> pi;
505 
506         boost::shared_ptr<int> pi2(pi);
507         BOOST_TEST(pi2 == pi);
508         BOOST_TEST(pi2? false: true);
509         BOOST_TEST(!pi2);
510         BOOST_TEST(pi2.get() == 0);
511         BOOST_TEST(pi2.use_count() == pi.use_count());
512 
513         boost::shared_ptr<void> pi3(pi);
514         BOOST_TEST(pi3 == pi);
515         BOOST_TEST(pi3? false: true);
516         BOOST_TEST(!pi3);
517         BOOST_TEST(pi3.get() == 0);
518         BOOST_TEST(pi3.use_count() == pi.use_count());
519 
520         boost::shared_ptr<void> pi4(pi3);
521         BOOST_TEST(pi4 == pi3);
522         BOOST_TEST(pi4? false: true);
523         BOOST_TEST(!pi4);
524         BOOST_TEST(pi4.get() == 0);
525         BOOST_TEST(pi4.use_count() == pi3.use_count());
526     }
527 
528     {
529         boost::shared_ptr<void> pv;
530 
531         boost::shared_ptr<void> pv2(pv);
532         BOOST_TEST(pv2 == pv);
533         BOOST_TEST(pv2? false: true);
534         BOOST_TEST(!pv2);
535         BOOST_TEST(pv2.get() == 0);
536         BOOST_TEST(pv2.use_count() == pv.use_count());
537     }
538 
539     {
540         boost::shared_ptr<incomplete> px;
541 
542         boost::shared_ptr<incomplete> px2(px);
543         BOOST_TEST(px2 == px);
544         BOOST_TEST(px2? false: true);
545         BOOST_TEST(!px2);
546         BOOST_TEST(px2.get() == 0);
547         BOOST_TEST(px2.use_count() == px.use_count());
548 
549         boost::shared_ptr<void> px3(px);
550         BOOST_TEST(px3 == px);
551         BOOST_TEST(px3? false: true);
552         BOOST_TEST(!px3);
553         BOOST_TEST(px3.get() == 0);
554         BOOST_TEST(px3.use_count() == px.use_count());
555     }
556 
557     {
558         boost::shared_ptr<int> pi(static_cast<int*>(0));
559 
560         boost::shared_ptr<int> pi2(pi);
561         BOOST_TEST(pi2 == pi);
562         BOOST_TEST(pi2? false: true);
563         BOOST_TEST(!pi2);
564         BOOST_TEST(pi2.get() == 0);
565         BOOST_TEST(pi2.use_count() == 2);
566         BOOST_TEST(!pi2.unique());
567         BOOST_TEST(pi2.use_count() == pi.use_count());
568         BOOST_TEST(!(pi < pi2 || pi2 < pi)); // shared ownership test
569 
570         boost::shared_ptr<void> pi3(pi);
571         BOOST_TEST(pi3 == pi);
572         BOOST_TEST(pi3? false: true);
573         BOOST_TEST(!pi3);
574         BOOST_TEST(pi3.get() == 0);
575         BOOST_TEST(pi3.use_count() == 3);
576         BOOST_TEST(!pi3.unique());
577         BOOST_TEST(pi3.use_count() == pi.use_count());
578         BOOST_TEST(!(pi < pi3 || pi3 < pi)); // shared ownership test
579 
580         boost::shared_ptr<void> pi4(pi2);
581         BOOST_TEST(pi4 == pi2);
582         BOOST_TEST(pi4? false: true);
583         BOOST_TEST(!pi4);
584         BOOST_TEST(pi4.get() == 0);
585         BOOST_TEST(pi4.use_count() == 4);
586         BOOST_TEST(!pi4.unique());
587         BOOST_TEST(pi4.use_count() == pi2.use_count());
588         BOOST_TEST(!(pi2 < pi4 || pi4 < pi2)); // shared ownership test
589 
590         BOOST_TEST(pi3.use_count() == pi4.use_count());
591         BOOST_TEST(!(pi3 < pi4 || pi4 < pi3)); // shared ownership test
592     }
593 
594     {
595         boost::shared_ptr<X> px(static_cast<X*>(0));
596 
597         boost::shared_ptr<X> px2(px);
598         BOOST_TEST(px2 == px);
599         BOOST_TEST(px2? false: true);
600         BOOST_TEST(!px2);
601         BOOST_TEST(px2.get() == 0);
602         BOOST_TEST(px2.use_count() == 2);
603         BOOST_TEST(!px2.unique());
604         BOOST_TEST(px2.use_count() == px.use_count());
605         BOOST_TEST(!(px < px2 || px2 < px)); // shared ownership test
606 
607         boost::shared_ptr<void> px3(px);
608         BOOST_TEST(px3 == px);
609         BOOST_TEST(px3? false: true);
610         BOOST_TEST(!px3);
611         BOOST_TEST(px3.get() == 0);
612         BOOST_TEST(px3.use_count() == 3);
613         BOOST_TEST(!px3.unique());
614         BOOST_TEST(px3.use_count() == px.use_count());
615         BOOST_TEST(!(px < px3 || px3 < px)); // shared ownership test
616 
617         boost::shared_ptr<void> px4(px2);
618         BOOST_TEST(px4 == px2);
619         BOOST_TEST(px4? false: true);
620         BOOST_TEST(!px4);
621         BOOST_TEST(px4.get() == 0);
622         BOOST_TEST(px4.use_count() == 4);
623         BOOST_TEST(!px4.unique());
624         BOOST_TEST(px4.use_count() == px2.use_count());
625         BOOST_TEST(!(px2 < px4 || px4 < px2)); // shared ownership test
626 
627         BOOST_TEST(px3.use_count() == px4.use_count());
628         BOOST_TEST(!(px3 < px4 || px4 < px3)); // shared ownership test
629     }
630 
631     {
632         int * p = new int(7);
633         boost::shared_ptr<int> pi(p);
634 
635         boost::shared_ptr<int> pi2(pi);
636         BOOST_TEST(pi2 == pi);
637         BOOST_TEST(pi2? true: false);
638         BOOST_TEST(!!pi2);
639         BOOST_TEST(pi2.get() == p);
640         BOOST_TEST(pi2.use_count() == 2);
641         BOOST_TEST(!pi2.unique());
642         BOOST_TEST(*pi2 == 7);
643         BOOST_TEST(pi2.use_count() == pi.use_count());
644         BOOST_TEST(!(pi < pi2 || pi2 < pi)); // shared ownership test
645     }
646 
647     {
648         int * p = new int(7);
649         boost::shared_ptr<void> pv(p);
650         BOOST_TEST(pv.get() == p);
651 
652         boost::shared_ptr<void> pv2(pv);
653         BOOST_TEST(pv2 == pv);
654         BOOST_TEST(pv2? true: false);
655         BOOST_TEST(!!pv2);
656         BOOST_TEST(pv2.get() == p);
657         BOOST_TEST(pv2.use_count() == 2);
658         BOOST_TEST(!pv2.unique());
659         BOOST_TEST(pv2.use_count() == pv.use_count());
660         BOOST_TEST(!(pv < pv2 || pv2 < pv)); // shared ownership test
661     }
662 
663     BOOST_TEST(X::instances == 0);
664 
665     {
666         X * p = new X;
667         boost::shared_ptr<X> px(p);
668         BOOST_TEST(px.get() == p);
669 
670         boost::shared_ptr<X> px2(px);
671         BOOST_TEST(px2 == px);
672         BOOST_TEST(px2? true: false);
673         BOOST_TEST(!!px2);
674         BOOST_TEST(px2.get() == p);
675         BOOST_TEST(px2.use_count() == 2);
676         BOOST_TEST(!px2.unique());
677 
678         BOOST_TEST(X::instances == 1);
679 
680         BOOST_TEST(px2.use_count() == px.use_count());
681         BOOST_TEST(!(px < px2 || px2 < px)); // shared ownership test
682 
683         boost::shared_ptr<void> px3(px);
684         BOOST_TEST(px3 == px);
685         BOOST_TEST(px3? true: false);
686         BOOST_TEST(!!px3);
687         BOOST_TEST(px3.get() == p);
688         BOOST_TEST(px3.use_count() == 3);
689         BOOST_TEST(!px3.unique());
690         BOOST_TEST(px3.use_count() == px.use_count());
691         BOOST_TEST(!(px < px3 || px3 < px)); // shared ownership test
692 
693         boost::shared_ptr<void> px4(px2);
694         BOOST_TEST(px4 == px2);
695         BOOST_TEST(px4? true: false);
696         BOOST_TEST(!!px4);
697         BOOST_TEST(px4.get() == p);
698         BOOST_TEST(px4.use_count() == 4);
699         BOOST_TEST(!px4.unique());
700         BOOST_TEST(px4.use_count() == px2.use_count());
701         BOOST_TEST(!(px2 < px4 || px4 < px2)); // shared ownership test
702 
703         BOOST_TEST(px3.use_count() == px4.use_count());
704         BOOST_TEST(!(px3 < px4 || px4 < px3)); // shared ownership test
705     }
706 
707     BOOST_TEST(X::instances == 0);
708     BOOST_TEST(Y::instances == 0);
709 
710     {
711         Y * p = new Y;
712         boost::shared_ptr<Y> py(p);
713         BOOST_TEST(py.get() == p);
714 
715         boost::shared_ptr<X> px(py);
716         BOOST_TEST(px == py);
717         BOOST_TEST(px? true: false);
718         BOOST_TEST(!!px);
719         BOOST_TEST(px.get() == p);
720         BOOST_TEST(px.use_count() == 2);
721         BOOST_TEST(!px.unique());
722         BOOST_TEST(px.use_count() == py.use_count());
723         BOOST_TEST(!(px < py || py < px)); // shared ownership test
724 
725         BOOST_TEST(X::instances == 1);
726         BOOST_TEST(Y::instances == 1);
727 
728         boost::shared_ptr<void const> pv(px);
729         BOOST_TEST(pv == px);
730         BOOST_TEST(pv? true: false);
731         BOOST_TEST(!!pv);
732         BOOST_TEST(pv.get() == px.get());
733         BOOST_TEST(pv.use_count() == 3);
734         BOOST_TEST(!pv.unique());
735         BOOST_TEST(pv.use_count() == px.use_count());
736         BOOST_TEST(!(px < pv || pv < px)); // shared ownership test
737 
738         boost::shared_ptr<void const> pv2(py);
739         BOOST_TEST(pv2 == py);
740         BOOST_TEST(pv2? true: false);
741         BOOST_TEST(!!pv2);
742         BOOST_TEST(pv2.get() == py.get());
743         BOOST_TEST(pv2.use_count() == 4);
744         BOOST_TEST(!pv2.unique());
745         BOOST_TEST(pv2.use_count() == py.use_count());
746         BOOST_TEST(!(py < pv2 || pv2 < py)); // shared ownership test
747 
748         BOOST_TEST(pv.use_count() == pv2.use_count());
749         BOOST_TEST(!(pv < pv2 || pv2 < pv)); // shared ownership test
750     }
751 
752     BOOST_TEST(X::instances == 0);
753     BOOST_TEST(Y::instances == 0);
754 }
755 
weak_ptr_constructor()756 void weak_ptr_constructor()
757 {
758     {
759         boost::weak_ptr<Y> wp;
760         BOOST_TEST(wp.use_count() == 0);
761 
762         try
763         {
764             boost::shared_ptr<Y> p2(wp);
765             BOOST_ERROR("shared_ptr<Y> p2(wp) failed to throw");
766         }
767         catch(boost::bad_weak_ptr)
768         {
769         }
770 
771         try
772         {
773             boost::shared_ptr<X> p3(wp);
774             BOOST_ERROR("shared_ptr<X> p3(wp) failed to throw");
775         }
776         catch(boost::bad_weak_ptr)
777         {
778         }
779     }
780 
781     {
782         boost::shared_ptr<Y> p;
783         boost::weak_ptr<Y> wp(p);
784 
785         if(wp.use_count() != 0) // 0 allowed but not required
786         {
787             boost::shared_ptr<Y> p2(wp);
788             BOOST_TEST(p2.use_count() == wp.use_count());
789             BOOST_TEST(p2.get() == 0);
790 
791             boost::shared_ptr<X> p3(wp);
792             BOOST_TEST(p3.use_count() == wp.use_count());
793             BOOST_TEST(p3.get() == 0);
794         }
795     }
796 
797     {
798         boost::shared_ptr<Y> p(new Y);
799         boost::weak_ptr<Y> wp(p);
800 
801         {
802             boost::shared_ptr<Y> p2(wp);
803             BOOST_TEST(p2? true: false);
804             BOOST_TEST(!!p2);
805             BOOST_TEST(p2.get() == p.get());
806             BOOST_TEST(p2.use_count() == 2);
807             BOOST_TEST(!p2.unique());
808             BOOST_TEST(p2.use_count() == wp.use_count());
809 
810             BOOST_TEST(p.use_count() == p2.use_count());
811             BOOST_TEST(!(p < p2 || p2 < p)); // shared ownership test
812 
813             boost::shared_ptr<X> p3(wp);
814             BOOST_TEST(p3? true: false);
815             BOOST_TEST(!!p3);
816             BOOST_TEST(p3.get() == p.get());
817             BOOST_TEST(p3.use_count() == 3);
818             BOOST_TEST(!p3.unique());
819             BOOST_TEST(p3.use_count() == wp.use_count());
820 
821             BOOST_TEST(p.use_count() == p3.use_count());
822         }
823 
824         p.reset();
825         BOOST_TEST(wp.use_count() == 0);
826 
827         try
828         {
829             boost::shared_ptr<Y> p2(wp);
830             BOOST_ERROR("shared_ptr<Y> p2(wp) failed to throw");
831         }
832         catch(boost::bad_weak_ptr)
833         {
834         }
835 
836         try
837         {
838             boost::shared_ptr<X> p3(wp);
839             BOOST_ERROR("shared_ptr<X> p3(wp) failed to throw");
840         }
841         catch(boost::bad_weak_ptr)
842         {
843         }
844     }
845 }
846 
847 #if defined(BOOST_DINKUMWARE_STDLIB) && (BOOST_DINKUMWARE_STDLIB < 306)
848 #  define BOOST_OLD_AUTO_PTR
849 #endif
850 
auto_ptr_constructor()851 void auto_ptr_constructor()
852 {
853     {
854         std::auto_ptr<int> p;
855         boost::shared_ptr<int> pi(p);
856         BOOST_TEST(pi? false: true);
857         BOOST_TEST(!pi);
858         BOOST_TEST(pi.get() == 0);
859         BOOST_TEST(pi.use_count() == 1);
860         BOOST_TEST(pi.unique());
861         BOOST_TEST(p.get() == 0);
862     }
863 
864     {
865         std::auto_ptr<int> p;
866         boost::shared_ptr<int const> pi(p);
867         BOOST_TEST(pi? false: true);
868         BOOST_TEST(!pi);
869         BOOST_TEST(pi.get() == 0);
870         BOOST_TEST(pi.use_count() == 1);
871         BOOST_TEST(pi.unique());
872         BOOST_TEST(p.get() == 0);
873     }
874 
875     {
876         std::auto_ptr<int> p;
877         boost::shared_ptr<void> pv(p);
878         BOOST_TEST(pv? false: true);
879         BOOST_TEST(!pv);
880         BOOST_TEST(pv.get() == 0);
881         BOOST_TEST(pv.use_count() == 1);
882         BOOST_TEST(pv.unique());
883         BOOST_TEST(p.get() == 0);
884     }
885 
886     {
887         std::auto_ptr<int> p;
888         boost::shared_ptr<void const> pv(p);
889         BOOST_TEST(pv? false: true);
890         BOOST_TEST(!pv);
891         BOOST_TEST(pv.get() == 0);
892         BOOST_TEST(pv.use_count() == 1);
893         BOOST_TEST(pv.unique());
894         BOOST_TEST(p.get() == 0);
895     }
896 
897     {
898         std::auto_ptr<X> p;
899         boost::shared_ptr<X> px(p);
900         BOOST_TEST(px? false: true);
901         BOOST_TEST(!px);
902         BOOST_TEST(px.get() == 0);
903         BOOST_TEST(px.use_count() == 1);
904         BOOST_TEST(px.unique());
905         BOOST_TEST(p.get() == 0);
906     }
907 
908     {
909         std::auto_ptr<X> p;
910         boost::shared_ptr<X const> px(p);
911         BOOST_TEST(px? false: true);
912         BOOST_TEST(!px);
913         BOOST_TEST(px.get() == 0);
914         BOOST_TEST(px.use_count() == 1);
915         BOOST_TEST(px.unique());
916         BOOST_TEST(p.get() == 0);
917     }
918 
919     {
920         std::auto_ptr<Y> p;
921         boost::shared_ptr<X> px(p);
922         BOOST_TEST(px? false: true);
923         BOOST_TEST(!px);
924         BOOST_TEST(px.get() == 0);
925         BOOST_TEST(px.use_count() == 1);
926         BOOST_TEST(px.unique());
927         BOOST_TEST(p.get() == 0);
928     }
929 
930     {
931         std::auto_ptr<Y> p;
932         boost::shared_ptr<X const> px(p);
933         BOOST_TEST(px? false: true);
934         BOOST_TEST(!px);
935         BOOST_TEST(px.get() == 0);
936         BOOST_TEST(px.use_count() == 1);
937         BOOST_TEST(px.unique());
938         BOOST_TEST(p.get() == 0);
939     }
940 
941     {
942         std::auto_ptr<Y> p;
943         boost::shared_ptr<void> pv(p);
944         BOOST_TEST(pv? false: true);
945         BOOST_TEST(!pv);
946         BOOST_TEST(pv.get() == 0);
947         BOOST_TEST(pv.use_count() == 1);
948         BOOST_TEST(pv.unique());
949         BOOST_TEST(p.get() == 0);
950     }
951 
952     {
953         std::auto_ptr<Y> p;
954         boost::shared_ptr<void const> pv(p);
955         BOOST_TEST(pv? false: true);
956         BOOST_TEST(!pv);
957         BOOST_TEST(pv.get() == 0);
958         BOOST_TEST(pv.use_count() == 1);
959         BOOST_TEST(pv.unique());
960         BOOST_TEST(p.get() == 0);
961     }
962 
963     {
964         std::auto_ptr<int> p(new int(7));
965         int * q = p.get();
966         boost::shared_ptr<int> pi(p);
967         BOOST_TEST(pi? true: false);
968         BOOST_TEST(!!pi);
969         BOOST_TEST(pi.get() == q);
970         BOOST_TEST(pi.use_count() == 1);
971         BOOST_TEST(pi.unique());
972         BOOST_TEST(*pi == 7);
973 
974 #if !defined(BOOST_OLD_AUTO_PTR)
975         BOOST_TEST(p.get() == 0);
976 #endif
977     }
978 
979     {
980         std::auto_ptr<int> p(new int(7));
981         int * q = p.get();
982         boost::shared_ptr<int const> pi(p);
983         BOOST_TEST(pi? true: false);
984         BOOST_TEST(!!pi);
985         BOOST_TEST(pi.get() == q);
986         BOOST_TEST(pi.use_count() == 1);
987         BOOST_TEST(pi.unique());
988         BOOST_TEST(*pi == 7);
989 
990 #if !defined(BOOST_OLD_AUTO_PTR)
991         BOOST_TEST(p.get() == 0);
992 #endif
993     }
994 
995     {
996         std::auto_ptr<int> p(new int(7));
997         int * q = p.get();
998         boost::shared_ptr<void> pv(p);
999         BOOST_TEST(pv? true: false);
1000         BOOST_TEST(!!pv);
1001         BOOST_TEST(pv.get() == q);
1002         BOOST_TEST(pv.use_count() == 1);
1003         BOOST_TEST(pv.unique());
1004 
1005 #if !defined(BOOST_OLD_AUTO_PTR)
1006         BOOST_TEST(p.get() == 0);
1007 #endif
1008     }
1009 
1010     {
1011         std::auto_ptr<int> p(new int(7));
1012         int * q = p.get();
1013         boost::shared_ptr<void const> pv(p);
1014         BOOST_TEST(pv? true: false);
1015         BOOST_TEST(!!pv);
1016         BOOST_TEST(pv.get() == q);
1017         BOOST_TEST(pv.use_count() == 1);
1018         BOOST_TEST(pv.unique());
1019 
1020 #if !defined(BOOST_OLD_AUTO_PTR)
1021         BOOST_TEST(p.get() == 0);
1022 #endif
1023     }
1024 
1025     BOOST_TEST(X::instances == 0);
1026 
1027     {
1028         std::auto_ptr<X> p(new X);
1029         X * q = p.get();
1030         boost::shared_ptr<X> px(p);
1031         BOOST_TEST(px? true: false);
1032         BOOST_TEST(!!px);
1033         BOOST_TEST(px.get() == q);
1034         BOOST_TEST(px.use_count() == 1);
1035         BOOST_TEST(px.unique());
1036         BOOST_TEST(X::instances == 1);
1037 
1038 #if !defined(BOOST_OLD_AUTO_PTR)
1039         BOOST_TEST(p.get() == 0);
1040 #endif
1041     }
1042 
1043     BOOST_TEST(X::instances == 0);
1044 
1045     {
1046         std::auto_ptr<X> p(new X);
1047         X * q = p.get();
1048         boost::shared_ptr<X const> px(p);
1049         BOOST_TEST(px? true: false);
1050         BOOST_TEST(!!px);
1051         BOOST_TEST(px.get() == q);
1052         BOOST_TEST(px.use_count() == 1);
1053         BOOST_TEST(px.unique());
1054         BOOST_TEST(X::instances == 1);
1055 
1056 #if !defined(BOOST_OLD_AUTO_PTR)
1057         BOOST_TEST(p.get() == 0);
1058 #endif
1059     }
1060 
1061     BOOST_TEST(X::instances == 0);
1062 
1063     {
1064         std::auto_ptr<X> p(new X);
1065         X * q = p.get();
1066         boost::shared_ptr<void> pv(p);
1067         BOOST_TEST(pv? true: false);
1068         BOOST_TEST(!!pv);
1069         BOOST_TEST(pv.get() == q);
1070         BOOST_TEST(pv.use_count() == 1);
1071         BOOST_TEST(pv.unique());
1072         BOOST_TEST(X::instances == 1);
1073 
1074 #if !defined(BOOST_OLD_AUTO_PTR)
1075         BOOST_TEST(p.get() == 0);
1076 #endif
1077     }
1078 
1079     BOOST_TEST(X::instances == 0);
1080 
1081     {
1082         std::auto_ptr<X> p(new X);
1083         X * q = p.get();
1084         boost::shared_ptr<void const> pv(p);
1085         BOOST_TEST(pv? true: false);
1086         BOOST_TEST(!!pv);
1087         BOOST_TEST(pv.get() == q);
1088         BOOST_TEST(pv.use_count() == 1);
1089         BOOST_TEST(pv.unique());
1090         BOOST_TEST(X::instances == 1);
1091 
1092 #if !defined(BOOST_OLD_AUTO_PTR)
1093         BOOST_TEST(p.get() == 0);
1094 #endif
1095     }
1096 
1097     BOOST_TEST(X::instances == 0);
1098     BOOST_TEST(Y::instances == 0);
1099 
1100     {
1101         std::auto_ptr<Y> p(new Y);
1102         Y * q = p.get();
1103         boost::shared_ptr<X> px(p);
1104         BOOST_TEST(px? true: false);
1105         BOOST_TEST(!!px);
1106         BOOST_TEST(px.get() == q);
1107         BOOST_TEST(px.use_count() == 1);
1108         BOOST_TEST(px.unique());
1109         BOOST_TEST(X::instances == 1);
1110         BOOST_TEST(Y::instances == 1);
1111 
1112 #if !defined(BOOST_OLD_AUTO_PTR)
1113         BOOST_TEST(p.get() == 0);
1114 #endif
1115     }
1116 
1117     BOOST_TEST(X::instances == 0);
1118     BOOST_TEST(Y::instances == 0);
1119 
1120     {
1121         std::auto_ptr<Y> p(new Y);
1122         Y * q = p.get();
1123         boost::shared_ptr<X const> px(p);
1124         BOOST_TEST(px? true: false);
1125         BOOST_TEST(!!px);
1126         BOOST_TEST(px.get() == q);
1127         BOOST_TEST(px.use_count() == 1);
1128         BOOST_TEST(px.unique());
1129         BOOST_TEST(X::instances == 1);
1130         BOOST_TEST(Y::instances == 1);
1131 
1132 #if !defined(BOOST_OLD_AUTO_PTR)
1133         BOOST_TEST(p.get() == 0);
1134 #endif
1135     }
1136 
1137     BOOST_TEST(X::instances == 0);
1138     BOOST_TEST(Y::instances == 0);
1139 }
1140 
test()1141 void test()
1142 {
1143     default_constructor();
1144     pointer_constructor();
1145     deleter_constructor();
1146     copy_constructor();
1147     weak_ptr_constructor();
1148     auto_ptr_constructor();
1149 }
1150 
1151 } // namespace n_constructors
1152 
1153 namespace n_assignment
1154 {
1155 
1156 class incomplete;
1157 
1158 struct A
1159 {
1160     int dummy;
1161 };
1162 
1163 struct X
1164 {
1165     static long instances;
1166 
Xn_assignment::X1167     X()
1168     {
1169         ++instances;
1170     }
1171 
~Xn_assignment::X1172     ~X()
1173     {
1174         --instances;
1175     }
1176 
1177 private:
1178 
1179     X(X const &);
1180     X & operator= (X const &);
1181 };
1182 
1183 long X::instances = 0;
1184 
1185 struct Y: public A, public virtual X
1186 {
1187     static long instances;
1188 
Yn_assignment::Y1189     Y()
1190     {
1191         ++instances;
1192     }
1193 
~Yn_assignment::Y1194     ~Y()
1195     {
1196         --instances;
1197     }
1198 
1199 private:
1200 
1201     Y(Y const &);
1202     Y & operator= (Y const &);
1203 };
1204 
1205 long Y::instances = 0;
1206 
copy_assignment()1207 void copy_assignment()
1208 {
1209     {
1210         boost::shared_ptr<incomplete> p1;
1211 
1212         p1 = p1;
1213 
1214         BOOST_TEST(p1 == p1);
1215         BOOST_TEST(p1? false: true);
1216         BOOST_TEST(!p1);
1217         BOOST_TEST(p1.get() == 0);
1218 
1219         boost::shared_ptr<incomplete> p2;
1220 
1221         p1 = p2;
1222 
1223         BOOST_TEST(p1 == p2);
1224         BOOST_TEST(p1? false: true);
1225         BOOST_TEST(!p1);
1226         BOOST_TEST(p1.get() == 0);
1227 
1228         boost::shared_ptr<incomplete> p3(p1);
1229 
1230         p1 = p3;
1231 
1232         BOOST_TEST(p1 == p3);
1233         BOOST_TEST(p1? false: true);
1234         BOOST_TEST(!p1);
1235         BOOST_TEST(p1.get() == 0);
1236     }
1237 
1238     {
1239         boost::shared_ptr<void> p1;
1240 
1241         p1 = p1;
1242 
1243         BOOST_TEST(p1 == p1);
1244         BOOST_TEST(p1? false: true);
1245         BOOST_TEST(!p1);
1246         BOOST_TEST(p1.get() == 0);
1247 
1248         boost::shared_ptr<void> p2;
1249 
1250         p1 = p2;
1251 
1252         BOOST_TEST(p1 == p2);
1253         BOOST_TEST(p1? false: true);
1254         BOOST_TEST(!p1);
1255         BOOST_TEST(p1.get() == 0);
1256 
1257         boost::shared_ptr<void> p3(p1);
1258 
1259         p1 = p3;
1260 
1261         BOOST_TEST(p1 == p3);
1262         BOOST_TEST(p1? false: true);
1263         BOOST_TEST(!p1);
1264         BOOST_TEST(p1.get() == 0);
1265 
1266         boost::shared_ptr<void> p4(new int);
1267         BOOST_TEST(p4.use_count() == 1);
1268 
1269         p1 = p4;
1270 
1271         BOOST_TEST(p1 == p4);
1272         BOOST_TEST(!(p1 < p4 || p4 < p1));
1273         BOOST_TEST(p1.use_count() == 2);
1274         BOOST_TEST(p4.use_count() == 2);
1275 
1276         p1 = p3;
1277 
1278         BOOST_TEST(p1 == p3);
1279         BOOST_TEST(p4.use_count() == 1);
1280     }
1281 
1282     {
1283         boost::shared_ptr<X> p1;
1284 
1285         p1 = p1;
1286 
1287         BOOST_TEST(p1 == p1);
1288         BOOST_TEST(p1? false: true);
1289         BOOST_TEST(!p1);
1290         BOOST_TEST(p1.get() == 0);
1291 
1292         boost::shared_ptr<X> p2;
1293 
1294         p1 = p2;
1295 
1296         BOOST_TEST(p1 == p2);
1297         BOOST_TEST(p1? false: true);
1298         BOOST_TEST(!p1);
1299         BOOST_TEST(p1.get() == 0);
1300 
1301         boost::shared_ptr<X> p3(p1);
1302 
1303         p1 = p3;
1304 
1305         BOOST_TEST(p1 == p3);
1306         BOOST_TEST(p1? false: true);
1307         BOOST_TEST(!p1);
1308         BOOST_TEST(p1.get() == 0);
1309 
1310         BOOST_TEST(X::instances == 0);
1311 
1312         boost::shared_ptr<X> p4(new X);
1313 
1314         BOOST_TEST(X::instances == 1);
1315 
1316         p1 = p4;
1317 
1318         BOOST_TEST(X::instances == 1);
1319 
1320         BOOST_TEST(p1 == p4);
1321         BOOST_TEST(!(p1 < p4 || p4 < p1));
1322 
1323         BOOST_TEST(p1.use_count() == 2);
1324 
1325         p1 = p2;
1326 
1327         BOOST_TEST(p1 == p2);
1328         BOOST_TEST(X::instances == 1);
1329 
1330         p4 = p3;
1331 
1332         BOOST_TEST(p4 == p3);
1333         BOOST_TEST(X::instances == 0);
1334     }
1335 }
1336 
conversion_assignment()1337 void conversion_assignment()
1338 {
1339     {
1340         boost::shared_ptr<void> p1;
1341 
1342         boost::shared_ptr<incomplete> p2;
1343 
1344         p1 = p2;
1345 
1346         BOOST_TEST(p1 == p2);
1347         BOOST_TEST(p1? false: true);
1348         BOOST_TEST(!p1);
1349         BOOST_TEST(p1.get() == 0);
1350 
1351         boost::shared_ptr<int> p4(new int);
1352         BOOST_TEST(p4.use_count() == 1);
1353 
1354         boost::shared_ptr<void> p5(p4);
1355         BOOST_TEST(p4.use_count() == 2);
1356 
1357         p1 = p4;
1358 
1359         BOOST_TEST(p1 == p4);
1360         BOOST_TEST(!(p1 < p5 || p5 < p1));
1361         BOOST_TEST(p1.use_count() == 3);
1362         BOOST_TEST(p4.use_count() == 3);
1363 
1364         p1 = p2;
1365 
1366         BOOST_TEST(p1 == p2);
1367         BOOST_TEST(p4.use_count() == 2);
1368     }
1369 
1370     {
1371         boost::shared_ptr<X> p1;
1372 
1373         boost::shared_ptr<Y> p2;
1374 
1375         p1 = p2;
1376 
1377         BOOST_TEST(p1 == p2);
1378         BOOST_TEST(p1? false: true);
1379         BOOST_TEST(!p1);
1380         BOOST_TEST(p1.get() == 0);
1381 
1382         BOOST_TEST(X::instances == 0);
1383         BOOST_TEST(Y::instances == 0);
1384 
1385         boost::shared_ptr<Y> p4(new Y);
1386 
1387         BOOST_TEST(X::instances == 1);
1388         BOOST_TEST(Y::instances == 1);
1389         BOOST_TEST(p4.use_count() == 1);
1390 
1391         boost::shared_ptr<X> p5(p4);
1392         BOOST_TEST(p4.use_count() == 2);
1393 
1394         p1 = p4;
1395 
1396         BOOST_TEST(X::instances == 1);
1397         BOOST_TEST(Y::instances == 1);
1398 
1399         BOOST_TEST(p1 == p4);
1400         BOOST_TEST(!(p1 < p5 || p5 < p1));
1401 
1402         BOOST_TEST(p1.use_count() == 3);
1403         BOOST_TEST(p4.use_count() == 3);
1404 
1405         p1 = p2;
1406 
1407         BOOST_TEST(p1 == p2);
1408         BOOST_TEST(X::instances == 1);
1409         BOOST_TEST(Y::instances == 1);
1410         BOOST_TEST(p4.use_count() == 2);
1411 
1412         p4 = p2;
1413         p5 = p2;
1414 
1415         BOOST_TEST(p4 == p2);
1416         BOOST_TEST(X::instances == 0);
1417         BOOST_TEST(Y::instances == 0);
1418     }
1419 }
1420 
auto_ptr_assignment()1421 void auto_ptr_assignment()
1422 {
1423     {
1424         boost::shared_ptr<int> p1;
1425 
1426         std::auto_ptr<int> p2;
1427 
1428         p1 = p2;
1429         BOOST_TEST(p1? false: true);
1430         BOOST_TEST(!p1);
1431         BOOST_TEST(p1.get() == 0);
1432         BOOST_TEST(p1.use_count() == 1);
1433 
1434         int * p = new int;
1435         std::auto_ptr<int> p3(p);
1436 
1437         p1 = p3;
1438         BOOST_TEST(p1.get() == p);
1439         BOOST_TEST(p1.use_count() == 1);
1440 
1441 #if !defined(BOOST_OLD_AUTO_PTR)
1442         BOOST_TEST(p3.get() == 0);
1443 #endif
1444 
1445         p1 = p2;
1446         BOOST_TEST(p1? false: true);
1447         BOOST_TEST(!p1);
1448         BOOST_TEST(p1.get() == 0);
1449         BOOST_TEST(p1.use_count() == 1);
1450     }
1451 
1452     {
1453         boost::shared_ptr<void> p1;
1454 
1455         std::auto_ptr<int> p2;
1456 
1457         p1 = p2;
1458         BOOST_TEST(p1? false: true);
1459         BOOST_TEST(!p1);
1460         BOOST_TEST(p1.get() == 0);
1461         BOOST_TEST(p1.use_count() == 1);
1462 
1463         int * p = new int;
1464         std::auto_ptr<int> p3(p);
1465 
1466         p1 = p3;
1467         BOOST_TEST(p1.get() == p);
1468         BOOST_TEST(p1.use_count() == 1);
1469 
1470 #if !defined(BOOST_OLD_AUTO_PTR)
1471         BOOST_TEST(p3.get() == 0);
1472 #endif
1473 
1474         p1 = p2;
1475         BOOST_TEST(p1? false: true);
1476         BOOST_TEST(!p1);
1477         BOOST_TEST(p1.get() == 0);
1478         BOOST_TEST(p1.use_count() == 1);
1479     }
1480 
1481 
1482     {
1483         boost::shared_ptr<X> p1;
1484 
1485         std::auto_ptr<Y> p2;
1486 
1487         p1 = p2;
1488         BOOST_TEST(p1? false: true);
1489         BOOST_TEST(!p1);
1490         BOOST_TEST(p1.get() == 0);
1491         BOOST_TEST(p1.use_count() == 1);
1492         BOOST_TEST(X::instances == 0);
1493         BOOST_TEST(Y::instances == 0);
1494 
1495         Y * p = new Y;
1496         std::auto_ptr<Y> p3(p);
1497 
1498         BOOST_TEST(X::instances == 1);
1499         BOOST_TEST(Y::instances == 1);
1500 
1501         p1 = p3;
1502         BOOST_TEST(p1.get() == p);
1503         BOOST_TEST(p1.use_count() == 1);
1504         BOOST_TEST(X::instances == 1);
1505         BOOST_TEST(Y::instances == 1);
1506 
1507 #if !defined(BOOST_OLD_AUTO_PTR)
1508         BOOST_TEST(p3.get() == 0);
1509 #endif
1510 
1511         p1 = p2;
1512         BOOST_TEST(p1? false: true);
1513         BOOST_TEST(!p1);
1514         BOOST_TEST(p1.get() == 0);
1515         BOOST_TEST(p1.use_count() == 1);
1516         BOOST_TEST(X::instances == 0);
1517         BOOST_TEST(Y::instances == 0);
1518     }
1519 }
1520 
test()1521 void test()
1522 {
1523     copy_assignment();
1524     conversion_assignment();
1525     auto_ptr_assignment();
1526 }
1527 
1528 } // namespace n_assignment
1529 
1530 namespace n_reset
1531 {
1532 
1533 class incomplete;
1534 
1535 incomplete * p0 = 0;
1536 
deleter(incomplete *)1537 void deleter(incomplete *)
1538 {
1539 }
1540 
1541 struct X
1542 {
1543     static long instances;
1544 
Xn_reset::X1545     X()
1546     {
1547         ++instances;
1548     }
1549 
~Xn_reset::X1550     ~X()
1551     {
1552         --instances;
1553     }
1554 
1555 private:
1556 
1557     X(X const &);
1558     X & operator= (X const &);
1559 };
1560 
1561 long X::instances = 0;
1562 
plain_reset()1563 void plain_reset()
1564 {
1565     {
1566         boost::shared_ptr<int> pi;
1567         pi.reset();
1568         BOOST_TEST(pi? false: true);
1569         BOOST_TEST(!pi);
1570         BOOST_TEST(pi.get() == 0);
1571         BOOST_TEST(pi.use_count() == 0);
1572     }
1573 
1574     {
1575         boost::shared_ptr<int> pi(static_cast<int*>(0));
1576         pi.reset();
1577         BOOST_TEST(pi? false: true);
1578         BOOST_TEST(!pi);
1579         BOOST_TEST(pi.get() == 0);
1580         BOOST_TEST(pi.use_count() == 0);
1581     }
1582 
1583     {
1584         boost::shared_ptr<int> pi(new int);
1585         pi.reset();
1586         BOOST_TEST(pi? false: true);
1587         BOOST_TEST(!pi);
1588         BOOST_TEST(pi.get() == 0);
1589         BOOST_TEST(pi.use_count() == 0);
1590     }
1591 
1592     {
1593         boost::shared_ptr<incomplete> px;
1594         px.reset();
1595         BOOST_TEST(px? false: true);
1596         BOOST_TEST(!px);
1597         BOOST_TEST(px.get() == 0);
1598         BOOST_TEST(px.use_count() == 0);
1599     }
1600 
1601     {
1602         boost::shared_ptr<incomplete> px(p0, deleter);
1603         px.reset();
1604         BOOST_TEST(px? false: true);
1605         BOOST_TEST(!px);
1606         BOOST_TEST(px.get() == 0);
1607         BOOST_TEST(px.use_count() == 0);
1608     }
1609 
1610     {
1611         boost::shared_ptr<X> px;
1612         px.reset();
1613         BOOST_TEST(px? false: true);
1614         BOOST_TEST(!px);
1615         BOOST_TEST(px.get() == 0);
1616         BOOST_TEST(px.use_count() == 0);
1617     }
1618 
1619     {
1620         BOOST_TEST(X::instances == 0);
1621         boost::shared_ptr<X> px(new X);
1622         BOOST_TEST(X::instances == 1);
1623         px.reset();
1624         BOOST_TEST(px? false: true);
1625         BOOST_TEST(!px);
1626         BOOST_TEST(px.get() == 0);
1627         BOOST_TEST(px.use_count() == 0);
1628         BOOST_TEST(X::instances == 0);
1629     }
1630 
1631     {
1632         boost::shared_ptr<void> pv;
1633         pv.reset();
1634         BOOST_TEST(pv? false: true);
1635         BOOST_TEST(!pv);
1636         BOOST_TEST(pv.get() == 0);
1637         BOOST_TEST(pv.use_count() == 0);
1638     }
1639 
1640     {
1641         BOOST_TEST(X::instances == 0);
1642         boost::shared_ptr<void> pv(new X);
1643         BOOST_TEST(X::instances == 1);
1644         pv.reset();
1645         BOOST_TEST(pv? false: true);
1646         BOOST_TEST(!pv);
1647         BOOST_TEST(pv.get() == 0);
1648         BOOST_TEST(pv.use_count() == 0);
1649         BOOST_TEST(X::instances == 0);
1650     }
1651 }
1652 
1653 struct A
1654 {
1655     int dummy;
1656 };
1657 
1658 struct Y: public A, public virtual X
1659 {
1660     static long instances;
1661 
Yn_reset::Y1662     Y()
1663     {
1664         ++instances;
1665     }
1666 
~Yn_reset::Y1667     ~Y()
1668     {
1669         --instances;
1670     }
1671 
1672 private:
1673 
1674     Y(Y const &);
1675     Y & operator= (Y const &);
1676 };
1677 
1678 long Y::instances = 0;
1679 
pointer_reset()1680 void pointer_reset()
1681 {
1682     {
1683         boost::shared_ptr<int> pi;
1684 
1685         pi.reset(static_cast<int*>(0));
1686         BOOST_TEST(pi? false: true);
1687         BOOST_TEST(!pi);
1688         BOOST_TEST(pi.get() == 0);
1689         BOOST_TEST(pi.use_count() == 1);
1690         BOOST_TEST(pi.unique());
1691 
1692         int * p = new int;
1693         pi.reset(p);
1694         BOOST_TEST(pi? true: false);
1695         BOOST_TEST(!!pi);
1696         BOOST_TEST(pi.get() == p);
1697         BOOST_TEST(pi.use_count() == 1);
1698         BOOST_TEST(pi.unique());
1699 
1700         pi.reset(static_cast<int*>(0));
1701         BOOST_TEST(pi? false: true);
1702         BOOST_TEST(!pi);
1703         BOOST_TEST(pi.get() == 0);
1704         BOOST_TEST(pi.use_count() == 1);
1705         BOOST_TEST(pi.unique());
1706     }
1707 
1708     {
1709         boost::shared_ptr<X> px;
1710 
1711         px.reset(static_cast<X*>(0));
1712         BOOST_TEST(px? false: true);
1713         BOOST_TEST(!px);
1714         BOOST_TEST(px.get() == 0);
1715         BOOST_TEST(px.use_count() == 1);
1716         BOOST_TEST(px.unique());
1717         BOOST_TEST(X::instances == 0);
1718 
1719         X * p = new X;
1720         px.reset(p);
1721         BOOST_TEST(px? true: false);
1722         BOOST_TEST(!!px);
1723         BOOST_TEST(px.get() == p);
1724         BOOST_TEST(px.use_count() == 1);
1725         BOOST_TEST(px.unique());
1726         BOOST_TEST(X::instances == 1);
1727 
1728         px.reset(static_cast<X*>(0));
1729         BOOST_TEST(px? false: true);
1730         BOOST_TEST(!px);
1731         BOOST_TEST(px.get() == 0);
1732         BOOST_TEST(px.use_count() == 1);
1733         BOOST_TEST(px.unique());
1734         BOOST_TEST(X::instances == 0);
1735         BOOST_TEST(Y::instances == 0);
1736 
1737         Y * q = new Y;
1738         px.reset(q);
1739         BOOST_TEST(px? true: false);
1740         BOOST_TEST(!!px);
1741         BOOST_TEST(px.get() == q);
1742         BOOST_TEST(px.use_count() == 1);
1743         BOOST_TEST(px.unique());
1744         BOOST_TEST(X::instances == 1);
1745         BOOST_TEST(Y::instances == 1);
1746 
1747         px.reset(static_cast<Y*>(0));
1748         BOOST_TEST(px? false: true);
1749         BOOST_TEST(!px);
1750         BOOST_TEST(px.get() == 0);
1751         BOOST_TEST(px.use_count() == 1);
1752         BOOST_TEST(px.unique());
1753         BOOST_TEST(X::instances == 0);
1754         BOOST_TEST(Y::instances == 0);
1755     }
1756 
1757     {
1758         boost::shared_ptr<void> pv;
1759 
1760         pv.reset(static_cast<X*>(0));
1761         BOOST_TEST(pv? false: true);
1762         BOOST_TEST(!pv);
1763         BOOST_TEST(pv.get() == 0);
1764         BOOST_TEST(pv.use_count() == 1);
1765         BOOST_TEST(pv.unique());
1766         BOOST_TEST(X::instances == 0);
1767 
1768         X * p = new X;
1769         pv.reset(p);
1770         BOOST_TEST(pv? true: false);
1771         BOOST_TEST(!!pv);
1772         BOOST_TEST(pv.get() == p);
1773         BOOST_TEST(pv.use_count() == 1);
1774         BOOST_TEST(pv.unique());
1775         BOOST_TEST(X::instances == 1);
1776 
1777         pv.reset(static_cast<X*>(0));
1778         BOOST_TEST(pv? false: true);
1779         BOOST_TEST(!pv);
1780         BOOST_TEST(pv.get() == 0);
1781         BOOST_TEST(pv.use_count() == 1);
1782         BOOST_TEST(pv.unique());
1783         BOOST_TEST(X::instances == 0);
1784         BOOST_TEST(Y::instances == 0);
1785 
1786         Y * q = new Y;
1787         pv.reset(q);
1788         BOOST_TEST(pv? true: false);
1789         BOOST_TEST(!!pv);
1790         BOOST_TEST(pv.get() == q);
1791         BOOST_TEST(pv.use_count() == 1);
1792         BOOST_TEST(pv.unique());
1793         BOOST_TEST(X::instances == 1);
1794         BOOST_TEST(Y::instances == 1);
1795 
1796         pv.reset(static_cast<Y*>(0));
1797         BOOST_TEST(pv? false: true);
1798         BOOST_TEST(!pv);
1799         BOOST_TEST(pv.get() == 0);
1800         BOOST_TEST(pv.use_count() == 1);
1801         BOOST_TEST(pv.unique());
1802         BOOST_TEST(X::instances == 0);
1803         BOOST_TEST(Y::instances == 0);
1804     }
1805 }
1806 
1807 void * deleted = 0;
1808 
deleter2(void * p)1809 void deleter2(void * p)
1810 {
1811     deleted = p;
1812 }
1813 
deleter_reset()1814 void deleter_reset()
1815 {
1816     {
1817         boost::shared_ptr<int> pi;
1818 
1819         pi.reset(static_cast<int*>(0), deleter2);
1820         BOOST_TEST(pi? false: true);
1821         BOOST_TEST(!pi);
1822         BOOST_TEST(pi.get() == 0);
1823         BOOST_TEST(pi.use_count() == 1);
1824         BOOST_TEST(pi.unique());
1825 
1826         deleted = &pi;
1827 
1828         int m = 0;
1829         pi.reset(&m, deleter2);
1830         BOOST_TEST(deleted == 0);
1831         BOOST_TEST(pi? true: false);
1832         BOOST_TEST(!!pi);
1833         BOOST_TEST(pi.get() == &m);
1834         BOOST_TEST(pi.use_count() == 1);
1835         BOOST_TEST(pi.unique());
1836 
1837         pi.reset(static_cast<int*>(0), deleter2);
1838         BOOST_TEST(deleted == &m);
1839         BOOST_TEST(pi? false: true);
1840         BOOST_TEST(!pi);
1841         BOOST_TEST(pi.get() == 0);
1842         BOOST_TEST(pi.use_count() == 1);
1843         BOOST_TEST(pi.unique());
1844 
1845         pi.reset();
1846         BOOST_TEST(deleted == 0);
1847     }
1848 
1849     {
1850         boost::shared_ptr<X> px;
1851 
1852         px.reset(static_cast<X*>(0), deleter2);
1853         BOOST_TEST(px? false: true);
1854         BOOST_TEST(!px);
1855         BOOST_TEST(px.get() == 0);
1856         BOOST_TEST(px.use_count() == 1);
1857         BOOST_TEST(px.unique());
1858 
1859         deleted = &px;
1860 
1861         X x;
1862         px.reset(&x, deleter2);
1863         BOOST_TEST(deleted == 0);
1864         BOOST_TEST(px? true: false);
1865         BOOST_TEST(!!px);
1866         BOOST_TEST(px.get() == &x);
1867         BOOST_TEST(px.use_count() == 1);
1868         BOOST_TEST(px.unique());
1869 
1870         px.reset(static_cast<X*>(0), deleter2);
1871         BOOST_TEST(deleted == &x);
1872         BOOST_TEST(px? false: true);
1873         BOOST_TEST(!px);
1874         BOOST_TEST(px.get() == 0);
1875         BOOST_TEST(px.use_count() == 1);
1876         BOOST_TEST(px.unique());
1877 
1878         Y y;
1879         px.reset(&y, deleter2);
1880         BOOST_TEST(deleted == 0);
1881         BOOST_TEST(px? true: false);
1882         BOOST_TEST(!!px);
1883         BOOST_TEST(px.get() == &y);
1884         BOOST_TEST(px.use_count() == 1);
1885         BOOST_TEST(px.unique());
1886 
1887         px.reset(static_cast<Y*>(0), deleter2);
1888         BOOST_TEST(deleted == &y);
1889         BOOST_TEST(px? false: true);
1890         BOOST_TEST(!px);
1891         BOOST_TEST(px.get() == 0);
1892         BOOST_TEST(px.use_count() == 1);
1893         BOOST_TEST(px.unique());
1894 
1895         px.reset();
1896         BOOST_TEST(deleted == 0);
1897     }
1898 
1899     {
1900         boost::shared_ptr<void> pv;
1901 
1902         pv.reset(static_cast<X*>(0), deleter2);
1903         BOOST_TEST(pv? false: true);
1904         BOOST_TEST(!pv);
1905         BOOST_TEST(pv.get() == 0);
1906         BOOST_TEST(pv.use_count() == 1);
1907         BOOST_TEST(pv.unique());
1908 
1909         deleted = &pv;
1910 
1911         X x;
1912         pv.reset(&x, deleter2);
1913         BOOST_TEST(deleted == 0);
1914         BOOST_TEST(pv? true: false);
1915         BOOST_TEST(!!pv);
1916         BOOST_TEST(pv.get() == &x);
1917         BOOST_TEST(pv.use_count() == 1);
1918         BOOST_TEST(pv.unique());
1919 
1920         pv.reset(static_cast<X*>(0), deleter2);
1921         BOOST_TEST(deleted == &x);
1922         BOOST_TEST(pv? false: true);
1923         BOOST_TEST(!pv);
1924         BOOST_TEST(pv.get() == 0);
1925         BOOST_TEST(pv.use_count() == 1);
1926         BOOST_TEST(pv.unique());
1927 
1928         Y y;
1929         pv.reset(&y, deleter2);
1930         BOOST_TEST(deleted == 0);
1931         BOOST_TEST(pv? true: false);
1932         BOOST_TEST(!!pv);
1933         BOOST_TEST(pv.get() == &y);
1934         BOOST_TEST(pv.use_count() == 1);
1935         BOOST_TEST(pv.unique());
1936 
1937         pv.reset(static_cast<Y*>(0), deleter2);
1938         BOOST_TEST(deleted == &y);
1939         BOOST_TEST(pv? false: true);
1940         BOOST_TEST(!pv);
1941         BOOST_TEST(pv.get() == 0);
1942         BOOST_TEST(pv.use_count() == 1);
1943         BOOST_TEST(pv.unique());
1944 
1945         pv.reset();
1946         BOOST_TEST(deleted == 0);
1947     }
1948 
1949     {
1950         boost::shared_ptr<incomplete> px;
1951 
1952         px.reset(p0, deleter2);
1953         BOOST_TEST(px? false: true);
1954         BOOST_TEST(!px);
1955         BOOST_TEST(px.get() == 0);
1956         BOOST_TEST(px.use_count() == 1);
1957         BOOST_TEST(px.unique());
1958 
1959         deleted = &px;
1960         px.reset(p0, deleter2);
1961         BOOST_TEST(deleted == 0);
1962     }
1963 }
1964 
test()1965 void test()
1966 {
1967     plain_reset();
1968     pointer_reset();
1969     deleter_reset();
1970 }
1971 
1972 } // namespace n_reset
1973 
1974 namespace n_access
1975 {
1976 
1977 struct X
1978 {
1979 };
1980 
test()1981 void test()
1982 {
1983     {
1984         boost::shared_ptr<X> px;
1985         BOOST_TEST(px.get() == 0);
1986         BOOST_TEST(px? false: true);
1987         BOOST_TEST(!px);
1988 
1989 #if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP)
1990         using boost::get_pointer;
1991 #endif
1992 
1993         BOOST_TEST(get_pointer(px) == px.get());
1994     }
1995 
1996     {
1997         boost::shared_ptr<X> px(static_cast<X*>(0));
1998         BOOST_TEST(px.get() == 0);
1999         BOOST_TEST(px? false: true);
2000         BOOST_TEST(!px);
2001 
2002 #if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP)
2003         using boost::get_pointer;
2004 #endif
2005 
2006         BOOST_TEST(get_pointer(px) == px.get());
2007     }
2008 
2009     {
2010         boost::shared_ptr<X> px(static_cast<X*>(0), boost::checked_deleter<X>());
2011         BOOST_TEST(px.get() == 0);
2012         BOOST_TEST(px? false: true);
2013         BOOST_TEST(!px);
2014 
2015 #if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP)
2016         using boost::get_pointer;
2017 #endif
2018 
2019         BOOST_TEST(get_pointer(px) == px.get());
2020     }
2021 
2022     {
2023         X * p = new X;
2024         boost::shared_ptr<X> px(p);
2025         BOOST_TEST(px.get() == p);
2026         BOOST_TEST(px? true: false);
2027         BOOST_TEST(!!px);
2028         BOOST_TEST(&*px == px.get());
2029         BOOST_TEST(px.operator ->() == px.get());
2030 
2031 #if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP)
2032         using boost::get_pointer;
2033 #endif
2034 
2035         BOOST_TEST(get_pointer(px) == px.get());
2036     }
2037 
2038     {
2039         X * p = new X;
2040         boost::shared_ptr<X> px(p, boost::checked_deleter<X>());
2041         BOOST_TEST(px.get() == p);
2042         BOOST_TEST(px? true: false);
2043         BOOST_TEST(!!px);
2044         BOOST_TEST(&*px == px.get());
2045         BOOST_TEST(px.operator ->() == px.get());
2046 
2047 #if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP)
2048         using boost::get_pointer;
2049 #endif
2050 
2051         BOOST_TEST(get_pointer(px) == px.get());
2052     }
2053 }
2054 
2055 } // namespace n_access
2056 
2057 namespace n_use_count
2058 {
2059 
2060 struct X
2061 {
2062 };
2063 
test()2064 void test()
2065 {
2066     {
2067         boost::shared_ptr<X> px(static_cast<X*>(0));
2068         BOOST_TEST(px.use_count() == 1);
2069         BOOST_TEST(px.unique());
2070 
2071         boost::shared_ptr<X> px2(px);
2072         BOOST_TEST(px2.use_count() == 2);
2073         BOOST_TEST(!px2.unique());
2074         BOOST_TEST(px.use_count() == 2);
2075         BOOST_TEST(!px.unique());
2076     }
2077 
2078     {
2079         boost::shared_ptr<X> px(new X);
2080         BOOST_TEST(px.use_count() == 1);
2081         BOOST_TEST(px.unique());
2082 
2083         boost::shared_ptr<X> px2(px);
2084         BOOST_TEST(px2.use_count() == 2);
2085         BOOST_TEST(!px2.unique());
2086         BOOST_TEST(px.use_count() == 2);
2087         BOOST_TEST(!px.unique());
2088     }
2089 
2090     {
2091         boost::shared_ptr<X> px(new X, boost::checked_deleter<X>());
2092         BOOST_TEST(px.use_count() == 1);
2093         BOOST_TEST(px.unique());
2094 
2095         boost::shared_ptr<X> px2(px);
2096         BOOST_TEST(px2.use_count() == 2);
2097         BOOST_TEST(!px2.unique());
2098         BOOST_TEST(px.use_count() == 2);
2099         BOOST_TEST(!px.unique());
2100     }
2101 }
2102 
2103 } // namespace n_use_count
2104 
2105 namespace n_swap
2106 {
2107 
2108 struct X
2109 {
2110 };
2111 
test()2112 void test()
2113 {
2114     {
2115         boost::shared_ptr<X> px;
2116         boost::shared_ptr<X> px2;
2117 
2118         px.swap(px2);
2119 
2120         BOOST_TEST(px.get() == 0);
2121         BOOST_TEST(px2.get() == 0);
2122 
2123         using std::swap;
2124         swap(px, px2);
2125 
2126         BOOST_TEST(px.get() == 0);
2127         BOOST_TEST(px2.get() == 0);
2128     }
2129 
2130     {
2131         X * p = new X;
2132         boost::shared_ptr<X> px;
2133         boost::shared_ptr<X> px2(p);
2134         boost::shared_ptr<X> px3(px2);
2135 
2136         px.swap(px2);
2137 
2138         BOOST_TEST(px.get() == p);
2139         BOOST_TEST(px.use_count() == 2);
2140         BOOST_TEST(px2.get() == 0);
2141         BOOST_TEST(px3.get() == p);
2142         BOOST_TEST(px3.use_count() == 2);
2143 
2144         using std::swap;
2145         swap(px, px2);
2146 
2147         BOOST_TEST(px.get() == 0);
2148         BOOST_TEST(px2.get() == p);
2149         BOOST_TEST(px2.use_count() == 2);
2150         BOOST_TEST(px3.get() == p);
2151         BOOST_TEST(px3.use_count() == 2);
2152     }
2153 
2154     {
2155         X * p1 = new X;
2156         X * p2 = new X;
2157         boost::shared_ptr<X> px(p1);
2158         boost::shared_ptr<X> px2(p2);
2159         boost::shared_ptr<X> px3(px2);
2160 
2161         px.swap(px2);
2162 
2163         BOOST_TEST(px.get() == p2);
2164         BOOST_TEST(px.use_count() == 2);
2165         BOOST_TEST(px2.get() == p1);
2166         BOOST_TEST(px2.use_count() == 1);
2167         BOOST_TEST(px3.get() == p2);
2168         BOOST_TEST(px3.use_count() == 2);
2169 
2170         using std::swap;
2171         swap(px, px2);
2172 
2173         BOOST_TEST(px.get() == p1);
2174         BOOST_TEST(px.use_count() == 1);
2175         BOOST_TEST(px2.get() == p2);
2176         BOOST_TEST(px2.use_count() == 2);
2177         BOOST_TEST(px3.get() == p2);
2178         BOOST_TEST(px3.use_count() == 2);
2179     }
2180 }
2181 
2182 } // namespace n_swap
2183 
2184 namespace n_comparison
2185 {
2186 
2187 struct X
2188 {
2189     int dummy;
2190 };
2191 
2192 struct Y
2193 {
2194     int dummy2;
2195 };
2196 
2197 struct Z: public X, public virtual Y
2198 {
2199 };
2200 
test()2201 void test()
2202 {
2203     {
2204         boost::shared_ptr<X> px;
2205         BOOST_TEST(px == px);
2206         BOOST_TEST(!(px != px));
2207         BOOST_TEST(!(px < px));
2208 
2209         boost::shared_ptr<X> px2;
2210 
2211         BOOST_TEST(px.get() == px2.get());
2212         BOOST_TEST(px == px2);
2213         BOOST_TEST(!(px != px2));
2214         BOOST_TEST(!(px < px2 && px2 < px));
2215     }
2216 
2217     {
2218         boost::shared_ptr<X> px;
2219         boost::shared_ptr<X> px2(px);
2220 
2221         BOOST_TEST(px2 == px2);
2222         BOOST_TEST(!(px2 != px2));
2223         BOOST_TEST(!(px2 < px2));
2224 
2225         BOOST_TEST(px.get() == px2.get());
2226         BOOST_TEST(px == px2);
2227         BOOST_TEST(!(px != px2));
2228         BOOST_TEST(!(px < px2 && px2 < px));
2229     }
2230 
2231     {
2232         boost::shared_ptr<X> px;
2233         boost::shared_ptr<X> px2(new X);
2234 
2235         BOOST_TEST(px2 == px2);
2236         BOOST_TEST(!(px2 != px2));
2237         BOOST_TEST(!(px2 < px2));
2238 
2239         BOOST_TEST(px.get() != px2.get());
2240         BOOST_TEST(px != px2);
2241         BOOST_TEST(!(px == px2));
2242         BOOST_TEST(px < px2 || px2 < px);
2243         BOOST_TEST(!(px < px2 && px2 < px));
2244     }
2245 
2246     {
2247         boost::shared_ptr<X> px(new X);
2248         boost::shared_ptr<X> px2(new X);
2249 
2250         BOOST_TEST(px.get() != px2.get());
2251         BOOST_TEST(px != px2);
2252         BOOST_TEST(!(px == px2));
2253         BOOST_TEST(px < px2 || px2 < px);
2254         BOOST_TEST(!(px < px2 && px2 < px));
2255     }
2256 
2257     {
2258         boost::shared_ptr<X> px(new X);
2259         boost::shared_ptr<X> px2(px);
2260 
2261         BOOST_TEST(px2 == px2);
2262         BOOST_TEST(!(px2 != px2));
2263         BOOST_TEST(!(px2 < px2));
2264 
2265         BOOST_TEST(px.get() == px2.get());
2266         BOOST_TEST(px == px2);
2267         BOOST_TEST(!(px != px2));
2268         BOOST_TEST(!(px < px2 || px2 < px));
2269     }
2270 
2271     {
2272         boost::shared_ptr<X> px(new X);
2273         boost::shared_ptr<Y> py(new Y);
2274         boost::shared_ptr<Z> pz(new Z);
2275 
2276         BOOST_TEST(px.get() != pz.get());
2277         BOOST_TEST(px != pz);
2278         BOOST_TEST(!(px == pz));
2279 
2280         BOOST_TEST(py.get() != pz.get());
2281         BOOST_TEST(py != pz);
2282         BOOST_TEST(!(py == pz));
2283 
2284         BOOST_TEST(px < py || py < px);
2285         BOOST_TEST(px < pz || pz < px);
2286         BOOST_TEST(py < pz || pz < py);
2287 
2288         BOOST_TEST(!(px < py && py < px));
2289         BOOST_TEST(!(px < pz && pz < px));
2290         BOOST_TEST(!(py < pz && pz < py));
2291 
2292         boost::shared_ptr<void> pvx(px);
2293 
2294         BOOST_TEST(pvx == pvx);
2295         BOOST_TEST(!(pvx != pvx));
2296         BOOST_TEST(!(pvx < pvx));
2297 
2298         boost::shared_ptr<void> pvy(py);
2299         boost::shared_ptr<void> pvz(pz);
2300 
2301         BOOST_TEST(pvx < pvy || pvy < pvx);
2302         BOOST_TEST(pvx < pvz || pvz < pvx);
2303         BOOST_TEST(pvy < pvz || pvz < pvy);
2304 
2305         BOOST_TEST(!(pvx < pvy && pvy < pvx));
2306         BOOST_TEST(!(pvx < pvz && pvz < pvx));
2307         BOOST_TEST(!(pvy < pvz && pvz < pvy));
2308     }
2309 
2310     {
2311         boost::shared_ptr<Z> pz(new Z);
2312         boost::shared_ptr<X> px(pz);
2313 
2314         BOOST_TEST(px == px);
2315         BOOST_TEST(!(px != px));
2316         BOOST_TEST(!(px < px));
2317 
2318         boost::shared_ptr<Y> py(pz);
2319 
2320         BOOST_TEST(px.get() == pz.get());
2321         BOOST_TEST(px == pz);
2322         BOOST_TEST(!(px != pz));
2323 
2324         BOOST_TEST(py.get() == pz.get());
2325         BOOST_TEST(py == pz);
2326         BOOST_TEST(!(py != pz));
2327 
2328         BOOST_TEST(!(px < py || py < px));
2329         BOOST_TEST(!(px < pz || pz < px));
2330         BOOST_TEST(!(py < pz || pz < py));
2331 
2332         boost::shared_ptr<void> pvx(px);
2333         boost::shared_ptr<void> pvy(py);
2334         boost::shared_ptr<void> pvz(pz);
2335 
2336         // pvx and pvy aren't equal...
2337         BOOST_TEST(pvx.get() != pvy.get());
2338         BOOST_TEST(pvx != pvy);
2339         BOOST_TEST(!(pvx == pvy));
2340 
2341         // ... but they share ownership ...
2342         BOOST_TEST(!(pvx < pvy || pvy < pvx));
2343 
2344         // ... with pvz
2345         BOOST_TEST(!(pvx < pvz || pvz < pvx));
2346         BOOST_TEST(!(pvy < pvz || pvz < pvy));
2347     }
2348 }
2349 
2350 } // namespace n_comparison
2351 
2352 namespace n_static_cast
2353 {
2354 
2355 struct X
2356 {
2357 };
2358 
2359 struct Y: public X
2360 {
2361 };
2362 
test()2363 void test()
2364 {
2365     {
2366         boost::shared_ptr<void> pv;
2367 
2368         boost::shared_ptr<int> pi = boost::static_pointer_cast<int>(pv);
2369         BOOST_TEST(pi.get() == 0);
2370 
2371         boost::shared_ptr<X> px = boost::static_pointer_cast<X>(pv);
2372         BOOST_TEST(px.get() == 0);
2373     }
2374 
2375     {
2376         boost::shared_ptr<int> pi(new int);
2377         boost::shared_ptr<void> pv(pi);
2378 
2379         boost::shared_ptr<int> pi2 = boost::static_pointer_cast<int>(pv);
2380         BOOST_TEST(pi.get() == pi2.get());
2381         BOOST_TEST(!(pi < pi2 || pi2 < pi));
2382         BOOST_TEST(pi.use_count() == 3);
2383         BOOST_TEST(pv.use_count() == 3);
2384         BOOST_TEST(pi2.use_count() == 3);
2385     }
2386 
2387     {
2388         boost::shared_ptr<X> px(new X);
2389         boost::shared_ptr<void> pv(px);
2390 
2391         boost::shared_ptr<X> px2 = boost::static_pointer_cast<X>(pv);
2392         BOOST_TEST(px.get() == px2.get());
2393         BOOST_TEST(!(px < px2 || px2 < px));
2394         BOOST_TEST(px.use_count() == 3);
2395         BOOST_TEST(pv.use_count() == 3);
2396         BOOST_TEST(px2.use_count() == 3);
2397     }
2398 
2399     {
2400         boost::shared_ptr<X> px(new Y);
2401 
2402         boost::shared_ptr<Y> py = boost::static_pointer_cast<Y>(px);
2403         BOOST_TEST(px.get() == py.get());
2404         BOOST_TEST(px.use_count() == 2);
2405         BOOST_TEST(py.use_count() == 2);
2406 
2407         boost::shared_ptr<X> px2(py);
2408         BOOST_TEST(!(px < px2 || px2 < px));
2409     }
2410 }
2411 
2412 } // namespace n_static_cast
2413 
2414 namespace n_const_cast
2415 {
2416 
2417 struct X;
2418 
test()2419 void test()
2420 {
2421     {
2422         boost::shared_ptr<void const volatile> px;
2423 
2424         boost::shared_ptr<void> px2 = boost::const_pointer_cast<void>(px);
2425         BOOST_TEST(px2.get() == 0);
2426     }
2427 
2428     {
2429         boost::shared_ptr<int const volatile> px;
2430 
2431         boost::shared_ptr<int> px2 = boost::const_pointer_cast<int>(px);
2432         BOOST_TEST(px2.get() == 0);
2433     }
2434 
2435     {
2436         boost::shared_ptr<X const volatile> px;
2437 
2438         boost::shared_ptr<X> px2 = boost::const_pointer_cast<X>(px);
2439         BOOST_TEST(px2.get() == 0);
2440     }
2441 
2442     {
2443         boost::shared_ptr<void const volatile> px(new int);
2444 
2445         boost::shared_ptr<void> px2 = boost::const_pointer_cast<void>(px);
2446         BOOST_TEST(px.get() == px2.get());
2447         BOOST_TEST(!(px < px2 || px2 < px));
2448         BOOST_TEST(px.use_count() == 2);
2449         BOOST_TEST(px2.use_count() == 2);
2450     }
2451 
2452     {
2453         boost::shared_ptr<int const volatile> px(new int);
2454 
2455         boost::shared_ptr<int> px2 = boost::const_pointer_cast<int>(px);
2456         BOOST_TEST(px.get() == px2.get());
2457         BOOST_TEST(!(px < px2 || px2 < px));
2458         BOOST_TEST(px.use_count() == 2);
2459         BOOST_TEST(px2.use_count() == 2);
2460     }
2461 }
2462 
2463 } // namespace n_const_cast
2464 
2465 #if !defined( BOOST_NO_RTTI )
2466 
2467 namespace n_dynamic_cast
2468 {
2469 
2470 struct V
2471 {
~Vn_dynamic_cast::V2472     virtual ~V() {}
2473 };
2474 
2475 struct W: public V
2476 {
2477 };
2478 
test()2479 void test()
2480 {
2481     {
2482         boost::shared_ptr<V> pv;
2483         boost::shared_ptr<W> pw = boost::dynamic_pointer_cast<W>(pv);
2484         BOOST_TEST(pw.get() == 0);
2485     }
2486 
2487     {
2488         boost::shared_ptr<V> pv(static_cast<V*>(0));
2489 
2490         boost::shared_ptr<W> pw = boost::dynamic_pointer_cast<W>(pv);
2491         BOOST_TEST(pw.get() == 0);
2492 
2493         boost::shared_ptr<V> pv2(pw);
2494         BOOST_TEST(pv < pv2 || pv2 < pv);
2495     }
2496 
2497     {
2498         boost::shared_ptr<V> pv(static_cast<W*>(0));
2499 
2500         boost::shared_ptr<W> pw = boost::dynamic_pointer_cast<W>(pv);
2501         BOOST_TEST(pw.get() == 0);
2502 
2503         boost::shared_ptr<V> pv2(pw);
2504         BOOST_TEST(pv < pv2 || pv2 < pv);
2505     }
2506 
2507     {
2508         boost::shared_ptr<V> pv(new V);
2509 
2510         boost::shared_ptr<W> pw = boost::dynamic_pointer_cast<W>(pv);
2511         BOOST_TEST(pw.get() == 0);
2512 
2513         boost::shared_ptr<V> pv2(pw);
2514         BOOST_TEST(pv < pv2 || pv2 < pv);
2515     }
2516 
2517     {
2518         boost::shared_ptr<V> pv(new W);
2519 
2520         boost::shared_ptr<W> pw = boost::dynamic_pointer_cast<W>(pv);
2521         BOOST_TEST(pw.get() == pv.get());
2522         BOOST_TEST(pv.use_count() == 2);
2523         BOOST_TEST(pw.use_count() == 2);
2524 
2525         boost::shared_ptr<V> pv2(pw);
2526         BOOST_TEST(!(pv < pv2 || pv2 < pv));
2527     }
2528 }
2529 
2530 } // namespace n_dynamic_cast
2531 
2532 #endif
2533 
2534 namespace n_map
2535 {
2536 
2537 struct X
2538 {
2539 };
2540 
test()2541 void test()
2542 {
2543     std::vector< boost::shared_ptr<int> > vi;
2544 
2545     {
2546         boost::shared_ptr<int> pi1(new int);
2547         boost::shared_ptr<int> pi2(new int);
2548         boost::shared_ptr<int> pi3(new int);
2549 
2550         vi.push_back(pi1);
2551         vi.push_back(pi1);
2552         vi.push_back(pi1);
2553         vi.push_back(pi2);
2554         vi.push_back(pi1);
2555         vi.push_back(pi2);
2556         vi.push_back(pi1);
2557         vi.push_back(pi3);
2558         vi.push_back(pi3);
2559         vi.push_back(pi2);
2560         vi.push_back(pi1);
2561     }
2562 
2563     std::vector< boost::shared_ptr<X> > vx;
2564 
2565     {
2566         boost::shared_ptr<X> px1(new X);
2567         boost::shared_ptr<X> px2(new X);
2568         boost::shared_ptr<X> px3(new X);
2569 
2570         vx.push_back(px2);
2571         vx.push_back(px2);
2572         vx.push_back(px1);
2573         vx.push_back(px2);
2574         vx.push_back(px1);
2575         vx.push_back(px1);
2576         vx.push_back(px1);
2577         vx.push_back(px2);
2578         vx.push_back(px1);
2579         vx.push_back(px3);
2580         vx.push_back(px2);
2581     }
2582 
2583     std::map< boost::shared_ptr<void>, long > m;
2584 
2585     {
2586         for(std::vector< boost::shared_ptr<int> >::iterator i = vi.begin(); i != vi.end(); ++i)
2587         {
2588             ++m[*i];
2589         }
2590     }
2591 
2592     {
2593         for(std::vector< boost::shared_ptr<X> >::iterator i = vx.begin(); i != vx.end(); ++i)
2594         {
2595             ++m[*i];
2596         }
2597     }
2598 
2599     {
2600         for(std::map< boost::shared_ptr<void>, long >::iterator i = m.begin(); i != m.end(); ++i)
2601         {
2602             BOOST_TEST(i->first.use_count() == i->second + 1);
2603         }
2604     }
2605 }
2606 
2607 } // namespace n_map
2608 
2609 namespace n_transitive
2610 {
2611 
2612 struct X
2613 {
Xn_transitive::X2614     X(): next() {}
2615     boost::shared_ptr<X> next;
2616 };
2617 
test()2618 void test()
2619 {
2620     boost::shared_ptr<X> p(new X);
2621     p->next = boost::shared_ptr<X>(new X);
2622     BOOST_TEST(!p->next->next);
2623     p = p->next;
2624     BOOST_TEST(!p->next);
2625 }
2626 
2627 } // namespace n_transitive
2628 
2629 namespace n_report_1
2630 {
2631 
2632 class foo
2633 {
2634 public:
2635 
foo()2636     foo(): m_self(this)
2637     {
2638     }
2639 
suicide()2640     void suicide()
2641     {
2642         m_self.reset();
2643     }
2644 
2645 private:
2646 
2647     boost::shared_ptr<foo> m_self;
2648 };
2649 
test()2650 void test()
2651 {
2652     foo * foo_ptr = new foo;
2653     foo_ptr->suicide();
2654 }
2655 
2656 } // namespace n_report_1
2657 
2658 // Test case by Per Kristensen
2659 namespace n_report_2
2660 {
2661 
2662 class foo
2663 {
2664 public:
2665 
setWeak(boost::shared_ptr<foo> s)2666     void setWeak(boost::shared_ptr<foo> s)
2667     {
2668         w = s;
2669     }
2670 
2671 private:
2672 
2673     boost::weak_ptr<foo> w;
2674 };
2675 
2676 class deleter
2677 {
2678 public:
2679 
deleter()2680     deleter(): lock(0)
2681     {
2682     }
2683 
~deleter()2684     ~deleter()
2685     {
2686         BOOST_TEST(lock == 0);
2687     }
2688 
operator ()(foo * p)2689     void operator() (foo * p)
2690     {
2691         ++lock;
2692         delete p;
2693         --lock;
2694     }
2695 
2696 private:
2697 
2698     int lock;
2699 };
2700 
test()2701 void test()
2702 {
2703     boost::shared_ptr<foo> s(new foo, deleter());
2704     s->setWeak(s);
2705     s.reset();
2706 }
2707 
2708 } // namespace n_report_2
2709 
2710 namespace n_spt_incomplete
2711 {
2712 
2713 class file;
2714 
2715 boost::shared_ptr<file> fopen(char const * name, char const * mode);
2716 void fread(boost::shared_ptr<file> f, void * data, long size);
2717 
2718 int file_instances = 0;
2719 
test()2720 void test()
2721 {
2722     BOOST_TEST(file_instances == 0);
2723 
2724     {
2725         boost::shared_ptr<file> pf = fopen("name", "mode");
2726         BOOST_TEST(file_instances == 1);
2727         fread(pf, 0, 17041);
2728     }
2729 
2730     BOOST_TEST(file_instances == 0);
2731 }
2732 
2733 } // namespace n_spt_incomplete
2734 
2735 namespace n_spt_pimpl
2736 {
2737 
2738 class file
2739 {
2740 private:
2741 
2742     class impl;
2743     boost::shared_ptr<impl> pimpl_;
2744 
2745 public:
2746 
2747     file(char const * name, char const * mode);
2748 
2749     // compiler generated members are fine and useful
2750 
2751     void read(void * data, long size);
2752 
2753     long total_size() const;
2754 };
2755 
2756 int file_instances = 0;
2757 
test()2758 void test()
2759 {
2760     BOOST_TEST(file_instances == 0);
2761 
2762     {
2763         file f("name", "mode");
2764         BOOST_TEST(file_instances == 1);
2765         f.read(0, 152);
2766 
2767         file f2(f);
2768         BOOST_TEST(file_instances == 1);
2769         f2.read(0, 894);
2770 
2771         BOOST_TEST(f.total_size() == 152+894);
2772 
2773         {
2774             file f3("name2", "mode2");
2775             BOOST_TEST(file_instances == 2);
2776         }
2777 
2778         BOOST_TEST(file_instances == 1);
2779     }
2780 
2781     BOOST_TEST(file_instances == 0);
2782 }
2783 
2784 } // namespace n_spt_pimpl
2785 
2786 namespace n_spt_abstract
2787 {
2788 
2789 class X
2790 {
2791 public:
2792 
2793     virtual void f(int) = 0;
2794     virtual int g() = 0;
2795 
2796 protected:
2797 
~X()2798     ~X() {}
2799 };
2800 
2801 boost::shared_ptr<X> createX();
2802 
2803 int X_instances = 0;
2804 
test()2805 void test()
2806 {
2807     BOOST_TEST(X_instances == 0);
2808 
2809     {
2810         boost::shared_ptr<X> px = createX();
2811 
2812         BOOST_TEST(X_instances == 1);
2813 
2814         px->f(18);
2815         px->f(152);
2816 
2817         BOOST_TEST(px->g() == 170);
2818     }
2819 
2820     BOOST_TEST(X_instances == 0);
2821 }
2822 
2823 } // namespace n_spt_abstract
2824 
2825 namespace n_spt_preventing_delete
2826 {
2827 
2828 int X_instances = 0;
2829 
2830 class X
2831 {
2832 private:
2833 
X()2834     X()
2835     {
2836         ++X_instances;
2837     }
2838 
~X()2839     ~X()
2840     {
2841         --X_instances;
2842     }
2843 
2844     class deleter;
2845     friend class deleter;
2846 
2847     class deleter
2848     {
2849     public:
2850 
operator ()(X * p)2851         void operator()(X * p) { delete p; }
2852     };
2853 
2854 public:
2855 
create()2856     static boost::shared_ptr<X> create()
2857     {
2858         boost::shared_ptr<X> px(new X, X::deleter());
2859         return px;
2860     }
2861 };
2862 
test()2863 void test()
2864 {
2865     BOOST_TEST(X_instances == 0);
2866 
2867     {
2868         boost::shared_ptr<X> px = X::create();
2869         BOOST_TEST(X_instances == 1);
2870     }
2871 
2872     BOOST_TEST(X_instances == 0);
2873 }
2874 
2875 } // namespace n_spt_preventing_delete
2876 
2877 namespace n_spt_array
2878 {
2879 
2880 int X_instances = 0;
2881 
2882 struct X
2883 {
Xn_spt_array::X2884     X()
2885     {
2886         ++X_instances;
2887     }
2888 
~Xn_spt_array::X2889     ~X()
2890     {
2891         --X_instances;
2892     }
2893 };
2894 
test()2895 void test()
2896 {
2897     BOOST_TEST(X_instances == 0);
2898 
2899     {
2900         boost::shared_ptr<X> px(new X[4], boost::checked_array_deleter<X>());
2901         BOOST_TEST(X_instances == 4);
2902     }
2903 
2904     BOOST_TEST(X_instances == 0);
2905 }
2906 
2907 } // namespace n_spt_array
2908 
2909 namespace n_spt_static
2910 {
2911 
2912 class X
2913 {
2914 public:
2915 
X()2916     X()
2917     {
2918     }
2919 
2920 private:
2921 
operator delete(void *)2922     void operator delete(void *)
2923     {
2924         // Comeau 4.3.0.1 wants a definition
2925         BOOST_ERROR("n_spt_static::X::operator delete() called.");
2926     }
2927 };
2928 
2929 struct null_deleter
2930 {
operator ()n_spt_static::null_deleter2931     void operator()(void const *) const
2932     {
2933     }
2934 };
2935 
2936 static X x;
2937 
test()2938 void test()
2939 {
2940     boost::shared_ptr<X> px(&x, null_deleter());
2941 }
2942 
2943 } // namespace n_spt_static
2944 
2945 namespace n_spt_intrusive
2946 {
2947 
2948 int X_instances = 0;
2949 
2950 struct X
2951 {
2952     long count;
2953 
Xn_spt_intrusive::X2954     X(): count(0)
2955     {
2956         ++X_instances;
2957     }
2958 
~Xn_spt_intrusive::X2959     ~X()
2960     {
2961         --X_instances;
2962     }
2963 };
2964 
intrusive_ptr_add_ref(X * p)2965 void intrusive_ptr_add_ref(X * p)
2966 {
2967     ++p->count;
2968 }
2969 
intrusive_ptr_release(X * p)2970 void intrusive_ptr_release(X * p)
2971 {
2972     if(--p->count == 0) delete p;
2973 }
2974 
2975 template<class T> struct intrusive_deleter
2976 {
operator ()n_spt_intrusive::intrusive_deleter2977     void operator()(T * p)
2978     {
2979         if(p != 0) intrusive_ptr_release(p);
2980     }
2981 };
2982 
make_shared_from_intrusive(X * p)2983 boost::shared_ptr<X> make_shared_from_intrusive(X * p)
2984 {
2985     if(p != 0) intrusive_ptr_add_ref(p);
2986     boost::shared_ptr<X> px(p, intrusive_deleter<X>());
2987     return px;
2988 }
2989 
test()2990 void test()
2991 {
2992     BOOST_TEST(X_instances == 0);
2993 
2994     {
2995         X * p = new X;
2996         BOOST_TEST(X_instances == 1);
2997         BOOST_TEST(p->count == 0);
2998         boost::shared_ptr<X> px = make_shared_from_intrusive(p);
2999         BOOST_TEST(px.get() == p);
3000         BOOST_TEST(p->count == 1);
3001         boost::shared_ptr<X> px2(px);
3002         BOOST_TEST(px2.get() == p);
3003         BOOST_TEST(p->count == 1);
3004     }
3005 
3006     BOOST_TEST(X_instances == 0);
3007 }
3008 
3009 } // namespace n_spt_intrusive
3010 
3011 namespace n_spt_another_sp
3012 {
3013 
3014 template<class T> class another_ptr: private boost::shared_ptr<T>
3015 {
3016 private:
3017 
3018     typedef boost::shared_ptr<T> base_type;
3019 
3020 public:
3021 
another_ptr(T * p=0)3022     explicit another_ptr(T * p = 0): base_type(p)
3023     {
3024     }
3025 
reset()3026     void reset()
3027     {
3028         base_type::reset();
3029     }
3030 
get() const3031     T * get() const
3032     {
3033         return base_type::get();
3034     }
3035 };
3036 
3037 class event_handler
3038 {
3039 public:
3040 
~event_handler()3041     virtual ~event_handler() {}
3042     virtual void begin() = 0;
3043     virtual void handle(int event) = 0;
3044     virtual void end() = 0;
3045 };
3046 
3047 int begin_called = 0;
3048 int handle_called = 0;
3049 int end_called = 0;
3050 
3051 class event_handler_impl: public event_handler
3052 {
3053 public:
3054 
begin()3055     virtual void begin()
3056     {
3057         ++begin_called;
3058     }
3059 
handle(int event)3060     virtual void handle(int event)
3061     {
3062         handle_called = event;
3063     }
3064 
end()3065     virtual void end()
3066     {
3067         ++end_called;
3068     }
3069 };
3070 
get_event_handler()3071 another_ptr<event_handler> get_event_handler()
3072 {
3073     another_ptr<event_handler> p(new event_handler_impl);
3074     return p;
3075 }
3076 
3077 boost::shared_ptr<event_handler> current_handler;
3078 
install_event_handler(boost::shared_ptr<event_handler> p)3079 void install_event_handler(boost::shared_ptr<event_handler> p)
3080 {
3081     p->begin();
3082     current_handler = p;
3083 }
3084 
handle_event(int event)3085 void handle_event(int event)
3086 {
3087     current_handler->handle(event);
3088 }
3089 
remove_event_handler()3090 void remove_event_handler()
3091 {
3092     current_handler->end();
3093     current_handler.reset();
3094 }
3095 
3096 template<class P> class smart_pointer_deleter
3097 {
3098 private:
3099 
3100     P p_;
3101 
3102 public:
3103 
smart_pointer_deleter(P const & p)3104     smart_pointer_deleter(P const & p): p_(p)
3105     {
3106     }
3107 
operator ()(void const *)3108     void operator()(void const *)
3109     {
3110         p_.reset();
3111     }
3112 };
3113 
test()3114 void test()
3115 {
3116     another_ptr<event_handler> p = get_event_handler();
3117 
3118     boost::shared_ptr<event_handler> q(p.get(), smart_pointer_deleter< another_ptr<event_handler> >(p));
3119 
3120     p.reset();
3121 
3122     BOOST_TEST(begin_called == 0);
3123 
3124     install_event_handler(q);
3125 
3126     BOOST_TEST(begin_called == 1);
3127 
3128     BOOST_TEST(handle_called == 0);
3129 
3130     handle_event(17041);
3131 
3132     BOOST_TEST(handle_called == 17041);
3133 
3134     BOOST_TEST(end_called == 0);
3135 
3136     remove_event_handler();
3137 
3138     BOOST_TEST(end_called == 1);
3139 }
3140 
3141 } // namespace n_spt_another_sp
3142 
3143 namespace n_spt_shared_from_this
3144 {
3145 
3146 class X
3147 {
3148 public:
3149 
3150     virtual void f() = 0;
3151 
3152 protected:
3153 
~X()3154     ~X() {}
3155 };
3156 
3157 class Y
3158 {
3159 public:
3160 
3161     virtual boost::shared_ptr<X> getX() = 0;
3162 
3163 protected:
3164 
~Y()3165     ~Y() {}
3166 };
3167 
3168 class impl: public X, public Y
3169 {
3170 private:
3171 
3172     boost::weak_ptr<impl> weak_this;
3173 
3174     impl(impl const &);
3175     impl & operator=(impl const &);
3176 
impl()3177     impl() {}
3178 
3179 public:
3180 
create()3181     static boost::shared_ptr<impl> create()
3182     {
3183         boost::shared_ptr<impl> pi(new impl);
3184         pi->weak_this = pi;
3185         return pi;
3186     }
3187 
f()3188     virtual void f() {}
3189 
getX()3190     virtual boost::shared_ptr<X> getX()
3191     {
3192         boost::shared_ptr<X> px = weak_this.lock();
3193         return px;
3194     }
3195 };
3196 
test()3197 void test()
3198 {
3199     boost::shared_ptr<Y> py = impl::create();
3200     BOOST_TEST(py.get() != 0);
3201     BOOST_TEST(py.use_count() == 1);
3202 
3203     boost::shared_ptr<X> px = py->getX();
3204     BOOST_TEST(px.get() != 0);
3205     BOOST_TEST(py.use_count() == 2);
3206 
3207 #if !defined( BOOST_NO_RTTI )
3208     boost::shared_ptr<Y> py2 = boost::dynamic_pointer_cast<Y>(px);
3209     BOOST_TEST(py.get() == py2.get());
3210     BOOST_TEST(!(py < py2 || py2 < py));
3211     BOOST_TEST(py.use_count() == 3);
3212 #endif
3213 }
3214 
3215 } // namespace n_spt_shared_from_this
3216 
3217 namespace n_spt_wrap
3218 {
3219 
test()3220 void test()
3221 {
3222 }
3223 
3224 } // namespace n_spt_wrap
3225 
main()3226 int main()
3227 {
3228     n_element_type::test();
3229     n_constructors::test();
3230     n_assignment::test();
3231     n_reset::test();
3232     n_access::test();
3233     n_use_count::test();
3234     n_swap::test();
3235     n_comparison::test();
3236     n_static_cast::test();
3237     n_const_cast::test();
3238 #if !defined( BOOST_NO_RTTI )
3239     n_dynamic_cast::test();
3240 #endif
3241 
3242     n_map::test();
3243 
3244     n_transitive::test();
3245     n_report_1::test();
3246     n_report_2::test();
3247 
3248     n_spt_incomplete::test();
3249     n_spt_pimpl::test();
3250     n_spt_abstract::test();
3251     n_spt_preventing_delete::test();
3252     n_spt_array::test();
3253     n_spt_static::test();
3254     n_spt_intrusive::test();
3255     n_spt_another_sp::test();
3256     n_spt_shared_from_this::test();
3257     n_spt_wrap::test();
3258 
3259     return boost::report_errors();
3260 }
3261 
3262 namespace n_spt_incomplete
3263 {
3264 
3265 class file
3266 {
3267 public:
3268 
file()3269     file(): fread_called(false)
3270     {
3271         ++file_instances;
3272     }
3273 
~file()3274     ~file()
3275     {
3276         BOOST_TEST(fread_called);
3277         --file_instances;
3278     }
3279 
3280     bool fread_called;
3281 };
3282 
fopen(char const *,char const *)3283 boost::shared_ptr<file> fopen(char const *, char const *)
3284 {
3285     boost::shared_ptr<file> pf(new file);
3286     return pf;
3287 }
3288 
fread(boost::shared_ptr<file> pf,void *,long)3289 void fread(boost::shared_ptr<file> pf, void *, long)
3290 {
3291     pf->fread_called = true;
3292 }
3293 
3294 } // namespace n_spt_incomplete
3295 
3296 namespace n_spt_pimpl
3297 {
3298 
3299 class file::impl
3300 {
3301 private:
3302 
3303     impl(impl const &);
3304     impl & operator=(impl const &);
3305 
3306     long total_size_;
3307 
3308 public:
3309 
impl(char const *,char const *)3310     impl(char const *, char const *): total_size_(0)
3311     {
3312         ++file_instances;
3313     }
3314 
~impl()3315     ~impl()
3316     {
3317         --file_instances;
3318     }
3319 
read(void *,long size)3320     void read(void *, long size)
3321     {
3322         total_size_ += size;
3323     }
3324 
total_size() const3325     long total_size() const
3326     {
3327         return total_size_;
3328     }
3329 };
3330 
file(char const * name,char const * mode)3331 file::file(char const * name, char const * mode): pimpl_(new impl(name, mode))
3332 {
3333 }
3334 
read(void * data,long size)3335 void file::read(void * data, long size)
3336 {
3337     pimpl_->read(data, size);
3338 }
3339 
total_size() const3340 long file::total_size() const
3341 {
3342     return pimpl_->total_size();
3343 }
3344 
3345 } // namespace n_spt_pimpl
3346 
3347 namespace n_spt_abstract
3348 {
3349 
3350 class X_impl: public X
3351 {
3352 private:
3353 
3354     X_impl(X_impl const &);
3355     X_impl & operator=(X_impl const &);
3356 
3357     int n_;
3358 
3359 public:
3360 
X_impl()3361     X_impl(): n_(0)
3362     {
3363         ++X_instances;
3364     }
3365 
~X_impl()3366     ~X_impl()
3367     {
3368         --X_instances;
3369     }
3370 
f(int n)3371     virtual void f(int n)
3372     {
3373         n_ += n;
3374     }
3375 
g()3376     virtual int g()
3377     {
3378         return n_;
3379     }
3380 };
3381 
createX()3382 boost::shared_ptr<X> createX()
3383 {
3384     boost::shared_ptr<X> px(new X_impl);
3385     return px;
3386 }
3387 
3388 } // namespace n_spt_abstract
3389