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
22using namespace CLHEP;
24
25
26int cnt = 0;
27
28struct X : public noncopyable {
29 X() { ++cnt; }
30 ~X() { --cnt; } // virtual destructor deliberately omitted
31 virtual int id() const { return 1; }
32}; // X
33
34struct Y: public X
35{
36 Y() { ++cnt; }
37 ~Y() { --cnt; }
38 virtual int id() const { return 2; }
39}; // Y
40
42{ return &++cnt; }
43
44void release_object(int * p)
45{
46 assert(p == &cnt);
47 --cnt;
48}
49
50template< 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
57template< 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
64template< 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
71template< 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
79template< 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
88template< 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
97template< 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
104template< 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
111template< 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
118template< 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
125template< class T >
127{
128 assert(!p);
129 assert(p.get() == 0);
130}
131
132template< 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
142int main()
143{
144
145 {
146 shared_ptr<X> p(new Y);
147 shared_ptr<X> p2(new X);
148
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
160 shared_ptr<Y> p3 = dynamic_pointer_cast<Y>(p);
161 shared_ptr<Y> p4 = dynamic_pointer_cast<Y>(p2);
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 > lock() const
virtual int id() const
virtual int id() const
@ b
@ a
int * get_object()
void test_eq(T const &a, T const &b)
void test_is_nonzero(shared_ptr< T > const &p)
void test_shared(weak_ptr< T > const &a, weak_ptr< U > const &b)
void test_is_X(shared_ptr< T > const &p)
void test_eq2(T const &a, U const &b)
void release_object(int *p)
void test_nonshared(weak_ptr< T > const &a, weak_ptr< U > const &b)
int cnt
void test_is_Y(shared_ptr< T > const &p)
void test_ne(T const &a, T const &b)
int main()
void test_ne2(T const &a, U const &b)
void test_is_zero(shared_ptr< T > const &p)