CLHEP VERSION Reference Documentation
   
CLHEP Home Page     CLHEP Documentation     CLHEP Bug Reports

testSharedPtr.cc

Go to the documentation of this file.
00001 // ======================================================================
00002 //
00003 // Test compilability and basic functionality of Utility/memory.h
00004 //
00005 // Author:  W. E. Brown, 2010-03-19, adapted from the boost library's
00006 // shared_ptr and related functionality whose internal attributions bear
00007 // the following various notices:
00008 //
00009 //   Copyright (c) 2002, 2003 Peter Dimov
00010 //   Distributed under the Boost Software License, Version 1.0.
00011 //   See http://www.boost.org/LICENSE_1_0.txt
00012 //
00013 // ======================================================================
00014 
00015 
00016 #include "CLHEP/Utility/memory.h"
00017 
00018 #include <cassert>
00019 #include <map>
00020 #include <vector>
00021 
00022 
00023 using namespace CLHEP;
00024 using CLHEP::shared_ptr;
00025 using CLHEP::weak_ptr;
00026 
00027 
00028 #if defined(_MSC_VER) && (_MSC_VER >= 1310)
00029 #  pragma warning (disable : 4675)  // suppress ADL warning
00030 #endif
00031 
00032 
00033 namespace n_element_type
00034 {
00035 
00036 void
00037   f(int &)
00038 { }
00039 
00040 void
00041   test()
00042 {
00043   typedef shared_ptr<int>::element_type T;
00044   T t;
00045   f(t);
00046 }
00047 
00048 } // namespace n_element_type
00049 
00050 namespace n_constructors
00051 {
00052 
00053 class incomplete;
00054 
00055 void
00056   default_constructor()
00057 {
00058   {
00059     shared_ptr<int> pi;
00060     assert(pi? false: true);
00061     assert(!pi);
00062     assert(pi.get() == 0);
00063     assert(pi.use_count() == 0);
00064   }
00065 
00066   {
00067     shared_ptr<void> pv;
00068     assert(pv? false: true);
00069     assert(!pv);
00070     assert(pv.get() == 0);
00071     assert(pv.use_count() == 0);
00072   }
00073 
00074   {
00075     shared_ptr<incomplete> px;
00076     assert(px? false: true);
00077     assert(!px);
00078     assert(px.get() == 0);
00079     assert(px.use_count() == 0);
00080   }
00081 }
00082 
00083 struct A
00084 {
00085   int dummy;
00086 };
00087 
00088 struct X
00089 {
00090   static long instances;
00091 
00092   X()
00093   {
00094     ++instances;
00095   }
00096 
00097   ~X()
00098   {
00099     --instances;
00100   }
00101 
00102 private:
00103   X(X const &);
00104   X & operator= (X const &);
00105 };
00106 
00107 long X::instances = 0;
00108 
00109 // virtual inheritance stresses the implementation
00110 
00111 struct Y
00112   : public A
00113   , public virtual X
00114 {
00115   static long instances;
00116 
00117   Y()
00118   {
00119     ++instances;
00120   }
00121 
00122   ~Y()
00123   {
00124     --instances;
00125   }
00126 
00127 private:
00128   Y(Y const &);
00129   Y & operator= (Y const &);
00130 };
00131 
00132 long Y::instances = 0;
00133 
00134 template< class T >
00135   void
00136   pc0_test(T * p)
00137 {
00138   assert(p == 0);
00139   shared_ptr<T> pt(p);
00140   assert(pt? false: true);
00141   assert(!pt);
00142   assert(pt.get() == 0);
00143   assert(pt.use_count() == 1);
00144   assert(pt.unique());
00145 }
00146 
00147 void
00148   pointer_constructor()
00149 {
00150   pc0_test(static_cast<int*>(0));
00151 
00152   pc0_test(static_cast<int const*>(0));
00153   pc0_test(static_cast<int volatile*>(0));
00154   pc0_test(static_cast<int const volatile*>(0));
00155 
00156   {
00157     shared_ptr<int const> pi(static_cast<int*>(0));
00158     assert(pi? false: true);
00159     assert(!pi);
00160     assert(pi.get() == 0);
00161     assert(pi.use_count() == 1);
00162     assert(pi.unique());
00163   }
00164 
00165   {
00166     shared_ptr<int volatile> pi(static_cast<int*>(0));
00167     assert(pi? false: true);
00168     assert(!pi);
00169     assert(pi.get() == 0);
00170     assert(pi.use_count() == 1);
00171     assert(pi.unique());
00172   }
00173 
00174   {
00175     shared_ptr<void> pv(static_cast<int*>(0));
00176     assert(pv? false: true);
00177     assert(!pv);
00178     assert(pv.get() == 0);
00179     assert(pv.use_count() == 1);
00180     assert(pv.unique());
00181   }
00182 
00183   {
00184     shared_ptr<void const> pv(static_cast<int*>(0));
00185     assert(pv? false: true);
00186     assert(!pv);
00187     assert(pv.get() == 0);
00188     assert(pv.use_count() == 1);
00189     assert(pv.unique());
00190   }
00191 
00192   pc0_test(static_cast<X*>(0));
00193   pc0_test(static_cast<X const*>(0));
00194   pc0_test(static_cast<X volatile*>(0));
00195   pc0_test(static_cast<X const volatile*>(0));
00196 
00197   {
00198     shared_ptr<X const> px(static_cast<X*>(0));
00199     assert(px? false: true);
00200     assert(!px);
00201     assert(px.get() == 0);
00202     assert(px.use_count() == 1);
00203     assert(px.unique());
00204   }
00205 
00206   {
00207     shared_ptr<X> px(static_cast<Y*>(0));
00208     assert(px? false: true);
00209     assert(!px);
00210     assert(px.get() == 0);
00211     assert(px.use_count() == 1);
00212     assert(px.unique());
00213   }
00214 
00215   {
00216     shared_ptr<X const> px(static_cast<Y*>(0));
00217     assert(px? false: true);
00218     assert(!px);
00219     assert(px.get() == 0);
00220     assert(px.use_count() == 1);
00221     assert(px.unique());
00222   }
00223 
00224   {
00225     shared_ptr<void> pv(static_cast<X*>(0));
00226     assert(pv? false: true);
00227     assert(!pv);
00228     assert(pv.get() == 0);
00229     assert(pv.use_count() == 1);
00230     assert(pv.unique());
00231   }
00232 
00233   {
00234     shared_ptr<void const> pv(static_cast<X*>(0));
00235     assert(pv? false: true);
00236     assert(!pv);
00237     assert(pv.get() == 0);
00238     assert(pv.use_count() == 1);
00239     assert(pv.unique());
00240   }
00241 
00242   {
00243     int * p = new int(7);
00244     shared_ptr<int> pi(p);
00245     assert(pi? true: false);
00246     assert(!!pi);
00247     assert(pi.get() == p);
00248     assert(pi.use_count() == 1);
00249     assert(pi.unique());
00250     assert(*pi == 7);
00251   }
00252 
00253   {
00254     int * p = new int(7);
00255     shared_ptr<int const> pi(p);
00256     assert(pi? true: false);
00257     assert(!!pi);
00258     assert(pi.get() == p);
00259     assert(pi.use_count() == 1);
00260     assert(pi.unique());
00261     assert(*pi == 7);
00262   }
00263 
00264   {
00265     int * p = new int(7);
00266     shared_ptr<void> pv(p);
00267     assert(pv? true: false);
00268     assert(!!pv);
00269     assert(pv.get() == p);
00270     assert(pv.use_count() == 1);
00271     assert(pv.unique());
00272   }
00273 
00274   {
00275     int * p = new int(7);
00276     shared_ptr<void const> pv(p);
00277     assert(pv? true: false);
00278     assert(!!pv);
00279     assert(pv.get() == p);
00280     assert(pv.use_count() == 1);
00281     assert(pv.unique());
00282   }
00283 
00284   assert(X::instances == 0);
00285 
00286   {
00287     X * p = new X;
00288     shared_ptr<X> px(p);
00289     assert(px? true: false);
00290     assert(!!px);
00291     assert(px.get() == p);
00292     assert(px.use_count() == 1);
00293     assert(px.unique());
00294     assert(X::instances == 1);
00295   }
00296 
00297   assert(X::instances == 0);
00298 
00299   {
00300     X * p = new X;
00301     shared_ptr<X const> px(p);
00302     assert(px? true: false);
00303     assert(!!px);
00304     assert(px.get() == p);
00305     assert(px.use_count() == 1);
00306     assert(px.unique());
00307     assert(X::instances == 1);
00308   }
00309 
00310   assert(X::instances == 0);
00311 
00312   {
00313     X * p = new X;
00314     shared_ptr<void> pv(p);
00315     assert(pv? true: false);
00316     assert(!!pv);
00317     assert(pv.get() == p);
00318     assert(pv.use_count() == 1);
00319     assert(pv.unique());
00320     assert(X::instances == 1);
00321   }
00322 
00323   assert(X::instances == 0);
00324 
00325   {
00326     X * p = new X;
00327     shared_ptr<void const> pv(p);
00328     assert(pv? true: false);
00329     assert(!!pv);
00330     assert(pv.get() == p);
00331     assert(pv.use_count() == 1);
00332     assert(pv.unique());
00333     assert(X::instances == 1);
00334   }
00335 
00336   assert(X::instances == 0);
00337   assert(Y::instances == 0);
00338 
00339   {
00340     Y * p = new Y;
00341     shared_ptr<X> px(p);
00342     assert(px? true: false);
00343     assert(!!px);
00344     assert(px.get() == p);
00345     assert(px.use_count() == 1);
00346     assert(px.unique());
00347     assert(X::instances == 1);
00348     assert(Y::instances == 1);
00349   }
00350 
00351   assert(X::instances == 0);
00352   assert(Y::instances == 0);
00353 
00354   {
00355     Y * p = new Y;
00356     shared_ptr<X const> px(p);
00357     assert(px? true: false);
00358     assert(!!px);
00359     assert(px.get() == p);
00360     assert(px.use_count() == 1);
00361     assert(px.unique());
00362     assert(X::instances == 1);
00363     assert(Y::instances == 1);
00364   }
00365 
00366   assert(X::instances == 0);
00367   assert(Y::instances == 0);
00368 }
00369 
00370 int m = 0;
00371 
00372 void
00373   deleter(int * p)
00374 {
00375   assert(p == 0);
00376 }
00377 
00378 void
00379   deleter2(int * p)
00380 {
00381   assert(p == &m);
00382   ++*p;
00383 }
00384 
00385 struct deleter3
00386 {
00387   void operator()(incomplete * p)
00388   {
00389     assert(p == 0);
00390   }
00391 };
00392 
00393 incomplete * p0 = 0;
00394 
00395 void
00396   deleter_constructor()
00397 {
00398   {
00399     shared_ptr<int> pi(static_cast<int*>(0), deleter);
00400     assert(pi? false: true);
00401     assert(!pi);
00402     assert(pi.get() == 0);
00403     assert(pi.use_count() == 1);
00404     assert(pi.unique());
00405   }
00406 
00407   {
00408     shared_ptr<void> pv(static_cast<int*>(0), &deleter);
00409     assert(pv? false: true);
00410     assert(!pv);
00411     assert(pv.get() == 0);
00412     assert(pv.use_count() == 1);
00413     assert(pv.unique());
00414   }
00415 
00416   {
00417     shared_ptr<void const> pv(static_cast<int*>(0), deleter);
00418     assert(pv? false: true);
00419     assert(!pv);
00420     assert(pv.get() == 0);
00421     assert(pv.use_count() == 1);
00422     assert(pv.unique());
00423   }
00424 
00425   {
00426     shared_ptr<incomplete> px(p0, deleter3());
00427     assert(px? false: true);
00428     assert(!px);
00429     assert(px.get() == 0);
00430     assert(px.use_count() == 1);
00431     assert(px.unique());
00432   }
00433 
00434   {
00435     shared_ptr<void> pv(p0, deleter3());
00436     assert(pv? false: true);
00437     assert(!pv);
00438     assert(pv.get() == 0);
00439     assert(pv.use_count() == 1);
00440     assert(pv.unique());
00441   }
00442 
00443   {
00444     shared_ptr<void const> pv(p0, deleter3());
00445     assert(pv? false: true);
00446     assert(!pv);
00447     assert(pv.get() == 0);
00448     assert(pv.use_count() == 1);
00449     assert(pv.unique());
00450   }
00451 
00452   assert(m == 0);
00453 
00454   {
00455     shared_ptr<int> pi(&m, deleter2);
00456     assert(pi? true: false);
00457     assert(!!pi);
00458     assert(pi.get() == &m);
00459     assert(pi.use_count() == 1);
00460     assert(pi.unique());
00461   }
00462 
00463   assert(m == 1);
00464 
00465   {
00466     shared_ptr<int const> pi(&m, &deleter2);
00467     assert(pi? true: false);
00468     assert(!!pi);
00469     assert(pi.get() == &m);
00470     assert(pi.use_count() == 1);
00471     assert(pi.unique());
00472   }
00473 
00474   assert(m == 2);
00475 
00476   {
00477     shared_ptr<void> pv(&m, deleter2);
00478     assert(pv? true: false);
00479     assert(!!pv);
00480     assert(pv.get() == &m);
00481     assert(pv.use_count() == 1);
00482     assert(pv.unique());
00483   }
00484 
00485   assert(m == 3);
00486 
00487   {
00488     shared_ptr<void const> pv(&m, &deleter2);
00489     assert(pv? true: false);
00490     assert(!!pv);
00491     assert(pv.get() == &m);
00492     assert(pv.use_count() == 1);
00493     assert(pv.unique());
00494   }
00495 
00496   assert(m == 4);
00497 }
00498 
00499 void
00500   copy_constructor()
00501 {
00502   {
00503     shared_ptr<int> pi;
00504 
00505     shared_ptr<int> pi2(pi);
00506     assert(pi2 == pi);
00507     assert(pi2? false: true);
00508     assert(!pi2);
00509     assert(pi2.get() == 0);
00510     assert(pi2.use_count() == pi.use_count());
00511 
00512     shared_ptr<void> pi3(pi);
00513     assert(pi3 == pi);
00514     assert(pi3? false: true);
00515     assert(!pi3);
00516     assert(pi3.get() == 0);
00517     assert(pi3.use_count() == pi.use_count());
00518 
00519     shared_ptr<void> pi4(pi3);
00520     assert(pi4 == pi3);
00521     assert(pi4? false: true);
00522     assert(!pi4);
00523     assert(pi4.get() == 0);
00524     assert(pi4.use_count() == pi3.use_count());
00525   }
00526 
00527   {
00528     shared_ptr<void> pv;
00529 
00530     shared_ptr<void> pv2(pv);
00531     assert(pv2 == pv);
00532     assert(pv2? false: true);
00533     assert(!pv2);
00534     assert(pv2.get() == 0);
00535     assert(pv2.use_count() == pv.use_count());
00536   }
00537 
00538   {
00539     shared_ptr<incomplete> px;
00540 
00541     shared_ptr<incomplete> px2(px);
00542     assert(px2 == px);
00543     assert(px2? false: true);
00544     assert(!px2);
00545     assert(px2.get() == 0);
00546     assert(px2.use_count() == px.use_count());
00547 
00548     shared_ptr<void> px3(px);
00549     assert(px3 == px);
00550     assert(px3? false: true);
00551     assert(!px3);
00552     assert(px3.get() == 0);
00553     assert(px3.use_count() == px.use_count());
00554   }
00555 
00556   {
00557     shared_ptr<int> pi(static_cast<int*>(0));
00558 
00559     shared_ptr<int> pi2(pi);
00560     assert(pi2 == pi);
00561     assert(pi2? false: true);
00562     assert(!pi2);
00563     assert(pi2.get() == 0);
00564     assert(pi2.use_count() == 2);
00565     assert(!pi2.unique());
00566     assert(pi2.use_count() == pi.use_count());
00567     assert(!(pi < pi2 || pi2 < pi)); // shared ownership test
00568 
00569     shared_ptr<void> pi3(pi);
00570     assert(pi3 == pi);
00571     assert(pi3? false: true);
00572     assert(!pi3);
00573     assert(pi3.get() == 0);
00574     assert(pi3.use_count() == 3);
00575     assert(!pi3.unique());
00576     assert(pi3.use_count() == pi.use_count());
00577     assert(!(pi < pi3 || pi3 < pi)); // shared ownership test
00578 
00579     shared_ptr<void> pi4(pi2);
00580     assert(pi4 == pi2);
00581     assert(pi4? false: true);
00582     assert(!pi4);
00583     assert(pi4.get() == 0);
00584     assert(pi4.use_count() == 4);
00585     assert(!pi4.unique());
00586     assert(pi4.use_count() == pi2.use_count());
00587     assert(!(pi2 < pi4 || pi4 < pi2)); // shared ownership test
00588 
00589     assert(pi3.use_count() == pi4.use_count());
00590     assert(!(pi3 < pi4 || pi4 < pi3)); // shared ownership test
00591   }
00592 
00593   {
00594     shared_ptr<X> px(static_cast<X*>(0));
00595 
00596     shared_ptr<X> px2(px);
00597     assert(px2 == px);
00598     assert(px2? false: true);
00599     assert(!px2);
00600     assert(px2.get() == 0);
00601     assert(px2.use_count() == 2);
00602     assert(!px2.unique());
00603     assert(px2.use_count() == px.use_count());
00604     assert(!(px < px2 || px2 < px)); // shared ownership test
00605 
00606     shared_ptr<void> px3(px);
00607     assert(px3 == px);
00608     assert(px3? false: true);
00609     assert(!px3);
00610     assert(px3.get() == 0);
00611     assert(px3.use_count() == 3);
00612     assert(!px3.unique());
00613     assert(px3.use_count() == px.use_count());
00614     assert(!(px < px3 || px3 < px)); // shared ownership test
00615 
00616     shared_ptr<void> px4(px2);
00617     assert(px4 == px2);
00618     assert(px4? false: true);
00619     assert(!px4);
00620     assert(px4.get() == 0);
00621     assert(px4.use_count() == 4);
00622     assert(!px4.unique());
00623     assert(px4.use_count() == px2.use_count());
00624     assert(!(px2 < px4 || px4 < px2)); // shared ownership test
00625 
00626     assert(px3.use_count() == px4.use_count());
00627     assert(!(px3 < px4 || px4 < px3)); // shared ownership test
00628   }
00629 
00630   {
00631     int * p = new int(7);
00632     shared_ptr<int> pi(p);
00633 
00634     shared_ptr<int> pi2(pi);
00635     assert(pi2 == pi);
00636     assert(pi2? true: false);
00637     assert(!!pi2);
00638     assert(pi2.get() == p);
00639     assert(pi2.use_count() == 2);
00640     assert(!pi2.unique());
00641     assert(*pi2 == 7);
00642     assert(pi2.use_count() == pi.use_count());
00643     assert(!(pi < pi2 || pi2 < pi)); // shared ownership test
00644   }
00645 
00646   {
00647     int * p = new int(7);
00648     shared_ptr<void> pv(p);
00649     assert(pv.get() == p);
00650 
00651     shared_ptr<void> pv2(pv);
00652     assert(pv2 == pv);
00653     assert(pv2? true: false);
00654     assert(!!pv2);
00655     assert(pv2.get() == p);
00656     assert(pv2.use_count() == 2);
00657     assert(!pv2.unique());
00658     assert(pv2.use_count() == pv.use_count());
00659     assert(!(pv < pv2 || pv2 < pv)); // shared ownership test
00660   }
00661 
00662   assert(X::instances == 0);
00663 
00664   {
00665     X * p = new X;
00666     shared_ptr<X> px(p);
00667     assert(px.get() == p);
00668 
00669     shared_ptr<X> px2(px);
00670     assert(px2 == px);
00671     assert(px2? true: false);
00672     assert(!!px2);
00673     assert(px2.get() == p);
00674     assert(px2.use_count() == 2);
00675     assert(!px2.unique());
00676 
00677     assert(X::instances == 1);
00678 
00679     assert(px2.use_count() == px.use_count());
00680     assert(!(px < px2 || px2 < px)); // shared ownership test
00681 
00682     shared_ptr<void> px3(px);
00683     assert(px3 == px);
00684     assert(px3? true: false);
00685     assert(!!px3);
00686     assert(px3.get() == p);
00687     assert(px3.use_count() == 3);
00688     assert(!px3.unique());
00689     assert(px3.use_count() == px.use_count());
00690     assert(!(px < px3 || px3 < px)); // shared ownership test
00691 
00692     shared_ptr<void> px4(px2);
00693     assert(px4 == px2);
00694     assert(px4? true: false);
00695     assert(!!px4);
00696     assert(px4.get() == p);
00697     assert(px4.use_count() == 4);
00698     assert(!px4.unique());
00699     assert(px4.use_count() == px2.use_count());
00700     assert(!(px2 < px4 || px4 < px2)); // shared ownership test
00701 
00702     assert(px3.use_count() == px4.use_count());
00703     assert(!(px3 < px4 || px4 < px3)); // shared ownership test
00704   }
00705 
00706   assert(X::instances == 0);
00707   assert(Y::instances == 0);
00708 
00709   {
00710     Y * p = new Y;
00711     shared_ptr<Y> py(p);
00712     assert(py.get() == p);
00713 
00714     shared_ptr<X> px(py);
00715     assert(px == py);
00716     assert(px? true: false);
00717     assert(!!px);
00718     assert(px.get() == p);
00719     assert(px.use_count() == 2);
00720     assert(!px.unique());
00721     assert(px.use_count() == py.use_count());
00722     assert(!(px < py || py < px)); // shared ownership test
00723 
00724     assert(X::instances == 1);
00725     assert(Y::instances == 1);
00726 
00727     shared_ptr<void const> pv(px);
00728     assert(pv == px);
00729     assert(pv? true: false);
00730     assert(!!pv);
00731     assert(pv.get() == px.get());
00732     assert(pv.use_count() == 3);
00733     assert(!pv.unique());
00734     assert(pv.use_count() == px.use_count());
00735     assert(!(px < pv || pv < px)); // shared ownership test
00736 
00737     shared_ptr<void const> pv2(py);
00738     assert(pv2 == py);
00739     assert(pv2? true: false);
00740     assert(!!pv2);
00741     assert(pv2.get() == py.get());
00742     assert(pv2.use_count() == 4);
00743     assert(!pv2.unique());
00744     assert(pv2.use_count() == py.use_count());
00745     assert(!(py < pv2 || pv2 < py)); // shared ownership test
00746 
00747     assert(pv.use_count() == pv2.use_count());
00748     assert(!(pv < pv2 || pv2 < pv)); // shared ownership test
00749   }
00750 
00751   assert(X::instances == 0);
00752   assert(Y::instances == 0);
00753 }
00754 
00755 void
00756   weak_ptr_constructor()
00757 {
00758   {
00759     weak_ptr<Y> wp;
00760     assert(wp.use_count() == 0);
00761 
00762     try
00763     {
00764       shared_ptr<Y> p2(wp);
00765       throw "shared_ptr<Y> p2(wp) failed to throw";
00766     }
00767     catch(bad_weak_ptr)
00768     {
00769     }
00770 
00771     try
00772     {
00773       shared_ptr<X> p3(wp);
00774       throw "shared_ptr<X> p3(wp) failed to throw";
00775     }
00776     catch(bad_weak_ptr)
00777     {
00778     }
00779   }
00780 
00781   {
00782     shared_ptr<Y> p;
00783     weak_ptr<Y> wp(p);
00784 
00785     if(wp.use_count() != 0) // 0 allowed but not required
00786     {
00787       shared_ptr<Y> p2(wp);
00788       assert(p2.use_count() == wp.use_count());
00789       assert(p2.get() == 0);
00790 
00791       shared_ptr<X> p3(wp);
00792       assert(p3.use_count() == wp.use_count());
00793       assert(p3.get() == 0);
00794     }
00795   }
00796 
00797   {
00798     shared_ptr<Y> p(new Y);
00799     weak_ptr<Y> wp(p);
00800 
00801     {
00802       shared_ptr<Y> p2(wp);
00803       assert(p2? true: false);
00804       assert(!!p2);
00805       assert(p2.get() == p.get());
00806       assert(p2.use_count() == 2);
00807       assert(!p2.unique());
00808       assert(p2.use_count() == wp.use_count());
00809 
00810       assert(p.use_count() == p2.use_count());
00811       assert(!(p < p2 || p2 < p)); // shared ownership test
00812 
00813       shared_ptr<X> p3(wp);
00814       assert(p3? true: false);
00815       assert(!!p3);
00816       assert(p3.get() == p.get());
00817       assert(p3.use_count() == 3);
00818       assert(!p3.unique());
00819       assert(p3.use_count() == wp.use_count());
00820 
00821       assert(p.use_count() == p3.use_count());
00822     }
00823 
00824     p.reset();
00825     assert(wp.use_count() == 0);
00826 
00827     try
00828     {
00829       shared_ptr<Y> p2(wp);
00830       throw "shared_ptr<Y> p2(wp) failed to throw";
00831     }
00832     catch(bad_weak_ptr)
00833     {
00834     }
00835 
00836     try
00837     {
00838       shared_ptr<X> p3(wp);
00839       throw "shared_ptr<X> p3(wp) failed to throw";
00840     }
00841     catch(bad_weak_ptr)
00842     {
00843     }
00844   }
00845 }
00846 
00847 void
00848   auto_ptr_constructor()
00849 {
00850   {
00851     std::auto_ptr<int> p;
00852     shared_ptr<int> pi(p);
00853     assert(pi? false: true);
00854     assert(!pi);
00855     assert(pi.get() == 0);
00856     assert(pi.use_count() == 1);
00857     assert(pi.unique());
00858     assert(p.get() == 0);
00859   }
00860 
00861   {
00862     std::auto_ptr<int> p;
00863     shared_ptr<int const> pi(p);
00864     assert(pi? false: true);
00865     assert(!pi);
00866     assert(pi.get() == 0);
00867     assert(pi.use_count() == 1);
00868     assert(pi.unique());
00869     assert(p.get() == 0);
00870   }
00871 
00872   {
00873     std::auto_ptr<int> p;
00874     shared_ptr<void> pv(p);
00875     assert(pv? false: true);
00876     assert(!pv);
00877     assert(pv.get() == 0);
00878     assert(pv.use_count() == 1);
00879     assert(pv.unique());
00880     assert(p.get() == 0);
00881   }
00882 
00883   {
00884     std::auto_ptr<int> p;
00885     shared_ptr<void const> pv(p);
00886     assert(pv? false: true);
00887     assert(!pv);
00888     assert(pv.get() == 0);
00889     assert(pv.use_count() == 1);
00890     assert(pv.unique());
00891     assert(p.get() == 0);
00892   }
00893 
00894   {
00895     std::auto_ptr<X> p;
00896     shared_ptr<X> px(p);
00897     assert(px? false: true);
00898     assert(!px);
00899     assert(px.get() == 0);
00900     assert(px.use_count() == 1);
00901     assert(px.unique());
00902     assert(p.get() == 0);
00903   }
00904 
00905   {
00906     std::auto_ptr<X> p;
00907     shared_ptr<X const> px(p);
00908     assert(px? false: true);
00909     assert(!px);
00910     assert(px.get() == 0);
00911     assert(px.use_count() == 1);
00912     assert(px.unique());
00913     assert(p.get() == 0);
00914   }
00915 
00916   {
00917     std::auto_ptr<Y> p;
00918     shared_ptr<X> px(p);
00919     assert(px? false: true);
00920     assert(!px);
00921     assert(px.get() == 0);
00922     assert(px.use_count() == 1);
00923     assert(px.unique());
00924     assert(p.get() == 0);
00925   }
00926 
00927   {
00928     std::auto_ptr<Y> p;
00929     shared_ptr<X const> px(p);
00930     assert(px? false: true);
00931     assert(!px);
00932     assert(px.get() == 0);
00933     assert(px.use_count() == 1);
00934     assert(px.unique());
00935     assert(p.get() == 0);
00936   }
00937 
00938   {
00939     std::auto_ptr<Y> p;
00940     shared_ptr<void> pv(p);
00941     assert(pv? false: true);
00942     assert(!pv);
00943     assert(pv.get() == 0);
00944     assert(pv.use_count() == 1);
00945     assert(pv.unique());
00946     assert(p.get() == 0);
00947   }
00948 
00949   {
00950     std::auto_ptr<Y> p;
00951     shared_ptr<void const> pv(p);
00952     assert(pv? false: true);
00953     assert(!pv);
00954     assert(pv.get() == 0);
00955     assert(pv.use_count() == 1);
00956     assert(pv.unique());
00957     assert(p.get() == 0);
00958   }
00959 
00960   {
00961     std::auto_ptr<int> p(new int(7));
00962     int * q = p.get();
00963     shared_ptr<int> pi(p);
00964     assert(pi? true: false);
00965     assert(!!pi);
00966     assert(pi.get() == q);
00967     assert(pi.use_count() == 1);
00968     assert(pi.unique());
00969     assert(*pi == 7);
00970 
00971     assert(p.get() == 0);
00972   }
00973 
00974   {
00975     std::auto_ptr<int> p(new int(7));
00976     int * q = p.get();
00977     shared_ptr<int const> pi(p);
00978     assert(pi? true: false);
00979     assert(!!pi);
00980     assert(pi.get() == q);
00981     assert(pi.use_count() == 1);
00982     assert(pi.unique());
00983     assert(*pi == 7);
00984 
00985     assert(p.get() == 0);
00986   }
00987 
00988   {
00989     std::auto_ptr<int> p(new int(7));
00990     int * q = p.get();
00991     shared_ptr<void> pv(p);
00992     assert(pv? true: false);
00993     assert(!!pv);
00994     assert(pv.get() == q);
00995     assert(pv.use_count() == 1);
00996     assert(pv.unique());
00997 
00998     assert(p.get() == 0);
00999   }
01000 
01001   {
01002     std::auto_ptr<int> p(new int(7));
01003     int * q = p.get();
01004     shared_ptr<void const> pv(p);
01005     assert(pv? true: false);
01006     assert(!!pv);
01007     assert(pv.get() == q);
01008     assert(pv.use_count() == 1);
01009     assert(pv.unique());
01010 
01011     assert(p.get() == 0);
01012   }
01013 
01014   assert(X::instances == 0);
01015 
01016   {
01017     std::auto_ptr<X> p(new X);
01018     X * q = p.get();
01019     shared_ptr<X> px(p);
01020     assert(px? true: false);
01021     assert(!!px);
01022     assert(px.get() == q);
01023     assert(px.use_count() == 1);
01024     assert(px.unique());
01025     assert(X::instances == 1);
01026 
01027     assert(p.get() == 0);
01028   }
01029 
01030   assert(X::instances == 0);
01031 
01032   {
01033     std::auto_ptr<X> p(new X);
01034     X * q = p.get();
01035     shared_ptr<X const> px(p);
01036     assert(px? true: false);
01037     assert(!!px);
01038     assert(px.get() == q);
01039     assert(px.use_count() == 1);
01040     assert(px.unique());
01041     assert(X::instances == 1);
01042 
01043     assert(p.get() == 0);
01044   }
01045 
01046   assert(X::instances == 0);
01047 
01048   {
01049     std::auto_ptr<X> p(new X);
01050     X * q = p.get();
01051     shared_ptr<void> pv(p);
01052     assert(pv? true: false);
01053     assert(!!pv);
01054     assert(pv.get() == q);
01055     assert(pv.use_count() == 1);
01056     assert(pv.unique());
01057     assert(X::instances == 1);
01058 
01059     assert(p.get() == 0);
01060   }
01061 
01062   assert(X::instances == 0);
01063 
01064   {
01065     std::auto_ptr<X> p(new X);
01066     X * q = p.get();
01067     shared_ptr<void const> pv(p);
01068     assert(pv? true: false);
01069     assert(!!pv);
01070     assert(pv.get() == q);
01071     assert(pv.use_count() == 1);
01072     assert(pv.unique());
01073     assert(X::instances == 1);
01074 
01075     assert(p.get() == 0);
01076   }
01077 
01078   assert(X::instances == 0);
01079   assert(Y::instances == 0);
01080 
01081   {
01082     std::auto_ptr<Y> p(new Y);
01083     Y * q = p.get();
01084     shared_ptr<X> px(p);
01085     assert(px? true: false);
01086     assert(!!px);
01087     assert(px.get() == q);
01088     assert(px.use_count() == 1);
01089     assert(px.unique());
01090     assert(X::instances == 1);
01091     assert(Y::instances == 1);
01092 
01093     assert(p.get() == 0);
01094   }
01095 
01096   assert(X::instances == 0);
01097   assert(Y::instances == 0);
01098 
01099   {
01100     std::auto_ptr<Y> p(new Y);
01101     Y * q = p.get();
01102     shared_ptr<X const> px(p);
01103     assert(px? true: false);
01104     assert(!!px);
01105     assert(px.get() == q);
01106     assert(px.use_count() == 1);
01107     assert(px.unique());
01108     assert(X::instances == 1);
01109     assert(Y::instances == 1);
01110 
01111     assert(p.get() == 0);
01112   }
01113 
01114   assert(X::instances == 0);
01115   assert(Y::instances == 0);
01116 }
01117 
01118 void
01119   test()
01120 {
01121   default_constructor();
01122   pointer_constructor();
01123   deleter_constructor();
01124   copy_constructor();
01125   weak_ptr_constructor();
01126   auto_ptr_constructor();
01127 }
01128 
01129 } // namespace n_constructors
01130 
01131 namespace n_assignment
01132 {
01133 
01134 class incomplete;
01135 
01136 struct A
01137 {
01138   int dummy;
01139 };
01140 
01141 struct X
01142 {
01143   static long instances;
01144 
01145   X()
01146   {
01147     ++instances;
01148   }
01149 
01150   ~X()
01151   {
01152     --instances;
01153   }
01154 
01155 private:
01156   X(X const &);
01157   X & operator= (X const &);
01158 };
01159 
01160 long X::instances = 0;
01161 
01162 struct Y
01163   : public A
01164   , public virtual X
01165 {
01166   static long instances;
01167 
01168   Y()
01169   {
01170     ++instances;
01171   }
01172 
01173   ~Y()
01174   {
01175     --instances;
01176   }
01177 
01178 private:
01179   Y(Y const &);
01180   Y & operator= (Y const &);
01181 };
01182 
01183 long Y::instances = 0;
01184 
01185 void
01186   copy_assignment()
01187 {
01188   {
01189     shared_ptr<incomplete> p1;
01190 
01191     p1 = p1;
01192 
01193     assert(p1 == p1);
01194     assert(p1? false: true);
01195     assert(!p1);
01196     assert(p1.get() == 0);
01197 
01198     shared_ptr<incomplete> p2;
01199 
01200     p1 = p2;
01201 
01202     assert(p1 == p2);
01203     assert(p1? false: true);
01204     assert(!p1);
01205     assert(p1.get() == 0);
01206 
01207     shared_ptr<incomplete> p3(p1);
01208 
01209     p1 = p3;
01210 
01211     assert(p1 == p3);
01212     assert(p1? false: true);
01213     assert(!p1);
01214     assert(p1.get() == 0);
01215   }
01216 
01217   {
01218     shared_ptr<void> p1;
01219 
01220     p1 = p1;
01221 
01222     assert(p1 == p1);
01223     assert(p1? false: true);
01224     assert(!p1);
01225     assert(p1.get() == 0);
01226 
01227     shared_ptr<void> p2;
01228 
01229     p1 = p2;
01230 
01231     assert(p1 == p2);
01232     assert(p1? false: true);
01233     assert(!p1);
01234     assert(p1.get() == 0);
01235 
01236     shared_ptr<void> p3(p1);
01237 
01238     p1 = p3;
01239 
01240     assert(p1 == p3);
01241     assert(p1? false: true);
01242     assert(!p1);
01243     assert(p1.get() == 0);
01244 
01245     shared_ptr<void> p4(new int);
01246     assert(p4.use_count() == 1);
01247 
01248     p1 = p4;
01249 
01250     assert(p1 == p4);
01251     assert(!(p1 < p4 || p4 < p1));
01252     assert(p1.use_count() == 2);
01253     assert(p4.use_count() == 2);
01254 
01255     p1 = p3;
01256 
01257     assert(p1 == p3);
01258     assert(p4.use_count() == 1);
01259   }
01260 
01261   {
01262     shared_ptr<X> p1;
01263 
01264     p1 = p1;
01265 
01266     assert(p1 == p1);
01267     assert(p1? false: true);
01268     assert(!p1);
01269     assert(p1.get() == 0);
01270 
01271     shared_ptr<X> p2;
01272 
01273     p1 = p2;
01274 
01275     assert(p1 == p2);
01276     assert(p1? false: true);
01277     assert(!p1);
01278     assert(p1.get() == 0);
01279 
01280     shared_ptr<X> p3(p1);
01281 
01282     p1 = p3;
01283 
01284     assert(p1 == p3);
01285     assert(p1? false: true);
01286     assert(!p1);
01287     assert(p1.get() == 0);
01288 
01289     assert(X::instances == 0);
01290 
01291     shared_ptr<X> p4(new X);
01292 
01293     assert(X::instances == 1);
01294 
01295     p1 = p4;
01296 
01297     assert(X::instances == 1);
01298 
01299     assert(p1 == p4);
01300     assert(!(p1 < p4 || p4 < p1));
01301 
01302     assert(p1.use_count() == 2);
01303 
01304     p1 = p2;
01305 
01306     assert(p1 == p2);
01307     assert(X::instances == 1);
01308 
01309     p4 = p3;
01310 
01311     assert(p4 == p3);
01312     assert(X::instances == 0);
01313   }
01314 }
01315 
01316 void
01317   conversion_assignment()
01318 {
01319   {
01320     shared_ptr<void> p1;
01321 
01322     shared_ptr<incomplete> p2;
01323 
01324     p1 = p2;
01325 
01326     assert(p1 == p2);
01327     assert(p1? false: true);
01328     assert(!p1);
01329     assert(p1.get() == 0);
01330 
01331     shared_ptr<int> p4(new int);
01332     assert(p4.use_count() == 1);
01333 
01334     shared_ptr<void> p5(p4);
01335     assert(p4.use_count() == 2);
01336 
01337     p1 = p4;
01338 
01339     assert(p1 == p4);
01340     assert(!(p1 < p5 || p5 < p1));
01341     assert(p1.use_count() == 3);
01342     assert(p4.use_count() == 3);
01343 
01344     p1 = p2;
01345 
01346     assert(p1 == p2);
01347     assert(p4.use_count() == 2);
01348   }
01349 
01350   {
01351     shared_ptr<X> p1;
01352 
01353     shared_ptr<Y> p2;
01354 
01355     p1 = p2;
01356 
01357     assert(p1 == p2);
01358     assert(p1? false: true);
01359     assert(!p1);
01360     assert(p1.get() == 0);
01361 
01362     assert(X::instances == 0);
01363     assert(Y::instances == 0);
01364 
01365     shared_ptr<Y> p4(new Y);
01366 
01367     assert(X::instances == 1);
01368     assert(Y::instances == 1);
01369     assert(p4.use_count() == 1);
01370 
01371     shared_ptr<X> p5(p4);
01372     assert(p4.use_count() == 2);
01373 
01374     p1 = p4;
01375 
01376     assert(X::instances == 1);
01377     assert(Y::instances == 1);
01378 
01379     assert(p1 == p4);
01380     assert(!(p1 < p5 || p5 < p1));
01381 
01382     assert(p1.use_count() == 3);
01383     assert(p4.use_count() == 3);
01384 
01385     p1 = p2;
01386 
01387     assert(p1 == p2);
01388     assert(X::instances == 1);
01389     assert(Y::instances == 1);
01390     assert(p4.use_count() == 2);
01391 
01392     p4 = p2;
01393     p5 = p2;
01394 
01395     assert(p4 == p2);
01396     assert(X::instances == 0);
01397     assert(Y::instances == 0);
01398   }
01399 }
01400 
01401 void
01402   auto_ptr_assignment()
01403 {
01404   {
01405     shared_ptr<int> p1;
01406 
01407     std::auto_ptr<int> p2;
01408 
01409     p1 = p2;
01410     assert(p1? false: true);
01411     assert(!p1);
01412     assert(p1.get() == 0);
01413     assert(p1.use_count() == 1);
01414 
01415     int * p = new int;
01416     std::auto_ptr<int> p3(p);
01417 
01418     p1 = p3;
01419     assert(p1.get() == p);
01420     assert(p1.use_count() == 1);
01421 
01422     assert(p3.get() == 0);
01423 
01424     p1 = p2;
01425     assert(p1? false: true);
01426     assert(!p1);
01427     assert(p1.get() == 0);
01428     assert(p1.use_count() == 1);
01429   }
01430 
01431   {
01432     shared_ptr<void> p1;
01433 
01434     std::auto_ptr<int> p2;
01435 
01436     p1 = p2;
01437     assert(p1? false: true);
01438     assert(!p1);
01439     assert(p1.get() == 0);
01440     assert(p1.use_count() == 1);
01441 
01442     int * p = new int;
01443     std::auto_ptr<int> p3(p);
01444 
01445     p1 = p3;
01446     assert(p1.get() == p);
01447     assert(p1.use_count() == 1);
01448 
01449     assert(p3.get() == 0);
01450 
01451     p1 = p2;
01452     assert(p1? false: true);
01453     assert(!p1);
01454     assert(p1.get() == 0);
01455     assert(p1.use_count() == 1);
01456   }
01457 
01458 
01459   {
01460     shared_ptr<X> p1;
01461 
01462     std::auto_ptr<Y> p2;
01463 
01464     p1 = p2;
01465     assert(p1? false: true);
01466     assert(!p1);
01467     assert(p1.get() == 0);
01468     assert(p1.use_count() == 1);
01469     assert(X::instances == 0);
01470     assert(Y::instances == 0);
01471 
01472     Y * p = new Y;
01473     std::auto_ptr<Y> p3(p);
01474 
01475     assert(X::instances == 1);
01476     assert(Y::instances == 1);
01477 
01478     p1 = p3;
01479     assert(p1.get() == p);
01480     assert(p1.use_count() == 1);
01481     assert(X::instances == 1);
01482     assert(Y::instances == 1);
01483 
01484     assert(p3.get() == 0);
01485 
01486     p1 = p2;
01487     assert(p1? false: true);
01488     assert(!p1);
01489     assert(p1.get() == 0);
01490     assert(p1.use_count() == 1);
01491     assert(X::instances == 0);
01492     assert(Y::instances == 0);
01493   }
01494 }
01495 
01496 void
01497   test()
01498 {
01499   copy_assignment();
01500   conversion_assignment();
01501   auto_ptr_assignment();
01502 }
01503 
01504 } // namespace n_assignment
01505 
01506 namespace n_reset
01507 {
01508 
01509 class incomplete;
01510 
01511 incomplete * p0 = 0;
01512 
01513 void
01514   deleter(incomplete *)
01515 {
01516 }
01517 
01518 struct X
01519 {
01520   static long instances;
01521 
01522   X()
01523   {
01524     ++instances;
01525   }
01526 
01527   ~X()
01528   {
01529     --instances;
01530   }
01531 
01532 private:
01533   X(X const &);
01534   X & operator= (X const &);
01535 };
01536 
01537 long X::instances = 0;
01538 
01539 void
01540   plain_reset()
01541 {
01542   {
01543     shared_ptr<int> pi;
01544     pi.reset();
01545     assert(pi? false: true);
01546     assert(!pi);
01547     assert(pi.get() == 0);
01548     assert(pi.use_count() == 0);
01549   }
01550 
01551   {
01552     shared_ptr<int> pi(static_cast<int*>(0));
01553     pi.reset();
01554     assert(pi? false: true);
01555     assert(!pi);
01556     assert(pi.get() == 0);
01557     assert(pi.use_count() == 0);
01558   }
01559 
01560   {
01561     shared_ptr<int> pi(new int);
01562     pi.reset();
01563     assert(pi? false: true);
01564     assert(!pi);
01565     assert(pi.get() == 0);
01566     assert(pi.use_count() == 0);
01567   }
01568 
01569   {
01570     shared_ptr<incomplete> px;
01571     px.reset();
01572     assert(px? false: true);
01573     assert(!px);
01574     assert(px.get() == 0);
01575     assert(px.use_count() == 0);
01576   }
01577 
01578   {
01579     shared_ptr<incomplete> px(p0, deleter);
01580     px.reset();
01581     assert(px? false: true);
01582     assert(!px);
01583     assert(px.get() == 0);
01584     assert(px.use_count() == 0);
01585   }
01586 
01587   {
01588     shared_ptr<X> px;
01589     px.reset();
01590     assert(px? false: true);
01591     assert(!px);
01592     assert(px.get() == 0);
01593     assert(px.use_count() == 0);
01594   }
01595 
01596   {
01597     assert(X::instances == 0);
01598     shared_ptr<X> px(new X);
01599     assert(X::instances == 1);
01600     px.reset();
01601     assert(px? false: true);
01602     assert(!px);
01603     assert(px.get() == 0);
01604     assert(px.use_count() == 0);
01605     assert(X::instances == 0);
01606   }
01607 
01608   {
01609     shared_ptr<void> pv;
01610     pv.reset();
01611     assert(pv? false: true);
01612     assert(!pv);
01613     assert(pv.get() == 0);
01614     assert(pv.use_count() == 0);
01615   }
01616 
01617   {
01618     assert(X::instances == 0);
01619     shared_ptr<void> pv(new X);
01620     assert(X::instances == 1);
01621     pv.reset();
01622     assert(pv? false: true);
01623     assert(!pv);
01624     assert(pv.get() == 0);
01625     assert(pv.use_count() == 0);
01626     assert(X::instances == 0);
01627   }
01628 }
01629 
01630 struct A
01631 {
01632   int dummy;
01633 };
01634 
01635 struct Y
01636   : public A
01637   , public virtual X
01638 {
01639   static long instances;
01640 
01641   Y()
01642   {
01643     ++instances;
01644   }
01645 
01646   ~Y()
01647   {
01648     --instances;
01649   }
01650 
01651 private:
01652   Y(Y const &);
01653   Y & operator= (Y const &);
01654 };
01655 
01656 long Y::instances = 0;
01657 
01658 void
01659   pointer_reset()
01660 {
01661   {
01662     shared_ptr<int> pi;
01663 
01664     pi.reset(static_cast<int*>(0));
01665     assert(pi? false: true);
01666     assert(!pi);
01667     assert(pi.get() == 0);
01668     assert(pi.use_count() == 1);
01669     assert(pi.unique());
01670 
01671     int * p = new int;
01672     pi.reset(p);
01673     assert(pi? true: false);
01674     assert(!!pi);
01675     assert(pi.get() == p);
01676     assert(pi.use_count() == 1);
01677     assert(pi.unique());
01678 
01679     pi.reset(static_cast<int*>(0));
01680     assert(pi? false: true);
01681     assert(!pi);
01682     assert(pi.get() == 0);
01683     assert(pi.use_count() == 1);
01684     assert(pi.unique());
01685   }
01686 
01687   {
01688     shared_ptr<X> px;
01689 
01690     px.reset(static_cast<X*>(0));
01691     assert(px? false: true);
01692     assert(!px);
01693     assert(px.get() == 0);
01694     assert(px.use_count() == 1);
01695     assert(px.unique());
01696     assert(X::instances == 0);
01697 
01698     X * p = new X;
01699     px.reset(p);
01700     assert(px? true: false);
01701     assert(!!px);
01702     assert(px.get() == p);
01703     assert(px.use_count() == 1);
01704     assert(px.unique());
01705     assert(X::instances == 1);
01706 
01707     px.reset(static_cast<X*>(0));
01708     assert(px? false: true);
01709     assert(!px);
01710     assert(px.get() == 0);
01711     assert(px.use_count() == 1);
01712     assert(px.unique());
01713     assert(X::instances == 0);
01714     assert(Y::instances == 0);
01715 
01716     Y * q = new Y;
01717     px.reset(q);
01718     assert(px? true: false);
01719     assert(!!px);
01720     assert(px.get() == q);
01721     assert(px.use_count() == 1);
01722     assert(px.unique());
01723     assert(X::instances == 1);
01724     assert(Y::instances == 1);
01725 
01726     px.reset(static_cast<Y*>(0));
01727     assert(px? false: true);
01728     assert(!px);
01729     assert(px.get() == 0);
01730     assert(px.use_count() == 1);
01731     assert(px.unique());
01732     assert(X::instances == 0);
01733     assert(Y::instances == 0);
01734   }
01735 
01736   {
01737     shared_ptr<void> pv;
01738 
01739     pv.reset(static_cast<X*>(0));
01740     assert(pv? false: true);
01741     assert(!pv);
01742     assert(pv.get() == 0);
01743     assert(pv.use_count() == 1);
01744     assert(pv.unique());
01745     assert(X::instances == 0);
01746 
01747     X * p = new X;
01748     pv.reset(p);
01749     assert(pv? true: false);
01750     assert(!!pv);
01751     assert(pv.get() == p);
01752     assert(pv.use_count() == 1);
01753     assert(pv.unique());
01754     assert(X::instances == 1);
01755 
01756     pv.reset(static_cast<X*>(0));
01757     assert(pv? false: true);
01758     assert(!pv);
01759     assert(pv.get() == 0);
01760     assert(pv.use_count() == 1);
01761     assert(pv.unique());
01762     assert(X::instances == 0);
01763     assert(Y::instances == 0);
01764 
01765     Y * q = new Y;
01766     pv.reset(q);
01767     assert(pv? true: false);
01768     assert(!!pv);
01769     assert(pv.get() == q);
01770     assert(pv.use_count() == 1);
01771     assert(pv.unique());
01772     assert(X::instances == 1);
01773     assert(Y::instances == 1);
01774 
01775     pv.reset(static_cast<Y*>(0));
01776     assert(pv? false: true);
01777     assert(!pv);
01778     assert(pv.get() == 0);
01779     assert(pv.use_count() == 1);
01780     assert(pv.unique());
01781     assert(X::instances == 0);
01782     assert(Y::instances == 0);
01783   }
01784 }
01785 
01786 void
01787   * deleted = 0;
01788 
01789 void
01790   deleter2(void * p)
01791 {
01792   deleted = p;
01793 }
01794 
01795 void
01796   deleter_reset()
01797 {
01798   {
01799     shared_ptr<int> pi;
01800 
01801     pi.reset(static_cast<int*>(0), deleter2);
01802     assert(pi? false: true);
01803     assert(!pi);
01804     assert(pi.get() == 0);
01805     assert(pi.use_count() == 1);
01806     assert(pi.unique());
01807 
01808     deleted = &pi;
01809 
01810     int m = 0;
01811     pi.reset(&m, deleter2);
01812     assert(deleted == 0);
01813     assert(pi? true: false);
01814     assert(!!pi);
01815     assert(pi.get() == &m);
01816     assert(pi.use_count() == 1);
01817     assert(pi.unique());
01818 
01819     pi.reset(static_cast<int*>(0), deleter2);
01820     assert(deleted == &m);
01821     assert(pi? false: true);
01822     assert(!pi);
01823     assert(pi.get() == 0);
01824     assert(pi.use_count() == 1);
01825     assert(pi.unique());
01826 
01827     pi.reset();
01828     assert(deleted == 0);
01829   }
01830 
01831   {
01832     shared_ptr<X> px;
01833 
01834     px.reset(static_cast<X*>(0), deleter2);
01835     assert(px? false: true);
01836     assert(!px);
01837     assert(px.get() == 0);
01838     assert(px.use_count() == 1);
01839     assert(px.unique());
01840 
01841     deleted = &px;
01842 
01843     X x;
01844     px.reset(&x, deleter2);
01845     assert(deleted == 0);
01846     assert(px? true: false);
01847     assert(!!px);
01848     assert(px.get() == &x);
01849     assert(px.use_count() == 1);
01850     assert(px.unique());
01851 
01852     px.reset(static_cast<X*>(0), deleter2);
01853     assert(deleted == &x);
01854     assert(px? false: true);
01855     assert(!px);
01856     assert(px.get() == 0);
01857     assert(px.use_count() == 1);
01858     assert(px.unique());
01859 
01860     Y y;
01861     px.reset(&y, deleter2);
01862     assert(deleted == 0);
01863     assert(px? true: false);
01864     assert(!!px);
01865     assert(px.get() == &y);
01866     assert(px.use_count() == 1);
01867     assert(px.unique());
01868 
01869     px.reset(static_cast<Y*>(0), deleter2);
01870     assert(deleted == &y);
01871     assert(px? false: true);
01872     assert(!px);
01873     assert(px.get() == 0);
01874     assert(px.use_count() == 1);
01875     assert(px.unique());
01876 
01877     px.reset();
01878     assert(deleted == 0);
01879   }
01880 
01881   {
01882     shared_ptr<void> pv;
01883 
01884     pv.reset(static_cast<X*>(0), deleter2);
01885     assert(pv? false: true);
01886     assert(!pv);
01887     assert(pv.get() == 0);
01888     assert(pv.use_count() == 1);
01889     assert(pv.unique());
01890 
01891     deleted = &pv;
01892 
01893     X x;
01894     pv.reset(&x, deleter2);
01895     assert(deleted == 0);
01896     assert(pv? true: false);
01897     assert(!!pv);
01898     assert(pv.get() == &x);
01899     assert(pv.use_count() == 1);
01900     assert(pv.unique());
01901 
01902     pv.reset(static_cast<X*>(0), deleter2);
01903     assert(deleted == &x);
01904     assert(pv? false: true);
01905     assert(!pv);
01906     assert(pv.get() == 0);
01907     assert(pv.use_count() == 1);
01908     assert(pv.unique());
01909 
01910     Y y;
01911     pv.reset(&y, deleter2);
01912     assert(deleted == 0);
01913     assert(pv? true: false);
01914     assert(!!pv);
01915     assert(pv.get() == &y);
01916     assert(pv.use_count() == 1);
01917     assert(pv.unique());
01918 
01919     pv.reset(static_cast<Y*>(0), deleter2);
01920     assert(deleted == &y);
01921     assert(pv? false: true);
01922     assert(!pv);
01923     assert(pv.get() == 0);
01924     assert(pv.use_count() == 1);
01925     assert(pv.unique());
01926 
01927     pv.reset();
01928     assert(deleted == 0);
01929   }
01930 
01931   {
01932     shared_ptr<incomplete> px;
01933 
01934     px.reset(p0, deleter2);
01935     assert(px? false: true);
01936     assert(!px);
01937     assert(px.get() == 0);
01938     assert(px.use_count() == 1);
01939     assert(px.unique());
01940 
01941     deleted = &px;
01942     px.reset(p0, deleter2);
01943     assert(deleted == 0);
01944   }
01945 }
01946 
01947 void
01948   test()
01949 {
01950   plain_reset();
01951   pointer_reset();
01952   deleter_reset();
01953 }
01954 
01955 } // namespace n_reset
01956 
01957 namespace n_access
01958 {
01959 
01960 struct X
01961 {
01962 };
01963 
01964 void
01965   test()
01966 {
01967   {
01968     shared_ptr<X> px;
01969     assert(px.get() == 0);
01970     assert(px? false: true);
01971     assert(!px);
01972 
01973     assert(get_pointer(px) == px.get());
01974   }
01975 
01976   {
01977     shared_ptr<X> px(static_cast<X*>(0));
01978     assert(px.get() == 0);
01979     assert(px? false: true);
01980     assert(!px);
01981 
01982     assert(get_pointer(px) == px.get());
01983   }
01984 
01985   #if 0
01986   {
01987     shared_ptr<X> px(static_cast<X*>(0), checked_deleter<X>());
01988     assert(px.get() == 0);
01989     assert(px? false: true);
01990     assert(!px);
01991 
01992     assert(get_pointer(px) == px.get());
01993   }
01994   #endif  // 0
01995 
01996   {
01997     X * p = new X;
01998     shared_ptr<X> px(p);
01999     assert(px.get() == p);
02000     assert(px? true: false);
02001     assert(!!px);
02002     assert(&*px == px.get());
02003     assert(px.operator ->() == px.get());
02004 
02005     assert(get_pointer(px) == px.get());
02006   }
02007 
02008   #if 0
02009   {
02010     X * p = new X;
02011     shared_ptr<X> px(p, checked_deleter<X>());
02012     assert(px.get() == p);
02013     assert(px? true: false);
02014     assert(!!px);
02015     assert(&*px == px.get());
02016     assert(px.operator ->() == px.get());
02017 
02018     assert(get_pointer(px) == px.get());
02019   }
02020   #endif  // 0
02021 }
02022 
02023 } // namespace n_access
02024 
02025 namespace n_use_count
02026 {
02027 
02028 struct X
02029 {
02030 };
02031 
02032 void
02033   test()
02034 {
02035   {
02036     shared_ptr<X> px(static_cast<X*>(0));
02037     assert(px.use_count() == 1);
02038     assert(px.unique());
02039 
02040     shared_ptr<X> px2(px);
02041     assert(px2.use_count() == 2);
02042     assert(!px2.unique());
02043     assert(px.use_count() == 2);
02044     assert(!px.unique());
02045   }
02046 
02047   {
02048     shared_ptr<X> px(new X);
02049     assert(px.use_count() == 1);
02050     assert(px.unique());
02051 
02052     shared_ptr<X> px2(px);
02053     assert(px2.use_count() == 2);
02054     assert(!px2.unique());
02055     assert(px.use_count() == 2);
02056     assert(!px.unique());
02057   }
02058 
02059   #if 0
02060   {
02061     shared_ptr<X> px(new X, checked_deleter<X>());
02062     assert(px.use_count() == 1);
02063     assert(px.unique());
02064 
02065     shared_ptr<X> px2(px);
02066     assert(px2.use_count() == 2);
02067     assert(!px2.unique());
02068     assert(px.use_count() == 2);
02069     assert(!px.unique());
02070   }
02071   #endif  // 0
02072 }
02073 
02074 } // namespace n_use_count
02075 
02076 namespace n_swap
02077 {
02078 
02079 struct X
02080 {
02081 };
02082 
02083 void
02084   test()
02085 {
02086   {
02087     shared_ptr<X> px;
02088     shared_ptr<X> px2;
02089 
02090     px.swap(px2);
02091 
02092     assert(px.get() == 0);
02093     assert(px2.get() == 0);
02094 
02095     using std::swap;
02096     swap(px, px2);
02097 
02098     assert(px.get() == 0);
02099     assert(px2.get() == 0);
02100   }
02101 
02102   {
02103     X * p = new X;
02104     shared_ptr<X> px;
02105     shared_ptr<X> px2(p);
02106     shared_ptr<X> px3(px2);
02107 
02108     px.swap(px2);
02109 
02110     assert(px.get() == p);
02111     assert(px.use_count() == 2);
02112     assert(px2.get() == 0);
02113     assert(px3.get() == p);
02114     assert(px3.use_count() == 2);
02115 
02116     using std::swap;
02117     swap(px, px2);
02118 
02119     assert(px.get() == 0);
02120     assert(px2.get() == p);
02121     assert(px2.use_count() == 2);
02122     assert(px3.get() == p);
02123     assert(px3.use_count() == 2);
02124   }
02125 
02126   {
02127     X * p1 = new X;
02128     X * p2 = new X;
02129     shared_ptr<X> px(p1);
02130     shared_ptr<X> px2(p2);
02131     shared_ptr<X> px3(px2);
02132 
02133     px.swap(px2);
02134 
02135     assert(px.get() == p2);
02136     assert(px.use_count() == 2);
02137     assert(px2.get() == p1);
02138     assert(px2.use_count() == 1);
02139     assert(px3.get() == p2);
02140     assert(px3.use_count() == 2);
02141 
02142     using std::swap;
02143     swap(px, px2);
02144 
02145     assert(px.get() == p1);
02146     assert(px.use_count() == 1);
02147     assert(px2.get() == p2);
02148     assert(px2.use_count() == 2);
02149     assert(px3.get() == p2);
02150     assert(px3.use_count() == 2);
02151   }
02152 }
02153 
02154 } // namespace n_swap
02155 
02156 namespace n_comparison
02157 {
02158 
02159 struct X
02160 {
02161   int dummy;
02162 };
02163 
02164 struct Y
02165 {
02166   int dummy2;
02167 };
02168 
02169 struct Z
02170   : public X
02171   , public virtual Y
02172 {
02173 };
02174 
02175 void
02176   test()
02177 {
02178   {
02179     shared_ptr<X> px;
02180     assert(px == px);
02181     assert(!(px != px));
02182     assert(!(px < px));
02183 
02184     shared_ptr<X> px2;
02185 
02186     assert(px.get() == px2.get());
02187     assert(px == px2);
02188     assert(!(px != px2));
02189     assert(!(px < px2 && px2 < px));
02190   }
02191 
02192   {
02193     shared_ptr<X> px;
02194     shared_ptr<X> px2(px);
02195 
02196     assert(px2 == px2);
02197     assert(!(px2 != px2));
02198     assert(!(px2 < px2));
02199 
02200     assert(px.get() == px2.get());
02201     assert(px == px2);
02202     assert(!(px != px2));
02203     assert(!(px < px2 && px2 < px));
02204   }
02205 
02206   {
02207     shared_ptr<X> px;
02208     shared_ptr<X> px2(new X);
02209 
02210     assert(px2 == px2);
02211     assert(!(px2 != px2));
02212     assert(!(px2 < px2));
02213 
02214     assert(px.get() != px2.get());
02215     assert(px != px2);
02216     assert(!(px == px2));
02217     assert(px < px2 || px2 < px);
02218     assert(!(px < px2 && px2 < px));
02219   }
02220 
02221   {
02222     shared_ptr<X> px(new X);
02223     shared_ptr<X> px2(new X);
02224 
02225     assert(px.get() != px2.get());
02226     assert(px != px2);
02227     assert(!(px == px2));
02228     assert(px < px2 || px2 < px);
02229     assert(!(px < px2 && px2 < px));
02230   }
02231 
02232   {
02233     shared_ptr<X> px(new X);
02234     shared_ptr<X> px2(px);
02235 
02236     assert(px2 == px2);
02237     assert(!(px2 != px2));
02238     assert(!(px2 < px2));
02239 
02240     assert(px.get() == px2.get());
02241     assert(px == px2);
02242     assert(!(px != px2));
02243     assert(!(px < px2 || px2 < px));
02244   }
02245 
02246   {
02247     shared_ptr<X> px(new X);
02248     shared_ptr<Y> py(new Y);
02249     shared_ptr<Z> pz(new Z);
02250 
02251     assert(px.get() != pz.get());
02252     assert(px != pz);
02253     assert(!(px == pz));
02254 
02255     assert(py.get() != pz.get());
02256     assert(py != pz);
02257     assert(!(py == pz));
02258 
02259     assert(px < py || py < px);
02260     assert(px < pz || pz < px);
02261     assert(py < pz || pz < py);
02262 
02263     assert(!(px < py && py < px));
02264     assert(!(px < pz && pz < px));
02265     assert(!(py < pz && pz < py));
02266 
02267     shared_ptr<void> pvx(px);
02268 
02269     assert(pvx == pvx);
02270     assert(!(pvx != pvx));
02271     assert(!(pvx < pvx));
02272 
02273     shared_ptr<void> pvy(py);
02274     shared_ptr<void> pvz(pz);
02275 
02276     assert(pvx < pvy || pvy < pvx);
02277     assert(pvx < pvz || pvz < pvx);
02278     assert(pvy < pvz || pvz < pvy);
02279 
02280     assert(!(pvx < pvy && pvy < pvx));
02281     assert(!(pvx < pvz && pvz < pvx));
02282     assert(!(pvy < pvz && pvz < pvy));
02283   }
02284 
02285   {
02286     shared_ptr<Z> pz(new Z);
02287     shared_ptr<X> px(pz);
02288 
02289     assert(px == px);
02290     assert(!(px != px));
02291     assert(!(px < px));
02292 
02293     shared_ptr<Y> py(pz);
02294 
02295     assert(px.get() == pz.get());
02296     assert(px == pz);
02297     assert(!(px != pz));
02298 
02299     assert(py.get() == pz.get());
02300     assert(py == pz);
02301     assert(!(py != pz));
02302 
02303     assert(!(px < py || py < px));
02304     assert(!(px < pz || pz < px));
02305     assert(!(py < pz || pz < py));
02306 
02307     shared_ptr<void> pvx(px);
02308     shared_ptr<void> pvy(py);
02309     shared_ptr<void> pvz(pz);
02310 
02311     // pvx and pvy aren't equal...
02312     assert(pvx.get() != pvy.get());
02313     assert(pvx != pvy);
02314     assert(!(pvx == pvy));
02315 
02316     // ... but they share ownership ...
02317     assert(!(pvx < pvy || pvy < pvx));
02318 
02319     // ... with pvz
02320     assert(!(pvx < pvz || pvz < pvx));
02321     assert(!(pvy < pvz || pvz < pvy));
02322   }
02323 }
02324 
02325 } // namespace n_comparison
02326 
02327 namespace n_static_cast
02328 {
02329 
02330 struct X
02331 {
02332 };
02333 
02334 struct Y
02335   : public X
02336 { };
02337 
02338 void
02339   test()
02340 {
02341   {
02342     shared_ptr<void> pv;
02343 
02344     shared_ptr<int> pi = static_pointer_cast<int>(pv);
02345     assert(pi.get() == 0);
02346 
02347     shared_ptr<X> px = static_pointer_cast<X>(pv);
02348     assert(px.get() == 0);
02349   }
02350 
02351   {
02352     shared_ptr<int> pi(new int);
02353     shared_ptr<void> pv(pi);
02354 
02355     shared_ptr<int> pi2 = static_pointer_cast<int>(pv);
02356     assert(pi.get() == pi2.get());
02357     assert(!(pi < pi2 || pi2 < pi));
02358     assert(pi.use_count() == 3);
02359     assert(pv.use_count() == 3);
02360     assert(pi2.use_count() == 3);
02361   }
02362 
02363   {
02364     shared_ptr<X> px(new X);
02365     shared_ptr<void> pv(px);
02366 
02367     shared_ptr<X> px2 = static_pointer_cast<X>(pv);
02368     assert(px.get() == px2.get());
02369     assert(!(px < px2 || px2 < px));
02370     assert(px.use_count() == 3);
02371     assert(pv.use_count() == 3);
02372     assert(px2.use_count() == 3);
02373   }
02374 
02375   {
02376     shared_ptr<X> px(new Y);
02377 
02378     shared_ptr<Y> py = static_pointer_cast<Y>(px);
02379     assert(px.get() == py.get());
02380     assert(px.use_count() == 2);
02381     assert(py.use_count() == 2);
02382 
02383     shared_ptr<X> px2(py);
02384     assert(!(px < px2 || px2 < px));
02385   }
02386 }
02387 
02388 } // namespace n_static_cast
02389 
02390 namespace n_const_cast
02391 {
02392 
02393 struct X;
02394 
02395 void
02396   test()
02397 {
02398   {
02399     shared_ptr<void const volatile> px;
02400 
02401     shared_ptr<void> px2 = const_pointer_cast<void>(px);
02402     assert(px2.get() == 0);
02403   }
02404 
02405   {
02406     shared_ptr<int const volatile> px;
02407 
02408     shared_ptr<int> px2 = const_pointer_cast<int>(px);
02409     assert(px2.get() == 0);
02410   }
02411 
02412   {
02413     shared_ptr<X const volatile> px;
02414 
02415     shared_ptr<X> px2 = const_pointer_cast<X>(px);
02416     assert(px2.get() == 0);
02417   }
02418 
02419   {
02420     shared_ptr<void const volatile> px(new int);
02421 
02422     shared_ptr<void> px2 = const_pointer_cast<void>(px);
02423     assert(px.get() == px2.get());
02424     assert(!(px < px2 || px2 < px));
02425     assert(px.use_count() == 2);
02426     assert(px2.use_count() == 2);
02427   }
02428 
02429   {
02430     shared_ptr<int const volatile> px(new int);
02431 
02432     shared_ptr<int> px2 = const_pointer_cast<int>(px);
02433     assert(px.get() == px2.get());
02434     assert(!(px < px2 || px2 < px));
02435     assert(px.use_count() == 2);
02436     assert(px2.use_count() == 2);
02437   }
02438 }
02439 
02440 } // namespace n_const_cast
02441 
02442 namespace n_dynamic_cast
02443 {
02444 
02445 struct V
02446 {
02447   virtual ~V() {}
02448 };
02449 
02450 struct W
02451   : public V
02452 { };
02453 
02454 void
02455   test()
02456 {
02457   {
02458     shared_ptr<V> pv;
02459     shared_ptr<W> pw = dynamic_pointer_cast<W>(pv);
02460     assert(pw.get() == 0);
02461   }
02462 
02463   {
02464     shared_ptr<V> pv(static_cast<V*>(0));
02465 
02466     shared_ptr<W> pw = dynamic_pointer_cast<W>(pv);
02467     assert(pw.get() == 0);
02468 
02469     shared_ptr<V> pv2(pw);
02470     assert(pv < pv2 || pv2 < pv);
02471   }
02472 
02473   {
02474     shared_ptr<V> pv(static_cast<W*>(0));
02475 
02476     shared_ptr<W> pw = dynamic_pointer_cast<W>(pv);
02477     assert(pw.get() == 0);
02478 
02479     shared_ptr<V> pv2(pw);
02480     assert(pv < pv2 || pv2 < pv);
02481   }
02482 
02483   {
02484     shared_ptr<V> pv(new V);
02485 
02486     shared_ptr<W> pw = dynamic_pointer_cast<W>(pv);
02487     assert(pw.get() == 0);
02488 
02489     shared_ptr<V> pv2(pw);
02490     assert(pv < pv2 || pv2 < pv);
02491   }
02492 
02493   {
02494     shared_ptr<V> pv(new W);
02495 
02496     shared_ptr<W> pw = dynamic_pointer_cast<W>(pv);
02497     assert(pw.get() == pv.get());
02498     assert(pv.use_count() == 2);
02499     assert(pw.use_count() == 2);
02500 
02501     shared_ptr<V> pv2(pw);
02502     assert(!(pv < pv2 || pv2 < pv));
02503   }
02504 }
02505 
02506 } // namespace n_dynamic_cast
02507 
02508 namespace n_map
02509 {
02510 
02511 struct X
02512 {
02513 };
02514 
02515 void
02516   test()
02517 {
02518   std::vector< shared_ptr<int> > vi;
02519 
02520   {
02521     shared_ptr<int> pi1(new int);
02522     shared_ptr<int> pi2(new int);
02523     shared_ptr<int> pi3(new int);
02524 
02525     vi.push_back(pi1);
02526     vi.push_back(pi1);
02527     vi.push_back(pi1);
02528     vi.push_back(pi2);
02529     vi.push_back(pi1);
02530     vi.push_back(pi2);
02531     vi.push_back(pi1);
02532     vi.push_back(pi3);
02533     vi.push_back(pi3);
02534     vi.push_back(pi2);
02535     vi.push_back(pi1);
02536   }
02537 
02538   std::vector< shared_ptr<X> > vx;
02539 
02540   {
02541     shared_ptr<X> px1(new X);
02542     shared_ptr<X> px2(new X);
02543     shared_ptr<X> px3(new X);
02544 
02545     vx.push_back(px2);
02546     vx.push_back(px2);
02547     vx.push_back(px1);
02548     vx.push_back(px2);
02549     vx.push_back(px1);
02550     vx.push_back(px1);
02551     vx.push_back(px1);
02552     vx.push_back(px2);
02553     vx.push_back(px1);
02554     vx.push_back(px3);
02555     vx.push_back(px2);
02556   }
02557 
02558   std::map< shared_ptr<void>, long > m;
02559 
02560   {
02561     for(std::vector< shared_ptr<int> >::iterator i = vi.begin(); i != vi.end(); ++i)
02562     {
02563       ++m[*i];
02564     }
02565   }
02566 
02567   {
02568     for(std::vector< shared_ptr<X> >::iterator i = vx.begin(); i != vx.end(); ++i)
02569     {
02570       ++m[*i];
02571     }
02572   }
02573 
02574   {
02575     for(std::map< shared_ptr<void>, long >::iterator i = m.begin(); i != m.end(); ++i)
02576     {
02577       assert(i->first.use_count() == i->second + 1);
02578     }
02579   }
02580 }
02581 
02582 } // namespace n_map
02583 
02584 namespace n_transitive
02585 {
02586 
02587 struct X
02588 {
02589   X(): next() {}
02590   shared_ptr<X> next;
02591 };
02592 
02593 void
02594   test()
02595 {
02596   shared_ptr<X> p(new X);
02597   p->next = shared_ptr<X>(new X);
02598   assert(!p->next->next);
02599   p = p->next;
02600   assert(!p->next);
02601 }
02602 
02603 } // namespace n_transitive
02604 
02605 #if 0
02606 namespace n_report_1
02607 {
02608 
02609 class foo
02610 {
02611 public:
02612 
02613   foo(): m_self(this)
02614   { }
02615 
02616   void suicide()
02617   { m_self.reset(); }
02618 
02619 private:
02620   shared_ptr<foo> m_self;
02621 };
02622 
02623 void
02624   test()
02625 {
02626   foo * foo_ptr = new foo;
02627   foo_ptr->suicide();
02628 }
02629 
02630 } // namespace n_report_1
02631 #endif  // 0
02632 
02633 // Test case by Per Kristensen
02634 namespace n_report_2
02635 {
02636 
02637 class foo
02638 {
02639 public:
02640 
02641   void setWeak(shared_ptr<foo> s)
02642   {
02643     w = s;
02644   }
02645 
02646 private:
02647 
02648   weak_ptr<foo> w;
02649 };
02650 
02651 class deleter
02652 {
02653 public:
02654 
02655   deleter(): lock(0)
02656   {
02657   }
02658 
02659   ~deleter()
02660   {
02661     assert(lock == 0);
02662   }
02663 
02664   void operator() (foo * p)
02665   {
02666     ++lock;
02667     delete p;
02668     --lock;
02669   }
02670 
02671 private:
02672 
02673   int lock;
02674 };
02675 
02676 void
02677   test()
02678 {
02679   shared_ptr<foo> s(new foo, deleter());
02680   s->setWeak(s);
02681   s.reset();
02682 }
02683 
02684 } // namespace n_report_2
02685 
02686 namespace n_spt_incomplete
02687 {
02688 
02689 class file;
02690 
02691 shared_ptr<file> fopen(char const * name, char const * mode);
02692 void
02693   fread(shared_ptr<file> f, void * data, long size);
02694 
02695 int file_instances = 0;
02696 
02697 void
02698   test()
02699 {
02700   assert(file_instances == 0);
02701 
02702   {
02703     shared_ptr<file> pf = fopen("name", "mode");
02704     assert(file_instances == 1);
02705     fread(pf, 0, 17041);
02706   }
02707 
02708   assert(file_instances == 0);
02709 }
02710 
02711 } // namespace n_spt_incomplete
02712 
02713 namespace n_spt_pimpl
02714 {
02715 
02716 class file
02717 {
02718 private:
02719   class impl;
02720   shared_ptr<impl> pimpl_;
02721 
02722 public:
02723 
02724   file(char const * name, char const * mode);
02725 
02726   // compiler generated members are fine and useful
02727 
02728   void read(void * data, long size);
02729 
02730   long total_size() const;
02731 };
02732 
02733 int file_instances = 0;
02734 
02735 void
02736   test()
02737 {
02738   assert(file_instances == 0);
02739 
02740   {
02741     file f("name", "mode");
02742     assert(file_instances == 1);
02743     f.read(0, 152);
02744 
02745     file f2(f);
02746     assert(file_instances == 1);
02747     f2.read(0, 894);
02748 
02749     assert(f.total_size() == 152+894);
02750 
02751     {
02752       file f3("name2", "mode2");
02753       assert(file_instances == 2);
02754     }
02755 
02756     assert(file_instances == 1);
02757   }
02758 
02759   assert(file_instances == 0);
02760 }
02761 
02762 } // namespace n_spt_pimpl
02763 
02764 namespace n_spt_abstract
02765 {
02766 
02767 class X
02768 {
02769 public:
02770 
02771   virtual void f(int) = 0;
02772   virtual int g() = 0;
02773 
02774 protected:
02775 
02776   virtual ~X() {}
02777 };
02778 
02779 shared_ptr<X> createX();
02780 
02781 int X_instances = 0;
02782 
02783 void
02784   test()
02785 {
02786   assert(X_instances == 0);
02787 
02788   {
02789     shared_ptr<X> px = createX();
02790 
02791     assert(X_instances == 1);
02792 
02793     px->f(18);
02794     px->f(152);
02795 
02796     assert(px->g() == 170);
02797   }
02798 
02799   assert(X_instances == 0);
02800 }
02801 
02802 } // namespace n_spt_abstract
02803 
02804 namespace n_spt_preventing_delete
02805 {
02806 
02807 int X_instances = 0;
02808 
02809 class X
02810 {
02811 private:
02812   X()
02813   {
02814     ++X_instances;
02815   }
02816 
02817   ~X()
02818   {
02819     --X_instances;
02820   }
02821 
02822   class deleter;
02823   friend class deleter;
02824 
02825   class deleter
02826   {
02827   public:
02828 
02829     void operator()(X * p) { delete p; }
02830   };
02831 
02832 public:
02833 
02834   static shared_ptr<X> create()
02835   {
02836     shared_ptr<X> px(new X, X::deleter());
02837     return px;
02838   }
02839 };
02840 
02841 void
02842   test()
02843 {
02844   assert(X_instances == 0);
02845 
02846   {
02847     shared_ptr<X> px = X::create();
02848     assert(X_instances == 1);
02849   }
02850 
02851   assert(X_instances == 0);
02852 }
02853 
02854 } // namespace n_spt_preventing_delete
02855 
02856 namespace n_spt_array
02857 {
02858 
02859 int X_instances = 0;
02860 
02861 struct X
02862 {
02863   X()
02864   {
02865     ++X_instances;
02866   }
02867 
02868   ~X()
02869   {
02870     --X_instances;
02871   }
02872 };
02873 
02874 void
02875   test()
02876 {
02877   assert(X_instances == 0);
02878 
02879   #if 0
02880   {
02881     shared_ptr<X> px(new X[4], checked_array_deleter<X>());
02882     assert(X_instances == 4);
02883   }
02884   #endif  // 0
02885 
02886   assert(X_instances == 0);
02887 }
02888 
02889 } // namespace n_spt_array
02890 
02891 namespace n_spt_static
02892 {
02893 
02894 class X
02895 {
02896 public:
02897 
02898   X()
02899   {
02900   }
02901 
02902 private:
02903   void operator delete(void *)
02904   {
02905     throw "n_spt_static::X::operator delete() called.";
02906   }
02907 };
02908 
02909 struct null_deleter
02910 {
02911   void operator()(void const *) const
02912   {
02913   }
02914 };
02915 
02916 static X x;
02917 
02918 void
02919   test()
02920 {
02921   shared_ptr<X> px(&x, null_deleter());
02922 }
02923 
02924 } // namespace n_spt_static
02925 
02926 namespace n_spt_intrusive
02927 {
02928 
02929 int X_instances = 0;
02930 
02931 struct X
02932 {
02933   long count;
02934 
02935   X(): count(0)
02936   {
02937     ++X_instances;
02938   }
02939 
02940   ~X()
02941   {
02942     --X_instances;
02943   }
02944 };
02945 
02946 void
02947   intrusive_ptr_add_ref(X * p)
02948 {
02949   ++p->count;
02950 }
02951 
02952 void
02953   intrusive_ptr_release(X * p)
02954 {
02955   if(--p->count == 0) delete p;
02956 }
02957 
02958 template< class T >
02959   struct intrusive_deleter
02960 {
02961   void operator()(T * p)
02962   {
02963     if(p != 0) intrusive_ptr_release(p);
02964   }
02965 };
02966 
02967 shared_ptr<X> make_shared_from_intrusive(X * p)
02968 {
02969   if(p != 0) intrusive_ptr_add_ref(p);
02970   shared_ptr<X> px(p, intrusive_deleter<X>());
02971   return px;
02972 }
02973 
02974 void
02975   test()
02976 {
02977   assert(X_instances == 0);
02978 
02979   {
02980     X * p = new X;
02981     assert(X_instances == 1);
02982     assert(p->count == 0);
02983     shared_ptr<X> px = make_shared_from_intrusive(p);
02984     assert(px.get() == p);
02985     assert(p->count == 1);
02986     shared_ptr<X> px2(px);
02987     assert(px2.get() == p);
02988     assert(p->count == 1);
02989   }
02990 
02991   assert(X_instances == 0);
02992 }
02993 
02994 } // namespace n_spt_intrusive
02995 
02996 namespace n_spt_another_sp
02997 {
02998 
02999 template< class T >
03000   class another_ptr
03001     : private shared_ptr<T>
03002 {
03003 private:
03004   typedef shared_ptr<T> base_type;
03005 
03006 public:
03007 
03008   explicit another_ptr(T * p = 0): base_type(p)
03009   {
03010   }
03011 
03012   void reset()
03013   {
03014     base_type::reset();
03015   }
03016 
03017   T * get() const
03018   {
03019     return base_type::get();
03020   }
03021 };
03022 
03023 class event_handler
03024 {
03025 public:
03026 
03027   virtual ~event_handler() {}
03028   virtual void begin() = 0;
03029   virtual void handle(int event) = 0;
03030   virtual void end() = 0;
03031 };
03032 
03033 int begin_called = 0;
03034 int handle_called = 0;
03035 int end_called = 0;
03036 
03037 class event_handler_impl
03038   : public event_handler
03039 {
03040 public:
03041 
03042   virtual void begin()
03043   {
03044     ++begin_called;
03045   }
03046 
03047   virtual void handle(int event)
03048   {
03049     handle_called = event;
03050   }
03051 
03052   virtual void end()
03053   {
03054     ++end_called;
03055   }
03056 };
03057 
03058 another_ptr<event_handler> get_event_handler()
03059 {
03060   another_ptr<event_handler> p(new event_handler_impl);
03061   return p;
03062 }
03063 
03064 shared_ptr<event_handler> current_handler;
03065 
03066 void
03067   install_event_handler(shared_ptr<event_handler> p)
03068 {
03069   p->begin();
03070   current_handler = p;
03071 }
03072 
03073 void
03074   handle_event(int event)
03075 {
03076   current_handler->handle(event);
03077 }
03078 
03079 void
03080   remove_event_handler()
03081 {
03082   current_handler->end();
03083   current_handler.reset();
03084 }
03085 
03086 template< class P >
03087   class smart_pointer_deleter
03088 {
03089 private:
03090   P p_;
03091 
03092 public:
03093 
03094   smart_pointer_deleter(P const & p): p_(p)
03095   {
03096   }
03097 
03098   void operator()(void const *)
03099   {
03100     p_.reset();
03101   }
03102 };
03103 
03104 void
03105   test()
03106 {
03107   another_ptr<event_handler> p = get_event_handler();
03108 
03109   shared_ptr<event_handler> q(p.get(), smart_pointer_deleter< another_ptr<event_handler> >(p));
03110 
03111   p.reset();
03112 
03113   assert(begin_called == 0);
03114 
03115   install_event_handler(q);
03116 
03117   assert(begin_called == 1);
03118 
03119   assert(handle_called == 0);
03120 
03121   handle_event(17041);
03122 
03123   assert(handle_called == 17041);
03124 
03125   assert(end_called == 0);
03126 
03127   remove_event_handler();
03128 
03129   assert(end_called == 1);
03130 }
03131 
03132 } // namespace n_spt_another_sp
03133 
03134 #if 0
03135 namespace n_spt_shared_from_this
03136 {
03137 
03138 class X
03139 {
03140 public:
03141 
03142   virtual void f() = 0;
03143 
03144 protected:
03145 
03146   ~X() {}
03147 };
03148 
03149 class Y
03150 {
03151 public:
03152 
03153   virtual shared_ptr<X> getX() = 0;
03154 
03155 protected:
03156 
03157   ~Y() {}
03158 };
03159 
03160 class impl
03161   : public X, public Y
03162 {
03163 private:
03164   weak_ptr<impl> weak_this;
03165 
03166   impl(impl const &);
03167   impl & operator=(impl const &);
03168 
03169   impl() {}
03170 
03171 public:
03172 
03173   static shared_ptr<impl> create()
03174   {
03175     shared_ptr<impl> pi(new impl);
03176     pi->weak_this = pi;
03177     return pi;
03178   }
03179 
03180   virtual void f() {}
03181 
03182   virtual shared_ptr<X> getX()
03183   {
03184     shared_ptr<X> px = weak_this.lock();
03185     return px;
03186   }
03187 };
03188 
03189 void
03190   test()
03191 {
03192   shared_ptr<Y> py = impl::create();
03193   assert(py.get() != 0);
03194   assert(py.use_count() == 1);
03195 
03196   shared_ptr<X> px = py->getX();
03197   assert(px.get() != 0);
03198   assert(py.use_count() == 2);
03199 
03200   shared_ptr<Y> py2 = dynamic_pointer_cast<Y>(px);
03201   assert(py.get() == py2.get());
03202   assert(!(py < py2 || py2 < py));
03203   assert(py.use_count() == 3);
03204 }
03205 
03206 } // namespace n_spt_shared_from_this
03207 #endif  // 0
03208 
03209 namespace n_spt_wrap
03210 {
03211 
03212 void
03213   test()
03214 {
03215 }
03216 
03217 } // namespace n_spt_wrap
03218 
03219 int main()
03220 {
03221   n_element_type::test();
03222   n_constructors::test();
03223   n_assignment::test();
03224   n_reset::test();
03225   n_access::test();
03226   n_use_count::test();
03227   n_swap::test();
03228   n_comparison::test();
03229   n_static_cast::test();
03230   n_const_cast::test();
03231   n_dynamic_cast::test();
03232 
03233   n_map::test();
03234 
03235   n_transitive::test();
03236   #if 0
03237   n_report_1::test();
03238   #endif  // 0
03239   n_report_2::test();
03240 
03241   n_spt_incomplete::test();
03242   n_spt_pimpl::test();
03243   n_spt_abstract::test();
03244   n_spt_preventing_delete::test();
03245   n_spt_array::test();
03246   n_spt_static::test();
03247   n_spt_intrusive::test();
03248   n_spt_another_sp::test();
03249   //n_spt_shared_from_this::test();
03250   n_spt_wrap::test();
03251 
03252   return 0;
03253 }
03254 
03255 namespace n_spt_incomplete
03256 {
03257 
03258 class file
03259 {
03260 public:
03261 
03262   file(): fread_called(false)
03263   {
03264     ++file_instances;
03265   }
03266 
03267   ~file()
03268   {
03269     assert(fread_called);
03270     --file_instances;
03271   }
03272 
03273   bool fread_called;
03274 };
03275 
03276 shared_ptr<file> fopen(char const *, char const *)
03277 {
03278   shared_ptr<file> pf(new file);
03279   return pf;
03280 }
03281 
03282 void
03283   fread(shared_ptr<file> pf, void *, long)
03284 {
03285   pf->fread_called = true;
03286 }
03287 
03288 } // namespace n_spt_incomplete
03289 
03290 namespace n_spt_pimpl
03291 {
03292 
03293 class file::impl
03294 {
03295 private:
03296   impl(impl const &);
03297   impl & operator=(impl const &);
03298 
03299   long total_size_;
03300 
03301 public:
03302 
03303   impl(char const *, char const *): total_size_(0)
03304   {
03305     ++file_instances;
03306   }
03307 
03308   ~impl()
03309   {
03310     --file_instances;
03311   }
03312 
03313   void read(void *, long size)
03314   {
03315     total_size_ += size;
03316   }
03317 
03318   long total_size() const
03319   {
03320     return total_size_;
03321   }
03322 };
03323 
03324 file::file(char const * name, char const * mode): pimpl_(new impl(name, mode))
03325 {
03326 }
03327 
03328 void
03329   file::read(void * data, long size)
03330 {
03331   pimpl_->read(data, size);
03332 }
03333 
03334 long file::total_size() const
03335 {
03336   return pimpl_->total_size();
03337 }
03338 
03339 } // namespace n_spt_pimpl
03340 
03341 namespace n_spt_abstract
03342 {
03343 
03344 class X_impl
03345   : public X
03346 {
03347 private:
03348   X_impl(X_impl const &);
03349   X_impl & operator=(X_impl const &);
03350 
03351   int n_;
03352 
03353 public:
03354 
03355   X_impl(): n_(0)
03356   {
03357     ++X_instances;
03358   }
03359 
03360   virtual ~X_impl()
03361   {
03362     --X_instances;
03363   }
03364 
03365   virtual void f(int n)
03366   {
03367     n_ += n;
03368   }
03369 
03370   virtual int g()
03371   {
03372     return n_;
03373   }
03374 };
03375 
03376 shared_ptr<X> createX()
03377 {
03378   shared_ptr<X> px(new X_impl);
03379   return px;
03380 }
03381 
03382 } // namespace n_spt_abstract

Generated on 15 Nov 2012 for CLHEP by  doxygen 1.4.7