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

testSharedPtrBasic.cc
Go to the documentation of this file.
1 // ======================================================================
2 //
3 // Test compilability and basic functionality of Utility/memory.h
4 //
5 // Author: W. E. Brown, 2010-03-19, adapted from the boost library's
6 // shared_ptr and related functionality whose internal attributions bear
7 // the following various notices:
8 //
9 // Copyright (c) 2001, 2002 Peter Dimov and Multi Media Ltd.
10 // Distributed under the Boost Software License, Version 1.0.
11 // See http://www.boost.org/LICENSE_1_0.txt
12 //
13 // ======================================================================
14 
15 
16 #include "CLHEP/Utility/noncopyable.h"
17 #include "CLHEP/Utility/memory.h"
18 
19 #include <cassert>
20 
21 
22 using namespace CLHEP;
23 using CLHEP::shared_ptr;
24 
25 
26 int cnt = 0;
27 
28 struct X : public noncopyable {
29  X() { ++cnt; }
30  ~X() { --cnt; } // virtual destructor deliberately omitted
31  virtual int id() const { return 1; }
32 }; // X
33 
34 struct Y: public X
35 {
36  Y() { ++cnt; }
37  ~Y() { --cnt; }
38  virtual int id() const { return 2; }
39 }; // Y
40 
41 int * get_object()
42 { return &++cnt; }
43 
44 void release_object(int * p)
45 {
46  assert(p == &cnt);
47  --cnt;
48 }
49 
50 template< class T >
51  void test_is_X(shared_ptr<T> const & p)
52 {
53  assert(p->id() == 1);
54  assert((*p).id() == 1);
55 }
56 
57 template< class T >
58  void test_is_X(weak_ptr<T> const & p)
59 {
60  assert(p.get() != 0);
61  assert(p.get()->id() == 1);
62 }
63 
64 template< class T >
65  void test_is_Y(shared_ptr<T> const & p)
66 {
67  assert(p->id() == 2);
68  assert((*p).id() == 2);
69 }
70 
71 template< class T >
72  void test_is_Y(weak_ptr<T> const & p)
73 {
74  shared_ptr<T> q = p.lock();
75  assert(q.get() != 0);
76  assert(q->id() == 2);
77 }
78 
79 template< class T >
80  void test_eq(T const & a, T const & b)
81 {
82  assert(a == b);
83  assert(!(a != b));
84  assert(!(a < b));
85  assert(!(b < a));
86 }
87 
88 template< class T >
89  void test_ne(T const & a, T const & b)
90 {
91  assert(!(a == b));
92  assert(a != b);
93  assert(a < b || b < a);
94  assert(!(a < b && b < a));
95 }
96 
97 template< class T, class U >
98  void test_shared(weak_ptr<T> const & a, weak_ptr<U> const & b)
99 {
100  assert(!(a < b));
101  assert(!(b < a));
102 }
103 
104 template< class T, class U >
105  void test_nonshared(weak_ptr<T> const & a, weak_ptr<U> const & b)
106 {
107  assert(a < b || b < a);
108  assert(!(a < b && b < a));
109 }
110 
111 template< class T, class U >
112  void test_eq2(T const & a, U const & b)
113 {
114  assert(a == b);
115  assert(!(a != b));
116 }
117 
118 template< class T, class U >
119  void test_ne2(T const & a, U const & b)
120 {
121  assert(!(a == b));
122  assert(a != b);
123 }
124 
125 template< class T >
126  void test_is_zero(shared_ptr<T> const & p)
127 {
128  assert(!p);
129  assert(p.get() == 0);
130 }
131 
132 template< class T >
134 {
135  // p? true: false is used to test p in a boolean context.
136  // assert(p) is not guaranteed to test the conversion,
137  // as the macro might test !!p instead.
138  assert(p? true: false);
139  assert(p.get() != 0);
140 }
141 
142 int main()
143 {
144 
145  {
146  shared_ptr<X> p(new Y);
147  shared_ptr<X> p2(new X);
148 
149  test_is_nonzero(p);
150  test_is_nonzero(p2);
151  test_is_Y(p);
152  test_is_X(p2);
153  test_ne(p, p2);
154 
155  {
156  shared_ptr<X> q(p);
157  test_eq(p, q);
158  }
159 
162 
163  test_is_nonzero(p3);
164  test_is_zero(p4);
165 
166  assert(p.use_count() == 2);
167  assert(p2.use_count() == 1);
168  assert(p3.use_count() == 2);
169 
170  test_is_Y(p3);
171  test_eq2(p, p3);
172  test_ne2(p2, p4);
173 
174  shared_ptr<void> p5(p);
175 
176  test_is_nonzero(p5);
177  test_eq2(p, p5);
178 
179  weak_ptr<X> wp1(p2);
180 
181  assert(!wp1.expired());
182  assert(wp1.use_count() != 0);
183 
184  p.reset();
185  p2.reset();
186  p3.reset();
187  p4.reset();
188 
189  test_is_zero(p);
190  test_is_zero(p2);
191  test_is_zero(p3);
192  test_is_zero(p4);
193 
194  assert(p5.use_count() == 1);
195 
196  assert(wp1.expired());
197  assert(wp1.use_count() == 0);
198 
199  try
200  {
201  shared_ptr<X> sp1(wp1);
202  throw "shared_ptr<X> sp1(wp1) failed to throw";
203  }
204  catch(bad_weak_ptr const &)
205  {
206  }
207 
208  test_is_zero(wp1.lock());
209 
210  weak_ptr<X> wp2 = static_pointer_cast<X>(p5);
211 
212  assert(wp2.use_count() == 1);
213  test_is_Y(wp2);
214  test_nonshared(wp1, wp2);
215 
216  // Scoped to not affect the subsequent use_count() tests.
217  {
218  shared_ptr<X> sp2(wp2);
219  test_is_nonzero(wp2.lock());
220  }
221 
222  weak_ptr<Y> wp3 = dynamic_pointer_cast<Y>(wp2.lock());
223 
224  assert(wp3.use_count() == 1);
225  test_shared(wp2, wp3);
226 
227  weak_ptr<X> wp4(wp3);
228 
229  assert(wp4.use_count() == 1);
230  test_shared(wp2, wp4);
231 
232  wp1 = p2;
233  test_is_zero(wp1.lock());
234 
235  wp1 = p4;
236  wp1 = wp3;
237  wp1 = wp2;
238 
239  assert(wp1.use_count() == 1);
240  test_shared(wp1, wp2);
241 
242  weak_ptr<X> wp5;
243 
244  bool b1 = wp1 < wp5;
245  bool b2 = wp5 < wp1;
246 
247  p5.reset();
248 
249  assert(wp1.use_count() == 0);
250  assert(wp2.use_count() == 0);
251  assert(wp3.use_count() == 0);
252 
253  // Test operator< stability for std::set< weak_ptr<> >
254  // Thanks to Joe Gottman for pointing this out
255 
256  assert(b1 == (wp1 < wp5));
257  assert(b2 == (wp5 < wp1));
258 
259  {
260  // note that both get_object and release_object deal with int*
262  }
263 
264  }
265 
266  assert(cnt == 0);
267 
268  return 0;
269 
270 } // main()
shared_ptr< P > dynamic_pointer_cast(shared_ptr< P2 > const &)
void test_nonshared(weak_ptr< T > const &a, weak_ptr< U > const &b)
void test_eq(T const &a, T const &b)
void test_ne2(T const &a, U const &b)
void test_is_X(shared_ptr< T > const &p)
void test_ne(T const &a, T const &b)
void test_is_zero(shared_ptr< T > const &p)
void release_object(int *p)
int main()
shared_ptr< P > lock() const
virtual int id() const
virtual int id() const
void test_eq2(T const &a, U const &b)
int * get_object()
void test_is_nonzero(shared_ptr< T > const &p)
int cnt
shared_ptr< P > static_pointer_cast(shared_ptr< P2 > const &)
void test_is_Y(shared_ptr< T > const &p)
void test_shared(weak_ptr< T > const &a, weak_ptr< U > const &b)