blob: 088b7f4dc3c54247586445f9dd4b836fd207a542 [file] [log] [blame]
Brian Silverman1f5d3982018-08-04 23:37:52 -07001//////////////////////////////////////////////////////////////////////////////
2//
3// (C) Copyright Howard Hinnant 2009
4// (C) Copyright Ion Gaztanaga 2014-2014.
5//
6// Distributed under the Boost Software License, Version 1.0.
7// (See accompanying file LICENSE_1_0.txt or copy at
8// http://www.boost.org/LICENSE_1_0.txt)
9//
10// See http://www.boost.org/libs/move for documentation.
11//
12//////////////////////////////////////////////////////////////////////////////
13#include <boost/move/utility_core.hpp>
14#include <boost/move/unique_ptr.hpp>
15#include <boost/static_assert.hpp>
16#include <boost/core/lightweight_test.hpp>
17
18//////////////////////////////////////////////
19//
20// The initial implementation of these tests
21// was written by Howard Hinnant.
22//
23// These test were later refactored grouping
24// and porting them to Boost.Move.
25//
26// Many thanks to Howard for releasing his C++03
27// unique_ptr implementation with such detailed
28// test cases.
29//
30//////////////////////////////////////////////
31
32#include "unique_ptr_test_utils_beg.hpp"
33
34namespace bml = ::boost::movelib;
35
36////////////////////////////////
37// unique_ptr_asgn_move_convert_defdel
38////////////////////////////////
39namespace unique_ptr_asgn_move_convert_defdel {
40
41void test()
42{
43 //Single unique_ptr
44 reset_counters();
45 {
46 bml::unique_ptr<B> s(new B);
47 A* p = s.get();
48 bml::unique_ptr<A> s2(new A);
49 BOOST_TEST(A::count == 2);
50 s2 = boost::move(s);
51 BOOST_TEST(s2.get() == p);
52 BOOST_TEST(s.get() == 0);
53 BOOST_TEST(A::count == 1);
54 BOOST_TEST(B::count == 1);
55 }
56 BOOST_TEST(A::count == 0);
57 BOOST_TEST(B::count == 0);
58
59 //Unbounded array unique_ptr
60 reset_counters();
61 {
62 bml::unique_ptr<A[]> s(new A[2]);
63 A* p = s.get();
64 bml::unique_ptr<const A[]> s2(new const A[2]);
65 BOOST_TEST(A::count == 4);
66 s2 = boost::move(s);
67 BOOST_TEST(s2.get() == p);
68 BOOST_TEST(s.get() == 0);
69 BOOST_TEST(A::count == 2);
70 }
71 BOOST_TEST(A::count == 0);
72 //Bounded array unique_ptr
73 reset_counters();
74 {
75 bml::unique_ptr<A[2]> s(new A[2]);
76 A* p = s.get();
77 bml::unique_ptr<const A[2]> s2(new const A[2]);
78 BOOST_TEST(A::count == 4);
79 s2 = boost::move(s);
80 BOOST_TEST(s2.get() == p);
81 BOOST_TEST(s.get() == 0);
82 BOOST_TEST(A::count == 2);
83 }
84 {
85 BOOST_TEST(A::count == 0);
86 bml::unique_ptr<A[2]> s(new A[2]);
87 A* p = s.get();
88 bml::unique_ptr<const A[]> s2(new const A[2]);
89 BOOST_TEST(A::count == 4);
90 s2 = boost::move(s);
91 BOOST_TEST(s2.get() == p);
92 BOOST_TEST(s.get() == 0);
93 BOOST_TEST(A::count == 2);
94 }
95 BOOST_TEST(A::count == 0);
96}
97
98} //namespace unique_ptr_asgn_move_convert_defdel{
99
100////////////////////////////////
101// unique_ptr_asgn_move_convert_movdel
102////////////////////////////////
103
104namespace unique_ptr_asgn_move_convert_movedel{
105
106void test()
107{
108 //Single unique_ptr
109 reset_counters();
110 {
111 bml::unique_ptr<B, move_constr_deleter<B> > s(new B);
112 A* p = s.get();
113 bml::unique_ptr<A, move_constr_deleter<A> > s2(new A);
114 BOOST_TEST(A::count == 2);
115 s2 = (boost::move(s));
116 BOOST_TEST(s2.get() == p);
117 BOOST_TEST(s.get() == 0);
118 BOOST_TEST(A::count == 1);
119 BOOST_TEST(B::count == 1);
120 BOOST_TEST(s2.get_deleter().state() == 5);
121 BOOST_TEST(s.get_deleter().state() == 0);
122 }
123 BOOST_TEST(A::count == 0);
124 BOOST_TEST(B::count == 0);
125
126 //Unbounded array unique_ptr
127 reset_counters();
128 {
129 bml::unique_ptr<A[], move_constr_deleter<A[]> > s(new A[2]);
130 A* p = s.get();
131 bml::unique_ptr<const A[], move_constr_deleter<const A[]> > s2(new const A[2]);
132 BOOST_TEST(A::count == 4);
133 s2 = (boost::move(s));
134 BOOST_TEST(s2.get() == p);
135 BOOST_TEST(s.get() == 0);
136 BOOST_TEST(A::count == 2);
137 BOOST_TEST(s2.get_deleter().state() == 5);
138 BOOST_TEST(s.get_deleter().state() == 0);
139 }
140 BOOST_TEST(A::count == 0);
141
142 //Bounded array unique_ptr
143 reset_counters();
144 {
145 bml::unique_ptr<A[2], move_constr_deleter<A[2]> > s(new A[3]);
146 A* p = s.get();
147 bml::unique_ptr<const A[2], move_constr_deleter<const A[2]> > s2(new const A[2]);
148 BOOST_TEST(A::count == 5);
149 s2 = (boost::move(s));
150 BOOST_TEST(s2.get() == p);
151 BOOST_TEST(s.get() == 0);
152 BOOST_TEST(A::count == 3);
153 BOOST_TEST(s2.get_deleter().state() == 5);
154 BOOST_TEST(s.get_deleter().state() == 0);
155 }
156 BOOST_TEST(A::count == 0);
157 reset_counters();
158 {
159 bml::unique_ptr<A[2], move_constr_deleter<A[3]> > s(new A[2]);
160 A* p = s.get();
161 bml::unique_ptr<const A[], move_constr_deleter<const A[]> > s2(new const A[2]);
162 BOOST_TEST(A::count == 4);
163 s2 = (boost::move(s));
164 BOOST_TEST(s2.get() == p);
165 BOOST_TEST(s.get() == 0);
166 BOOST_TEST(A::count == 2);
167 BOOST_TEST(s2.get_deleter().state() == 5);
168 BOOST_TEST(s.get_deleter().state() == 0);
169 }
170 BOOST_TEST(A::count == 0);
171}
172
173} //namespace unique_ptr_asgn_move_convert_movedel{
174
175////////////////////////////////
176// unique_ptr_asgn_move_convert_copydelref
177////////////////////////////////
178
179namespace unique_ptr_asgn_move_convert_copydelref{
180
181// test converting move assignment with reference deleters
182
183void test()
184{
185 //Single unique_ptr
186 reset_counters();
187 {
188 copy_constr_deleter<B> db(5);
189 bml::unique_ptr<B, copy_constr_deleter<B>&> s(new B, db);
190 A* p = s.get();
191 copy_constr_deleter<A> da(6);
192 bml::unique_ptr<A, copy_constr_deleter<A>&> s2(new A, da);
193 s2 = boost::move(s);
194 BOOST_TEST(s2.get() == p);
195 BOOST_TEST(s.get() == 0);
196 BOOST_TEST(A::count == 1);
197 BOOST_TEST(B::count == 1);
198 BOOST_TEST(s2.get_deleter().state() == 5);
199 }
200 BOOST_TEST(A::count == 0);
201 BOOST_TEST(B::count == 0);
202
203 //Unbounded array unique_ptr
204 reset_counters();
205 {
206 copy_constr_deleter<A[]> db(5);
207 bml::unique_ptr<A[], copy_constr_deleter<A[]>&> s(new A[2], db);
208 A* p = s.get();
209 copy_constr_deleter<const A[]> da(6);
210 bml::unique_ptr<const A[], copy_constr_deleter<const A[]>&> s2(new const A[2], da);
211 BOOST_TEST(A::count == 4);
212 s2 = boost::move(s);
213 BOOST_TEST(s2.get() == p);
214 BOOST_TEST(s.get() == 0);
215 BOOST_TEST(A::count == 2);
216 BOOST_TEST(s2.get_deleter().state() == 5);
217 }
218 BOOST_TEST(A::count == 0);
219
220 //Bounded array unique_ptr
221 reset_counters();
222 {
223 copy_constr_deleter<A[2]> db(5);
224 bml::unique_ptr<A[2], copy_constr_deleter<A[2]>&> s(new A[2], db);
225 A* p = s.get();
226 copy_constr_deleter<const A[2]> da(6);
227 bml::unique_ptr<const A[2], copy_constr_deleter<const A[2]>&> s2(new const A[2], da);
228 BOOST_TEST(A::count == 4);
229 s2 = boost::move(s);
230 BOOST_TEST(s2.get() == p);
231 BOOST_TEST(s.get() == 0);
232 BOOST_TEST(A::count == 2);
233 BOOST_TEST(s2.get_deleter().state() == 5);
234 }
235 BOOST_TEST(A::count == 0);
236 reset_counters();
237 {
238 copy_constr_deleter<A[2]> db(5);
239 bml::unique_ptr<A[2], copy_constr_deleter<A[2]>&> s(new A[2], db);
240 A* p = s.get();
241 copy_constr_deleter<const A[]> da(6);
242 bml::unique_ptr<const A[], copy_constr_deleter<const A[]>&> s2(new const A[2], da);
243 BOOST_TEST(A::count == 4);
244 s2 = boost::move(s);
245 BOOST_TEST(s2.get() == p);
246 BOOST_TEST(s.get() == 0);
247 BOOST_TEST(A::count == 2);
248 BOOST_TEST(s2.get_deleter().state() == 5);
249 }
250 BOOST_TEST(A::count == 0);
251}
252
253} //namespace unique_ptr_asgn_move_convert_copydelref{
254
255////////////////////////////////
256// unique_ptr_asgn_move_defdel
257////////////////////////////////
258namespace unique_ptr_asgn_move_defdel {
259
260void test()
261{
262 //Single unique_ptr
263 reset_counters();
264 {
265 bml::unique_ptr<A> s1(new A);
266 A* p = s1.get();
267 bml::unique_ptr<A> s2(new A);
268 BOOST_TEST(A::count == 2);
269 s2 = boost::move(s1);
270 BOOST_TEST(A::count == 1);
271 BOOST_TEST(s2.get() == p);
272 BOOST_TEST(s1.get() == 0);
273 }
274 BOOST_TEST(A::count == 0);
275
276 //Unbounded array unique_ptr
277 reset_counters();
278 {
279 bml::unique_ptr<A[]> s1(new A[2]);
280 A* p = s1.get();
281 bml::unique_ptr<A[]> s2(new A[2]);
282 BOOST_TEST(A::count == 4);
283 s2 = boost::move(s1);
284 BOOST_TEST(A::count == 2);
285 BOOST_TEST(s2.get() == p);
286 BOOST_TEST(s1.get() == 0);
287 }
288 BOOST_TEST(A::count == 0);
289 //Bounded array unique_ptr
290 reset_counters();
291 {
292 bml::unique_ptr<A[2]> s1(new A[2]);
293 A* p = s1.get();
294 bml::unique_ptr<A[2]> s2(new A[2]);
295 BOOST_TEST(A::count == 4);
296 s2 = boost::move(s1);
297 BOOST_TEST(A::count == 2);
298 BOOST_TEST(s2.get() == p);
299 BOOST_TEST(s1.get() == 0);
300 }
301 BOOST_TEST(A::count == 0);
302}
303
304} //unique_ptr_asgn_move_defdel
305
306////////////////////////////////
307// unique_ptr_asgn_move_movedel
308////////////////////////////////
309namespace unique_ptr_asgn_move_movedel {
310
311void test()
312{
313 //Single unique_ptr
314 reset_counters();
315 {
316 bml::unique_ptr<A, move_constr_deleter<A> > s1(new A);
317 A* p = s1.get();
318 bml::unique_ptr<A, move_constr_deleter<A> > s2(new A);
319 BOOST_TEST(A::count == 2);
320 s2 = boost::move(s1);
321 BOOST_TEST(s2.get() == p);
322 BOOST_TEST(s1.get() == 0);
323 BOOST_TEST(A::count == 1);
324 BOOST_TEST(s2.get_deleter().state() == 5);
325 BOOST_TEST(s1.get_deleter().state() == 0);
326 }
327 BOOST_TEST(A::count == 0);
328
329 //Unbounded array unique_ptr
330 reset_counters();
331 {
332 bml::unique_ptr<A[], move_constr_deleter<A[]> > s1(new A[2]);
333 A* p = s1.get();
334 bml::unique_ptr<A[], move_constr_deleter<A[]> > s2(new A[2]);
335 BOOST_TEST(A::count == 4);
336 s2 = boost::move(s1);
337 BOOST_TEST(s2.get() == p);
338 BOOST_TEST(s1.get() == 0);
339 BOOST_TEST(A::count == 2);
340 BOOST_TEST(s2.get_deleter().state() == 5);
341 BOOST_TEST(s1.get_deleter().state() == 0);
342 }
343 BOOST_TEST(A::count == 0);
344
345 BOOST_TEST(A::count == 0);
346 //Bounded array unique_ptr
347 reset_counters();
348 {
349 bml::unique_ptr<A[2], move_constr_deleter<A[2]> > s1(new A[2]);
350 A* p = s1.get();
351 bml::unique_ptr<A[2], move_constr_deleter<A[2]> > s2(new A[2]);
352 BOOST_TEST(A::count == 4);
353 s2 = boost::move(s1);
354 BOOST_TEST(s2.get() == p);
355 BOOST_TEST(s1.get() == 0);
356 BOOST_TEST(A::count == 2);
357 BOOST_TEST(s2.get_deleter().state() == 5);
358 BOOST_TEST(s1.get_deleter().state() == 0);
359 }
360 BOOST_TEST(A::count == 0);
361}
362
363} //unique_ptr_asgn_move_movedel
364
365////////////////////////////////
366// unique_ptr_asgn_move_copydelref
367////////////////////////////////
368namespace unique_ptr_asgn_move_copydelref {
369
370void test()
371{
372 //Single unique_ptr
373 reset_counters();
374 {
375 copy_constr_deleter<A> d1(5);
376 bml::unique_ptr<A, copy_constr_deleter<A>&> s1(new A, d1);
377 A* p = s1.get();
378 copy_constr_deleter<A> d2(6);
379 bml::unique_ptr<A, copy_constr_deleter<A>&> s2(new A, d2);
380 s2 = boost::move(s1);
381 BOOST_TEST(s2.get() == p);
382 BOOST_TEST(s1.get() == 0);
383 BOOST_TEST(A::count == 1);
384 BOOST_TEST(d1.state() == 5);
385 BOOST_TEST(d2.state() == 5);
386 }
387 BOOST_TEST(A::count == 0);
388
389 //Unbounded array unique_ptr
390 reset_counters();
391 {
392 copy_constr_deleter<A[]> d1(5);
393 bml::unique_ptr<A[], copy_constr_deleter<A[]>&> s1(new A[2], d1);
394 A* p = s1.get();
395 copy_constr_deleter<A[]> d2(6);
396 bml::unique_ptr<A[], copy_constr_deleter<A[]>&> s2(new A[2], d2);
397 BOOST_TEST(A::count == 4);
398 s2 = boost::move(s1);
399 BOOST_TEST(s2.get() == p);
400 BOOST_TEST(s1.get() == 0);
401 BOOST_TEST(A::count == 2);
402 BOOST_TEST(d1.state() == 5);
403 BOOST_TEST(d2.state() == 5);
404 }
405 BOOST_TEST(A::count == 0);
406 //Bounded array unique_ptr
407 reset_counters();
408 {
409 copy_constr_deleter<A[2]> d1(5);
410 bml::unique_ptr<A[2], copy_constr_deleter<A[2]>&> s1(new A[2], d1);
411 A* p = s1.get();
412 copy_constr_deleter<A[2]> d2(6);
413 bml::unique_ptr<A[2], copy_constr_deleter<A[2]>&> s2(new A[2], d2);
414 BOOST_TEST(A::count == 4);
415 s2 = boost::move(s1);
416 BOOST_TEST(s2.get() == p);
417 BOOST_TEST(s1.get() == 0);
418 BOOST_TEST(A::count == 2);
419 BOOST_TEST(d1.state() == 5);
420 BOOST_TEST(d2.state() == 5);
421 }
422 BOOST_TEST(A::count == 0);
423}
424
425} //unique_ptr_asgn_move_copydelref
426
427////////////////////////////////
428// main
429////////////////////////////////
430int main()
431{
432 //Assignment
433 unique_ptr_asgn_move_convert_defdel::test();
434 unique_ptr_asgn_move_convert_movedel::test();
435 unique_ptr_asgn_move_convert_copydelref::test();
436 unique_ptr_asgn_move_defdel::test();
437 unique_ptr_asgn_move_movedel::test();
438 unique_ptr_asgn_move_copydelref::test();
439
440 //Test results
441 return boost::report_errors();
442}
443
444#include "unique_ptr_test_utils_end.hpp"