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