Lumiera 0.pre.04~rc.1
»edit your freedom«
Loading...
Searching...
No Matches
custom-shared-ptr-test.cpp
Go to the documentation of this file.
1/*
2 CustomSharedPtr(Test) - ref counting, equality and comparisons
3
4 Copyright (C)
5 2008, 2010, Hermann Vosseler <Ichthyostega@web.de>
6
7  **Lumiera** is free software; you can redistribute it and/or modify it
8  under the terms of the GNU General Public License as published by the
9  Free Software Foundation; either version 2 of the License, or (at your
10  option) any later version. See the file COPYING for further details.
11
12* *****************************************************************/
13
19#include "lib/test/run.hpp"
21#include "lib/util.hpp"
22
23#include "lib/p.hpp"
24
25
26
27namespace lib {
28namespace test{
29
30 using std::string;
31 using std::shared_ptr;
32 using std::weak_ptr;
33
34 using lumiera::error::LUMIERA_ERROR_ASSERTION;
35
36
37 struct X
38 {
39 long x_;
40
41 explicit X(long x=0) : x_(x) {}
42 operator long () { return x_; }
43
44 std::strong_ordering operator<=>(X const&) const = default;
45
46 virtual ~X() {} // using RTTI
47 };
48
49 struct XX : public X
50 {
51 long xx_;
52
53 XX(long x=0) : X(x), xx_(x+1) {}
54 };
55
56
57 /************************************************************/
63 class CustomSharedPtr_test : public Test
64 {
65 virtual void
74
75
77 void
79 {
80 P<X> p1 (new X(7));
81 CHECK (p1);
82 CHECK (1 == p1.use_count());
83 CHECK (7 == p1->x_);
84
85 {
86 P<X> p2 (new X(9));
87 CHECK (1 == p2.use_count());
88
89 p2.swap (p1);
90 CHECK (1 == p1.use_count());
91 CHECK (1 == p2.use_count());
92
93 p2 = p1;
94 CHECK (2 == p1.use_count());
95 CHECK (2 == p2.use_count());
96 }
97
98 CHECK (1 == p1.use_count());
99 CHECK (9 == p1->x_);
100
101 p1.reset();
102 CHECK (0 == p1.use_count());
103 CHECK (!p1);
104 }
105
106
108 void
110 {
111 P<X> pX (new X(22));
112 CHECK (pX);
113 CHECK (1 == pX.use_count());
114
115 weak_ptr<X> wX (pX);
116 CHECK (wX.lock());
117 CHECK (1 == pX.use_count());
118
119 shared_ptr<X> sp1 (wX);
120 shared_ptr<X> sp2 (pX);
121 shared_ptr<X> sp3; sp3 = pX;
122
123 CHECK (22 == sp3->x_);
124 CHECK (4 == pX.use_count());
125 CHECK (*pX == *sp1);
126 CHECK (*sp1 == *sp2);
127 CHECK (*sp2 == *sp3);
128
129 P<X> pX2;
130 pX2.swap(pX);
131 CHECK (!pX);
132 CHECK (0 == pX.use_count());
133 CHECK (4 == pX2.use_count());
134
135 P<X, P<X>> pXX (pX2); // a different type, but compatible pointers
136 pX2 = pX;
137 CHECK (!pX2);
138 CHECK (0 == pX2.use_count());
139 CHECK (4 == pXX.use_count());
140
141 sp3 = sp2 = sp1 = pX;
142 CHECK (22 == pXX->x_);
143 CHECK (1 == pXX.use_count());
144 CHECK (!sp1);
145 CHECK (!sp2);
146 CHECK (!sp3);
147
148 CHECK (22 == wX.lock()->x_);
149 CHECK (1 == pXX.use_count());
150
151 pXX.reset();
152 CHECK (!pXX);
153 CHECK (!wX.lock());
154 }
155
156
157 void
159 {
160 std::unique_ptr<X> up (new X(23));
161 CHECK (up.get());
162
163 P<X> pX (std::move(up));
164 CHECK (!up.get());
165 CHECK (pX);
166 CHECK (1 == pX.use_count());
167 CHECK (23 == pX->x_);
168 }
169
170
172 void
174 {
175 P<X> pX; // Base: shared_ptr<X>
176 P<XX> pX1; // Base: shared_ptr<XX>
177 P<XX,P<X>> pX2; // Base: P<X>
178 P<XX,shared_ptr<X>> pX3; // Base: shared_ptr<X>
179 P<XX,shared_ptr<long>> pLo;// Base: shared_ptr<long> (rather nonsense, but well...)
180 P<X,string> pLoL; // Base: std::string
181 P<string> pLoLoL; // Base: shared_ptr<string>
182
183 CHECK (INSTANCEOF (shared_ptr<X>, &pX));
184
185 CHECK ( INSTANCEOF (shared_ptr<XX>, &pX1));
186// CHECK (!INSTANCEOF (shared_ptr<X>, &pX1)); // doesn't compile (no RTTI) -- that's correct
187// CHECK (!INSTANCEOF (P<X>, &pX1)); // similar, type mismatch detected by compiler
188
189 CHECK ( INSTANCEOF (shared_ptr<X>, &pX2));
190// CHECK (!INSTANCEOF (shared_ptr<XX>, &pX2));
191 CHECK ( INSTANCEOF (P<X>, &pX2));
192
193 CHECK ( INSTANCEOF (shared_ptr<X>, &pX3));
194// CHECK (!INSTANCEOF (shared_ptr<XX>, &pX3));
195// CHECK (!INSTANCEOF (P<X>, &pX3));
196
197 CHECK ( INSTANCEOF (shared_ptr<long>, &pLo));
198// CHECK (!INSTANCEOF (shared_ptr<X>, &pLo));
199// CHECK (!INSTANCEOF (P<X>, &pLo));
200
201// CHECK (!INSTANCEOF (shared_ptr<long>, &pLoL));
202// CHECK (!INSTANCEOF (shared_ptr<X>, &pLoL));
203// CHECK (!INSTANCEOF (P<X>, &pLoL));
204 CHECK ( INSTANCEOF (string, &pLoL));
205
206 CHECK ( INSTANCEOF (shared_ptr<string>, &pLoLoL));
207// CHECK (!INSTANCEOF (string, &pLoLoL));
208// CHECK (!INSTANCEOF (shared_ptr<X>, &pLoLoL));
209
210 pX = pX1; // OK: pointee subtype...
211 pX = pX2; // invokes shared_ptr<X>::operator= (shared_ptr<X> const&)
212 pX = pX3;
213// pX = pLo; // similar, but long* not assignable to X*
214// pX = pLoL; // similar, but string* not assignable to X*
215// pX = pLoLoL; // same...
216 // you won't be able to do much with the "LoLo"-Types,
217 // as their types and pointee types's relations don't match
218
219 pX.reset (new XX(5));
220 CHECK (5 == *pX); // implicit conversion from X to long
221
222 pX2 = pX; // works, because both are implemented in terms of shared_ptr<X>
223 CHECK (5 == pX2->x_);
224 CHECK (6 == pX2->xx_); // using the XX interface (performing dynamic downcast)
225
226 pX3.reset (new X(7)); // again works because implemented in terms of shared_ptr<X>
227 pX2 = pX3; // same
228 CHECK (pX2); // both contain indeed a valid pointer....
229 CHECK (pX3);
230 CHECK (! pX2.get()); // but dynamic cast to XX at access fails
231 CHECK (! pX3.get());
232 }
233
234
236 void
238 {
239 typedef P<X> PX;
240 typedef P<XX,PX> PXX;
241
242 PX pX1 (new X(3));
243 PX pX2 (new XX(5));
244 PX pX3, pX4, pX5, pX6;
245 PXX pXX (new XX(7));
246
247 pX3 = pXX;
248 pX4.reset(new X(*pXX));
249
250 CHECK ( (pX1 == pX1)); // reflexivity
251 CHECK (!(pX1 != pX1));
252 CHECK (!(pX1 < pX1));
253 CHECK (!(pX1 > pX1));
254 CHECK ( (pX1 <= pX1));
255 CHECK ( (pX1 >= pX1));
256
257 CHECK (!(pX1 == pX2)); // compare to same ptr type with larger pointee of subtype
258 CHECK ( (pX1 != pX2));
259 CHECK ( (pX1 < pX2));
260 CHECK (!(pX1 > pX2));
261 CHECK ( (pX1 <= pX2));
262 CHECK (!(pX1 >= pX2));
263
264 CHECK (!(pX2 == pXX)); // compare to ptr subtype with larger pointee of same subtype
265 CHECK ( (pX2 != pXX));
266 CHECK ( (pX2 < pXX));
267 CHECK (!(pX2 > pXX));
268 CHECK ( (pX2 <= pXX));
269 CHECK (!(pX2 >= pXX));
270
271 CHECK (!(pX1 == pXX)); // transitively compare to ptr subtype with larger pointee of subtype
272 CHECK ( (pX1 != pXX));
273 CHECK ( (pX1 < pXX));
274 CHECK (!(pX1 > pXX));
275 CHECK ( (pX1 <= pXX));
276 CHECK (!(pX1 >= pXX));
277
278 CHECK ( (pX3 == pXX)); // compare ptr to subtype ptr both referring to same pointee
279 CHECK (!(pX3 != pXX));
280 CHECK (!(pX3 < pXX));
281 CHECK (!(pX3 > pXX));
282 CHECK ( (pX3 <= pXX));
283 CHECK ( (pX3 >= pXX));
284
285 CHECK ( (pX4 == pXX)); // compare ptr to subtype ptr both referring to different but equal pointees
286 CHECK (!(pX4 != pXX));
287 CHECK (!(pX4 < pXX));
288 CHECK (!(pX4 > pXX));
289 CHECK ( (pX4 <= pXX));
290 CHECK ( (pX4 >= pXX));
291
292 CHECK (!(pXX == pX5)); // compare subtype ptr to empty ptr: "unequal but not orderable"
293 CHECK ( (pXX != pX5));
294
295 CHECK ( (pX5 == pX6)); // compare two empty ptrs: "equal, equivalent but not orderable"
296 CHECK (!(pX5 != pX6));
297
298 // order relations on NIL pointers disallowed
299
300#if false
301 VERIFY_ERROR (ASSERTION, pXX < pX5 );
302 VERIFY_ERROR (ASSERTION, pXX > pX5 );
303 VERIFY_ERROR (ASSERTION, pXX <= pX5 );
304 VERIFY_ERROR (ASSERTION, pXX >= pX5 );
305
306 VERIFY_ERROR (ASSERTION, pX5 < pXX );
307 VERIFY_ERROR (ASSERTION, pX5 > pXX );
308 VERIFY_ERROR (ASSERTION, pX5 <= pXX );
309 VERIFY_ERROR (ASSERTION, pX5 >= pXX );
310
311 VERIFY_ERROR (ASSERTION, pX5 < pX6 );
312 VERIFY_ERROR (ASSERTION, pX5 > pX6 );
313 VERIFY_ERROR (ASSERTION, pX5 <= pX6 );
314 VERIFY_ERROR (ASSERTION, pX5 >= pX6 );
315#endif
316 }
317 };
318
319
322
323
324
325}} // namespace lib::test
Customised refcounting smart pointer template, built upon std::shared_ptr, but forwarding type relati...
Definition p.hpp:77
TAR * get() const
Definition p.hpp:94
void swap(P &b)
Definition p.hpp:98
Implementation namespace for support and library code.
Test runner and basic definitions for tests.
Customised refcounting smart pointer.
Simplistic test class runner.
#define LAUNCHER(_TEST_CLASS_, _GROUPS_)
Definition run.hpp:116
std::strong_ordering operator<=>(X const &) const =default
A collection of frequently used helper functions to support unit testing.
#define VERIFY_ERROR(ERROR_ID, ERRONEOUS_STATEMENT)
Macro to verify that a statement indeed raises an exception.
Tiny helper functions and shortcuts to be used everywhere Consider this header to be effectively incl...
#define INSTANCEOF(CLASS, EXPR)
shortcut for subclass test, intended for assertions only.
Definition util.hpp:514