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

testSharedPtrBasic.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) 2001, 2002 Peter Dimov and Multi Media Ltd.
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/noncopyable.h"
00017 #include "CLHEP/Utility/memory.h"
00018 
00019 #include <cassert>
00020 
00021 
00022 using namespace CLHEP;
00023 using CLHEP::shared_ptr;
00024 
00025 
00026 int cnt = 0;
00027 
00028 struct X : public noncopyable {
00029   X() { ++cnt; }
00030   ~X() { --cnt; }  // virtual destructor deliberately omitted
00031   virtual int id() const { return 1; }
00032 };  // X
00033 
00034 struct Y: public X
00035 {
00036   Y() { ++cnt; }
00037   ~Y() { --cnt; }
00038   virtual int id() const { return 2; }
00039 };  // Y
00040 
00041 int * get_object()
00042 { return &++cnt; }
00043 
00044 void release_object(int * p)
00045 {
00046   assert(p == &cnt);
00047   --cnt;
00048 }
00049 
00050 template< class T >
00051  void test_is_X(shared_ptr<T> const & p)
00052 {
00053   assert(p->id() == 1);
00054   assert((*p).id() == 1);
00055 }
00056 
00057 template< class T >
00058  void test_is_X(weak_ptr<T> const & p)
00059 {
00060   assert(p.get() != 0);
00061   assert(p.get()->id() == 1);
00062 }
00063 
00064 template< class T >
00065  void test_is_Y(shared_ptr<T> const & p)
00066 {
00067   assert(p->id() == 2);
00068   assert((*p).id() == 2);
00069 }
00070 
00071 template< class T >
00072  void test_is_Y(weak_ptr<T> const & p)
00073 {
00074   shared_ptr<T> q = p.lock();
00075   assert(q.get() != 0);
00076   assert(q->id() == 2);
00077 }
00078 
00079 template< class T >
00080  void test_eq(T const & a, T const & b)
00081 {
00082   assert(a == b);
00083   assert(!(a != b));
00084   assert(!(a < b));
00085   assert(!(b < a));
00086 }
00087 
00088 template< class T >
00089  void test_ne(T const & a, T const & b)
00090 {
00091   assert(!(a == b));
00092   assert(a != b);
00093   assert(a < b || b < a);
00094   assert(!(a < b && b < a));
00095 }
00096 
00097 template< class T, class U >
00098  void test_shared(weak_ptr<T> const & a, weak_ptr<U> const & b)
00099 {
00100   assert(!(a < b));
00101   assert(!(b < a));
00102 }
00103 
00104 template< class T, class U >
00105  void test_nonshared(weak_ptr<T> const & a, weak_ptr<U> const & b)
00106 {
00107   assert(a < b || b < a);
00108   assert(!(a < b && b < a));
00109 }
00110 
00111 template< class T, class U >
00112  void test_eq2(T const & a, U const & b)
00113 {
00114   assert(a == b);
00115   assert(!(a != b));
00116 }
00117 
00118 template< class T, class U >
00119  void test_ne2(T const & a, U const & b)
00120 {
00121   assert(!(a == b));
00122   assert(a != b);
00123 }
00124 
00125 template< class T >
00126  void test_is_zero(shared_ptr<T> const & p)
00127 {
00128   assert(!p);
00129   assert(p.get() == 0);
00130 }
00131 
00132 template< class T >
00133  void test_is_nonzero(shared_ptr<T> const & p)
00134 {
00135   // p? true: false is used to test p in a boolean context.
00136   // assert(p) is not guaranteed to test the conversion,
00137   // as the macro might test !!p instead.
00138   assert(p? true: false);
00139   assert(p.get() != 0);
00140 }
00141 
00142 int main()
00143 {
00144 
00145   {
00146     shared_ptr<X> p(new Y);
00147     shared_ptr<X> p2(new X);
00148 
00149     test_is_nonzero(p);
00150     test_is_nonzero(p2);
00151     test_is_Y(p);
00152     test_is_X(p2);
00153     test_ne(p, p2);
00154 
00155     {
00156       shared_ptr<X> q(p);
00157       test_eq(p, q);
00158     }
00159 
00160     shared_ptr<Y> p3 = dynamic_pointer_cast<Y>(p);
00161     shared_ptr<Y> p4 = dynamic_pointer_cast<Y>(p2);
00162 
00163     test_is_nonzero(p3);
00164     test_is_zero(p4);
00165 
00166     assert(p.use_count() == 2);
00167     assert(p2.use_count() == 1);
00168     assert(p3.use_count() == 2);
00169 
00170     test_is_Y(p3);
00171     test_eq2(p, p3);
00172     test_ne2(p2, p4);
00173 
00174     shared_ptr<void> p5(p);
00175 
00176     test_is_nonzero(p5);
00177     test_eq2(p, p5);
00178 
00179     weak_ptr<X> wp1(p2);
00180 
00181     assert(!wp1.expired());
00182     assert(wp1.use_count() != 0);
00183 
00184     p.reset();
00185     p2.reset();
00186     p3.reset();
00187     p4.reset();
00188 
00189     test_is_zero(p);
00190     test_is_zero(p2);
00191     test_is_zero(p3);
00192     test_is_zero(p4);
00193 
00194     assert(p5.use_count() == 1);
00195 
00196     assert(wp1.expired());
00197     assert(wp1.use_count() == 0);
00198 
00199     try
00200     {
00201       shared_ptr<X> sp1(wp1);
00202       throw "shared_ptr<X> sp1(wp1) failed to throw";
00203     }
00204     catch(bad_weak_ptr const &)
00205     {
00206     }
00207 
00208     test_is_zero(wp1.lock());
00209 
00210     weak_ptr<X> wp2 = static_pointer_cast<X>(p5);
00211 
00212     assert(wp2.use_count() == 1);
00213     test_is_Y(wp2);
00214     test_nonshared(wp1, wp2);
00215 
00216     // Scoped to not affect the subsequent use_count() tests.
00217     {
00218       shared_ptr<X> sp2(wp2);
00219       test_is_nonzero(wp2.lock());
00220     }
00221 
00222     weak_ptr<Y> wp3 = dynamic_pointer_cast<Y>(wp2.lock());
00223 
00224     assert(wp3.use_count() == 1);
00225     test_shared(wp2, wp3);
00226 
00227     weak_ptr<X> wp4(wp3);
00228 
00229     assert(wp4.use_count() == 1);
00230     test_shared(wp2, wp4);
00231 
00232     wp1 = p2;
00233     test_is_zero(wp1.lock());
00234 
00235     wp1 = p4;
00236     wp1 = wp3;
00237     wp1 = wp2;
00238 
00239     assert(wp1.use_count() == 1);
00240     test_shared(wp1, wp2);
00241 
00242     weak_ptr<X> wp5;
00243 
00244     bool b1 = wp1 < wp5;
00245     bool b2 = wp5 < wp1;
00246 
00247     p5.reset();
00248 
00249     assert(wp1.use_count() == 0);
00250     assert(wp2.use_count() == 0);
00251     assert(wp3.use_count() == 0);
00252 
00253     // Test operator< stability for std::set< weak_ptr<> >
00254     // Thanks to Joe Gottman for pointing this out
00255 
00256     assert(b1 == (wp1 < wp5));
00257     assert(b2 == (wp5 < wp1));
00258 
00259     {
00260       // note that both get_object and release_object deal with int*
00261       shared_ptr<void> p6(get_object(), release_object);
00262     }
00263 
00264   }
00265 
00266   assert(cnt == 0);
00267 
00268   return 0;
00269 
00270 }  // main()

Generated on 15 Nov 2012 for CLHEP by  doxygen 1.4.7