1 | ////////////////////////////////////////////////////////////////////////////// |
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/core/lightweight_test.hpp> |
16 | |
17 | ////////////////////////////////////////////// |
18 | // |
19 | // The initial implementation of these tests |
20 | // was written by Howard Hinnant. |
21 | // |
22 | // These test were later refactored grouping |
23 | // and porting them to Boost.Move. |
24 | // |
25 | // Many thanks to Howard for releasing his C++03 |
26 | // unique_ptr implementation with such detailed |
27 | // test cases. |
28 | // |
29 | ////////////////////////////////////////////// |
30 | |
31 | #include "unique_ptr_test_utils_beg.hpp" |
32 | |
33 | namespace bml = ::boost::movelib; |
34 | |
35 | //////////////////////////////// |
36 | // unique_ptr_dtor_null |
37 | //////////////////////////////// |
38 | |
39 | namespace unique_ptr_dtor_null{ |
40 | |
41 | // The deleter is not called if get() == 0 |
42 | |
43 | void test() |
44 | { |
45 | //Single unique_ptr |
46 | { |
47 | def_constr_deleter<int> d; |
48 | BOOST_TEST(d.state() == 5); |
49 | { |
50 | bml::unique_ptr<int, def_constr_deleter<int>&> p(0, d); |
51 | BOOST_TEST(p.get() == 0); |
52 | BOOST_TEST(&p.get_deleter() == &d); |
53 | } |
54 | BOOST_TEST(d.state() == 5); |
55 | } |
56 | { |
57 | //Unbounded array unique_ptr |
58 | def_constr_deleter<int[]> d; |
59 | BOOST_TEST(d.state() == 5); |
60 | { |
61 | bml::unique_ptr<int[], def_constr_deleter<int[]>&> p(0, d); |
62 | BOOST_TEST(p.get() == 0); |
63 | BOOST_TEST(&p.get_deleter() == &d); |
64 | } |
65 | BOOST_TEST(d.state() == 5); |
66 | } |
67 | { |
68 | //Bounded array unique_ptr |
69 | def_constr_deleter<int[2]> d; |
70 | BOOST_TEST(d.state() == 5); |
71 | { |
72 | bml::unique_ptr<int[2], def_constr_deleter<int[2]>&> p(0, d); |
73 | BOOST_TEST(p.get() == 0); |
74 | BOOST_TEST(&p.get_deleter() == &d); |
75 | } |
76 | BOOST_TEST(d.state() == 5); |
77 | } |
78 | } |
79 | |
80 | } //namespace unique_ptr_dtor_null{ |
81 | |
82 | //////////////////////////////// |
83 | // unique_ptr_ctor_default_delreq |
84 | //////////////////////////////// |
85 | |
86 | namespace unique_ptr_ctor_default_delreq{ |
87 | |
88 | // default unique_ptr ctor should only require default deleter ctor |
89 | |
90 | void test() |
91 | { |
92 | //Single unique_ptr |
93 | { |
94 | bml::unique_ptr<int> p; |
95 | BOOST_TEST(p.get() == 0); |
96 | } |
97 | { |
98 | bml::unique_ptr<int, def_constr_deleter<int> > p; |
99 | BOOST_TEST(p.get() == 0); |
100 | BOOST_TEST(p.get_deleter().state() == 5); |
101 | } |
102 | //Unbounded array unique_ptr |
103 | { |
104 | bml::unique_ptr<int[]> p; |
105 | BOOST_TEST(p.get() == 0); |
106 | } |
107 | { |
108 | bml::unique_ptr<int[], def_constr_deleter<int[]> > p; |
109 | BOOST_TEST(p.get() == 0); |
110 | BOOST_TEST(p.get_deleter().state() == 5); |
111 | } |
112 | |
113 | //Unbounded array unique_ptr |
114 | { |
115 | bml::unique_ptr<int[]> p; |
116 | BOOST_TEST(p.get() == 0); |
117 | } |
118 | { |
119 | bml::unique_ptr<int[], def_constr_deleter<int[]> > p; |
120 | BOOST_TEST(p.get() == 0); |
121 | BOOST_TEST(p.get_deleter().state() == 5); |
122 | } |
123 | |
124 | //Unbounded array unique_ptr |
125 | { |
126 | bml::unique_ptr<int[2]> p; |
127 | BOOST_TEST(p.get() == 0); |
128 | } |
129 | { |
130 | bml::unique_ptr<int[2], def_constr_deleter<int[2]> > p; |
131 | BOOST_TEST(p.get() == 0); |
132 | BOOST_TEST(p.get_deleter().state() == 5); |
133 | } |
134 | } |
135 | |
136 | } //namespace unique_ptr_ctor_default_delreq{ |
137 | |
138 | //////////////////////////////// |
139 | // unique_ptr_ctor_default_nocomplete |
140 | //////////////////////////////// |
141 | |
142 | namespace unique_ptr_ctor_default_nocomplete{ |
143 | |
144 | // default unique_ptr ctor shouldn't require complete type |
145 | |
146 | void test() |
147 | { |
148 | //Single unique_ptr |
149 | reset_counters(); |
150 | { |
151 | J<I> s; |
152 | BOOST_TEST(s.get() == 0); |
153 | } |
154 | check(i: 0); |
155 | { |
156 | J<I, def_constr_deleter<I> > s; |
157 | BOOST_TEST(s.get() == 0); |
158 | BOOST_TEST(s.get_deleter().state() == 5); |
159 | } |
160 | check(i: 0); |
161 | //Unbounded array unique_ptr |
162 | reset_counters(); |
163 | { |
164 | J<I[]> s; |
165 | BOOST_TEST(s.get() == 0); |
166 | } |
167 | check(i: 0); |
168 | { |
169 | J<I[], def_constr_deleter<I[]> > s; |
170 | BOOST_TEST(s.get() == 0); |
171 | BOOST_TEST(s.get_deleter().state() == 5); |
172 | } |
173 | check(i: 0); |
174 | |
175 | //Bounded array unique_ptr |
176 | reset_counters(); |
177 | { |
178 | J<I[2]> s; |
179 | BOOST_TEST(s.get() == 0); |
180 | } |
181 | check(i: 0); |
182 | { |
183 | J<I[2], def_constr_deleter<I[2]> > s; |
184 | BOOST_TEST(s.get() == 0); |
185 | BOOST_TEST(s.get_deleter().state() == 5); |
186 | } |
187 | check(i: 0); |
188 | } |
189 | |
190 | } //namespace unique_ptr_ctor_default_nocomplete{ |
191 | |
192 | //////////////////////////////// |
193 | // unique_ptr_ctor_pointer_delreq |
194 | //////////////////////////////// |
195 | |
196 | namespace unique_ptr_ctor_pointer_delreq{ |
197 | |
198 | // unique_ptr(pointer) ctor should only require default deleter ctor |
199 | |
200 | void test() |
201 | { |
202 | //Single unique_ptr |
203 | reset_counters(); |
204 | { |
205 | A* p = new A; |
206 | BOOST_TEST(A::count == 1); |
207 | bml::unique_ptr<A> s(p); |
208 | BOOST_TEST(s.get() == p); |
209 | } |
210 | BOOST_TEST(A::count == 0); |
211 | { |
212 | A* p = new A; |
213 | BOOST_TEST(A::count == 1); |
214 | bml::unique_ptr<A, def_constr_deleter<A> > s(p); |
215 | BOOST_TEST(s.get() == p); |
216 | BOOST_TEST(s.get_deleter().state() == 5); |
217 | } |
218 | BOOST_TEST(A::count == 0); |
219 | //Unbounded array unique_ptr |
220 | reset_counters(); |
221 | { |
222 | A* p = new A[2]; |
223 | BOOST_TEST(A::count == 2); |
224 | bml::unique_ptr<A[]> s(p); |
225 | BOOST_TEST(s.get() == p); |
226 | } |
227 | BOOST_TEST(A::count == 0); |
228 | { |
229 | A* p = new A[2]; |
230 | BOOST_TEST(A::count == 2); |
231 | bml::unique_ptr<A[], def_constr_deleter<A[]> > s(p); |
232 | BOOST_TEST(s.get() == p); |
233 | BOOST_TEST(s.get_deleter().state() == 5); |
234 | } |
235 | BOOST_TEST(A::count == 0); |
236 | //Bounded array unique_ptr |
237 | reset_counters(); |
238 | { |
239 | A* p = new A[2]; |
240 | BOOST_TEST(A::count == 2); |
241 | bml::unique_ptr<A[2]> s(p); |
242 | BOOST_TEST(s.get() == p); |
243 | } |
244 | BOOST_TEST(A::count == 0); |
245 | { |
246 | A* p = new A[2]; |
247 | BOOST_TEST(A::count == 2); |
248 | bml::unique_ptr<A[2], def_constr_deleter<A[2]> > s(p); |
249 | BOOST_TEST(s.get() == p); |
250 | BOOST_TEST(s.get_deleter().state() == 5); |
251 | } |
252 | BOOST_TEST(A::count == 0); |
253 | } |
254 | |
255 | } //namespace unique_ptr_ctor_pointer_delreq{ |
256 | |
257 | //////////////////////////////// |
258 | // unique_ptr_ctor_pointer_nocomplete |
259 | //////////////////////////////// |
260 | |
261 | namespace unique_ptr_ctor_pointer_nocomplete{ |
262 | |
263 | // unique_ptr(pointer) ctor shouldn't require complete type |
264 | |
265 | void test() |
266 | { |
267 | //Single unique_ptr |
268 | reset_counters(); |
269 | { |
270 | I* p = get(); |
271 | check(i: 1); |
272 | J<I> s(p); |
273 | BOOST_TEST(s.get() == p); |
274 | } |
275 | check(i: 0); |
276 | { |
277 | I* p = get(); |
278 | check(i: 1); |
279 | J<I, def_constr_deleter<I> > s(p); |
280 | BOOST_TEST(s.get() == p); |
281 | BOOST_TEST(s.get_deleter().state() == 5); |
282 | } |
283 | check(i: 0); |
284 | //Unbounded array unique_ptr |
285 | reset_counters(); |
286 | { |
287 | I* p = get_array(i: 2); |
288 | check(i: 2); |
289 | J<I[]> s(p); |
290 | BOOST_TEST(s.get() == p); |
291 | } |
292 | check(i: 0); |
293 | { |
294 | I* p = get_array(i: 2); |
295 | check(i: 2); |
296 | J<I[], def_constr_deleter<I[]> > s(p); |
297 | BOOST_TEST(s.get() == p); |
298 | BOOST_TEST(s.get_deleter().state() == 5); |
299 | } |
300 | check(i: 0); |
301 | //Bounded array unique_ptr |
302 | reset_counters(); |
303 | { |
304 | I* p = get_array(i: 2); |
305 | check(i: 2); |
306 | J<I[]> s(p); |
307 | BOOST_TEST(s.get() == p); |
308 | } |
309 | check(i: 0); |
310 | { |
311 | I* p = get_array(i: 2); |
312 | check(i: 2); |
313 | J<I[2], def_constr_deleter<I[2]> > s(p); |
314 | BOOST_TEST(s.get() == p); |
315 | BOOST_TEST(s.get_deleter().state() == 5); |
316 | } |
317 | check(i: 0); |
318 | } |
319 | |
320 | } //namespace unique_ptr_ctor_pointer_nocomplete{ |
321 | |
322 | //////////////////////////////// |
323 | // unique_ptr_ctor_pointer_convert |
324 | //////////////////////////////// |
325 | |
326 | namespace unique_ptr_ctor_pointer_convert{ |
327 | |
328 | // unique_ptr(pointer) ctor should work with derived pointers |
329 | // or same types (cv aside) for unique_ptr<arrays> |
330 | |
331 | void test() |
332 | { |
333 | //Single unique_ptr |
334 | reset_counters(); |
335 | { |
336 | B* p = new B; |
337 | BOOST_TEST(A::count == 1); |
338 | BOOST_TEST(B::count == 1); |
339 | bml::unique_ptr<A> s(p); |
340 | BOOST_TEST(s.get() == p); |
341 | } |
342 | BOOST_TEST(A::count == 0); |
343 | BOOST_TEST(B::count == 0); |
344 | { |
345 | B* p = new B; |
346 | BOOST_TEST(A::count == 1); |
347 | BOOST_TEST(B::count == 1); |
348 | bml::unique_ptr<A, def_constr_deleter<A> > s(p); |
349 | BOOST_TEST(s.get() == p); |
350 | BOOST_TEST(s.get_deleter().state() == 5); |
351 | } |
352 | BOOST_TEST(A::count == 0); |
353 | BOOST_TEST(B::count == 0); |
354 | //Unbounded array unique_ptr |
355 | reset_counters(); |
356 | { |
357 | A* p = new A[2]; |
358 | BOOST_TEST(A::count == 2); |
359 | bml::unique_ptr<const A[]> s(p); |
360 | BOOST_TEST(s.get() == p); |
361 | } |
362 | BOOST_TEST(A::count == 0); |
363 | { |
364 | const A* p = new const A[2]; |
365 | BOOST_TEST(A::count == 2); |
366 | bml::unique_ptr<const volatile A[], def_constr_deleter<const volatile A[]> > s(p); |
367 | BOOST_TEST(s.get() == p); |
368 | BOOST_TEST(s.get_deleter().state() == 5); |
369 | } |
370 | BOOST_TEST(A::count == 0); |
371 | //Bounded array unique_ptr |
372 | reset_counters(); |
373 | { |
374 | A* p = new A[2]; |
375 | BOOST_TEST(A::count == 2); |
376 | bml::unique_ptr<const A[2]> s(p); |
377 | BOOST_TEST(s.get() == p); |
378 | } |
379 | BOOST_TEST(A::count == 0); |
380 | { |
381 | const A* p = new const A[2]; |
382 | BOOST_TEST(A::count == 2); |
383 | bml::unique_ptr<const volatile A[2], def_constr_deleter<const volatile A[2]> > s(p); |
384 | BOOST_TEST(s.get() == p); |
385 | BOOST_TEST(s.get_deleter().state() == 5); |
386 | } |
387 | BOOST_TEST(A::count == 0); |
388 | } |
389 | |
390 | } //namespace unique_ptr_ctor_pointer_convert{ |
391 | |
392 | //////////////////////////////// |
393 | // unique_ptr_ctor_pointer_deleter_movedel |
394 | //////////////////////////////// |
395 | |
396 | namespace unique_ptr_ctor_pointer_deleter_movedel{ |
397 | |
398 | // test move ctor. Should only require a MoveConstructible deleter, or if |
399 | // deleter is a reference, not even that. |
400 | |
401 | // unique_ptr(pointer, deleter()) only requires MoveConstructible deleter |
402 | |
403 | void test() |
404 | { |
405 | //Single unique_ptr |
406 | reset_counters(); |
407 | { |
408 | A* p = new A; |
409 | BOOST_TEST(A::count == 1); |
410 | move_constr_deleter<A> d; |
411 | bml::unique_ptr<A, move_constr_deleter<A> > s(p, ::boost::move(t&: d)); |
412 | BOOST_TEST(s.get() == p); |
413 | BOOST_TEST(s.get_deleter().state() == 5); |
414 | bml::unique_ptr<A, move_constr_deleter<A> > s2(s.release(), move_constr_deleter<A>(6)); |
415 | BOOST_TEST(s2.get() == p); |
416 | BOOST_TEST(s2.get_deleter().state() == 6); |
417 | } |
418 | BOOST_TEST(A::count == 0); |
419 | //Unbounded array unique_ptr |
420 | reset_counters(); |
421 | { |
422 | A* p = new A[2]; |
423 | BOOST_TEST(A::count == 2); |
424 | move_constr_deleter<A[]> d; |
425 | bml::unique_ptr<A[], move_constr_deleter<A[]> > s(p, ::boost::move(t&: d)); |
426 | BOOST_TEST(s.get() == p); |
427 | BOOST_TEST(s.get_deleter().state() == 5); |
428 | bml::unique_ptr<A[], move_constr_deleter<A[]> > s2(s.release(), move_constr_deleter<A[]>(6)); |
429 | BOOST_TEST(s2.get() == p); |
430 | BOOST_TEST(s2.get_deleter().state() == 6); |
431 | } |
432 | BOOST_TEST(A::count == 0); |
433 | //Bounded array unique_ptr |
434 | reset_counters(); |
435 | { |
436 | A* p = new A[2]; |
437 | BOOST_TEST(A::count == 2); |
438 | move_constr_deleter<A[2]> d; |
439 | bml::unique_ptr<A[2], move_constr_deleter<A[2]> > s(p, ::boost::move(t&: d)); |
440 | BOOST_TEST(s.get() == p); |
441 | BOOST_TEST(s.get_deleter().state() == 5); |
442 | bml::unique_ptr<A[2], move_constr_deleter<A[2]> > s2(s.release(), move_constr_deleter<A[2]>(6)); |
443 | BOOST_TEST(s2.get() == p); |
444 | BOOST_TEST(s2.get_deleter().state() == 6); |
445 | } |
446 | BOOST_TEST(A::count == 0); |
447 | } |
448 | |
449 | } //namespace unique_ptr_ctor_pointer_deleter_movedel{ |
450 | |
451 | //////////////////////////////// |
452 | // unique_ptr_ctor_pointer_deleter_copydel |
453 | //////////////////////////////// |
454 | |
455 | namespace unique_ptr_ctor_pointer_deleter_copydel{ |
456 | |
457 | // unique_ptr(pointer, d) requires CopyConstructible deleter |
458 | |
459 | void test() |
460 | { |
461 | //Single unique_ptr |
462 | reset_counters(); |
463 | { |
464 | A* p = new A; |
465 | BOOST_TEST(A::count == 1); |
466 | copy_constr_deleter<A> d; |
467 | bml::unique_ptr<A, copy_constr_deleter<A> > s(p, d); |
468 | BOOST_TEST(s.get() == p); |
469 | BOOST_TEST(s.get_deleter().state() == 5); |
470 | d.set_state(6); |
471 | BOOST_TEST(s.get_deleter().state() == 5); |
472 | } |
473 | BOOST_TEST(A::count == 0); |
474 | //Unbounded array unique_ptr |
475 | reset_counters(); |
476 | { |
477 | A* p = new A[2]; |
478 | BOOST_TEST(A::count == 2); |
479 | copy_constr_deleter<A[]> d; |
480 | bml::unique_ptr<A[], copy_constr_deleter<A[]> > s(p, d); |
481 | BOOST_TEST(s.get() == p); |
482 | BOOST_TEST(s.get_deleter().state() == 5); |
483 | d.set_state(6); |
484 | BOOST_TEST(s.get_deleter().state() == 5); |
485 | } |
486 | BOOST_TEST(A::count == 0); |
487 | //Bounded array unique_ptr |
488 | reset_counters(); |
489 | { |
490 | A* p = new A[2]; |
491 | BOOST_TEST(A::count == 2); |
492 | copy_constr_deleter<A[2]> d; |
493 | bml::unique_ptr<A[2], copy_constr_deleter<A[2]> > s(p, d); |
494 | BOOST_TEST(s.get() == p); |
495 | BOOST_TEST(s.get_deleter().state() == 5); |
496 | d.set_state(6); |
497 | BOOST_TEST(s.get_deleter().state() == 5); |
498 | } |
499 | BOOST_TEST(A::count == 0); |
500 | } |
501 | |
502 | } //namespace unique_ptr_ctor_pointer_deleter_copydel{ |
503 | |
504 | //////////////////////////////// |
505 | // unique_ptr_ctor_pointer_deleter_dfctrdelref |
506 | //////////////////////////////// |
507 | |
508 | namespace unique_ptr_ctor_pointer_deleter_dfctrdelref{ |
509 | |
510 | // unique_ptr<T, D&>(pointer, d) does not requires CopyConstructible deleter |
511 | |
512 | void test() |
513 | { |
514 | //Single unique_ptr |
515 | reset_counters(); |
516 | { |
517 | A* p = new A; |
518 | BOOST_TEST(A::count == 1); |
519 | def_constr_deleter<A> d; |
520 | bml::unique_ptr<A, def_constr_deleter<A>&> s(p, d); |
521 | BOOST_TEST(s.get() == p); |
522 | BOOST_TEST(s.get_deleter().state() == 5); |
523 | d.set_state(6); |
524 | BOOST_TEST(s.get_deleter().state() == 6); |
525 | } |
526 | BOOST_TEST(A::count == 0); |
527 | //Unbounded array unique_ptr |
528 | reset_counters(); |
529 | { |
530 | A* p = new A[2]; |
531 | BOOST_TEST(A::count == 2); |
532 | def_constr_deleter<A[]> d; |
533 | bml::unique_ptr<A[], def_constr_deleter<A[]>&> s(p, d); |
534 | BOOST_TEST(s.get() == p); |
535 | BOOST_TEST(s.get_deleter().state() == 5); |
536 | d.set_state(6); |
537 | BOOST_TEST(s.get_deleter().state() == 6); |
538 | } |
539 | BOOST_TEST(A::count == 0); |
540 | //Bounded array unique_ptr |
541 | reset_counters(); |
542 | { |
543 | A* p = new A[2]; |
544 | BOOST_TEST(A::count == 2); |
545 | def_constr_deleter<A[2]> d; |
546 | bml::unique_ptr<A[2], def_constr_deleter<A[2]>&> s(p, d); |
547 | BOOST_TEST(s.get() == p); |
548 | BOOST_TEST(s.get_deleter().state() == 5); |
549 | d.set_state(6); |
550 | BOOST_TEST(s.get_deleter().state() == 6); |
551 | } |
552 | BOOST_TEST(A::count == 0); |
553 | } |
554 | |
555 | } //namespace unique_ptr_ctor_pointer_deleter_dfctrdelref{ |
556 | |
557 | //////////////////////////////// |
558 | // unique_ptr_ctor_pointer_deleter_dfctrdelconstref |
559 | //////////////////////////////// |
560 | |
561 | namespace unique_ptr_ctor_pointer_deleter_dfctrdelconstref{ |
562 | |
563 | // unique_ptr<T, const D&>(pointer, d) does not requires CopyConstructible deleter |
564 | |
565 | void test() |
566 | { |
567 | //Single unique_ptr |
568 | reset_counters(); |
569 | { |
570 | A* p = new A; |
571 | BOOST_TEST(A::count == 1); |
572 | def_constr_deleter<A> d; |
573 | bml::unique_ptr<A, const def_constr_deleter<A>&> s(p, d); |
574 | BOOST_TEST(s.get() == p); |
575 | BOOST_TEST(s.get_deleter().state() == 5); |
576 | } |
577 | BOOST_TEST(A::count == 0); |
578 | //Unbounded array unique_ptr |
579 | reset_counters(); |
580 | { |
581 | A* p = new A[2]; |
582 | BOOST_TEST(A::count == 2); |
583 | def_constr_deleter<A[]> d; |
584 | bml::unique_ptr<A[], const def_constr_deleter<A[]>&> s(p, d); |
585 | BOOST_TEST(s.get() == p); |
586 | BOOST_TEST(s.get_deleter().state() == 5); |
587 | } |
588 | BOOST_TEST(A::count == 0); |
589 | //Bounded array unique_ptr |
590 | reset_counters(); |
591 | { |
592 | A* p = new A[2]; |
593 | BOOST_TEST(A::count == 2); |
594 | def_constr_deleter<A[2]> d; |
595 | bml::unique_ptr<A[2], const def_constr_deleter<A[2]>&> s(p, d); |
596 | BOOST_TEST(s.get() == p); |
597 | BOOST_TEST(s.get_deleter().state() == 5); |
598 | } |
599 | BOOST_TEST(A::count == 0); |
600 | } |
601 | |
602 | } //namespace unique_ptr_ctor_pointer_deleter_dfctrdelconstref{ |
603 | |
604 | //////////////////////////////// |
605 | // unique_ptr_ctor_pointer_deleter_convert |
606 | //////////////////////////////// |
607 | |
608 | namespace unique_ptr_ctor_pointer_deleter_convert{ |
609 | |
610 | // unique_ptr(pointer, deleter) should work with derived pointers |
611 | // or same (cv aside) types for array unique_ptrs |
612 | |
613 | void test() |
614 | { |
615 | //Single unique_ptr |
616 | reset_counters(); |
617 | { |
618 | B* p = new B; |
619 | BOOST_TEST(A::count == 1); |
620 | BOOST_TEST(B::count == 1); |
621 | bml::unique_ptr<A, copy_constr_deleter<A> > s(p, copy_constr_deleter<A>()); |
622 | BOOST_TEST(s.get() == p); |
623 | BOOST_TEST(s.get_deleter().state() == 5); |
624 | } |
625 | BOOST_TEST(A::count == 0); |
626 | BOOST_TEST(B::count == 0); |
627 | //Unbounded array unique_ptr |
628 | reset_counters(); |
629 | { |
630 | A* p = new A[2]; |
631 | BOOST_TEST(A::count == 2); |
632 | bml::unique_ptr<const A[], copy_constr_deleter<const A[]> > s(p, copy_constr_deleter<const A[]>()); |
633 | BOOST_TEST(s.get() == p); |
634 | BOOST_TEST(s.get_deleter().state() == 5); |
635 | } |
636 | BOOST_TEST(A::count == 0); |
637 | BOOST_TEST(B::count == 0); |
638 | //Bounded array unique_ptr |
639 | reset_counters(); |
640 | { |
641 | A* p = new A[2]; |
642 | BOOST_TEST(A::count == 2); |
643 | bml::unique_ptr<const A[2], copy_constr_deleter<const A[2]> > s(p, copy_constr_deleter<const A[2]>()); |
644 | BOOST_TEST(s.get() == p); |
645 | BOOST_TEST(s.get_deleter().state() == 5); |
646 | } |
647 | BOOST_TEST(A::count == 0); |
648 | BOOST_TEST(B::count == 0); |
649 | } |
650 | |
651 | } //namespace unique_ptr_ctor_pointer_deleter_convert{ |
652 | |
653 | //////////////////////////////// |
654 | // unique_ptr_ctor_pointer_deleter_void |
655 | //////////////////////////////// |
656 | |
657 | namespace unique_ptr_ctor_pointer_deleter_void{ |
658 | |
659 | // unique_ptr(pointer, deleter) should work with function pointers |
660 | // unique_ptr<void> should work |
661 | |
662 | bool my_free_called = false; |
663 | |
664 | void my_free(void*) |
665 | { |
666 | my_free_called = true; |
667 | } |
668 | |
669 | void test() |
670 | { |
671 | { |
672 | int i = 0; |
673 | bml::unique_ptr<void, void (*)(void*)> s(&i, my_free); |
674 | BOOST_TEST(s.get() == &i); |
675 | BOOST_TEST(s.get_deleter() == my_free); |
676 | BOOST_TEST(!my_free_called); |
677 | } |
678 | BOOST_TEST(my_free_called); |
679 | } |
680 | |
681 | } //namespace unique_ptr_ctor_pointer_deleter_void{ |
682 | |
683 | //////////////////////////////// |
684 | // return_unique_single_conversion |
685 | //////////////////////////////// |
686 | |
687 | namespace return_unique_single_conversion{ |
688 | |
689 | template<class T> |
690 | bml::unique_ptr<T> make_unique_ptr_of_t() |
691 | { |
692 | return bml::unique_ptr<T>(new T); |
693 | } |
694 | |
695 | template<class T> |
696 | bml::unique_ptr<T const> return_const_unique_of_t() |
697 | { |
698 | return bml::unique_ptr<T const> (make_unique_ptr_of_t<T>()); |
699 | } |
700 | |
701 | void test() |
702 | { |
703 | reset_counters(); |
704 | BOOST_TEST(A::count == 0); |
705 | { |
706 | bml::unique_ptr<const A> p(return_const_unique_of_t<A>()); |
707 | BOOST_TEST(A::count == 1); |
708 | BOOST_TEST(B::count == 0); |
709 | } |
710 | BOOST_TEST(A::count == 0); |
711 | { |
712 | bml::unique_ptr<const A> p(return_const_unique_of_t<B>()); |
713 | BOOST_TEST(A::count == 1); |
714 | BOOST_TEST(B::count == 1); |
715 | } |
716 | BOOST_TEST(A::count == 0); |
717 | } |
718 | |
719 | } //namespace return_unique_single_conversion{ |
720 | |
721 | |
722 | //////////////////////////////// |
723 | // return_unique_array_conversion |
724 | //////////////////////////////// |
725 | |
726 | namespace return_unique_array_conversion{ |
727 | |
728 | template<class T> |
729 | bml::unique_ptr<T[]> return_unique_array_of_t(std::size_t n) |
730 | { |
731 | return bml::unique_ptr<T[]>(new T[n]); |
732 | } |
733 | |
734 | template<class T> |
735 | bml::unique_ptr<const T[]> return_const_array_of_t(std::size_t n) |
736 | { |
737 | return bml::unique_ptr<const T[]>(return_unique_array_of_t<T>(n)); |
738 | } |
739 | |
740 | template<class T> |
741 | bml::unique_ptr<T[2]> return_unique_array_of_t_2() |
742 | { |
743 | return bml::unique_ptr<T[2]>(new T[2]); |
744 | } |
745 | |
746 | template<class T> |
747 | bml::unique_ptr<const T[2]> return_const_array_of_t_2() |
748 | { |
749 | return bml::unique_ptr<const T[2]>(return_unique_array_of_t_2<T>()); |
750 | } |
751 | |
752 | void test() |
753 | { |
754 | reset_counters(); |
755 | BOOST_TEST(A::count == 0); |
756 | { |
757 | bml::unique_ptr<const A[]> p(return_unique_array_of_t<A>(n: 2)); |
758 | BOOST_TEST(A::count == 2); |
759 | BOOST_TEST(B::count == 0); |
760 | } |
761 | BOOST_TEST(A::count == 0); |
762 | { |
763 | bml::unique_ptr<const volatile A[]> p(return_unique_array_of_t<volatile A>(n: 2)); |
764 | BOOST_TEST(A::count == 2); |
765 | BOOST_TEST(B::count == 0); |
766 | } |
767 | BOOST_TEST(A::count == 0); |
768 | { |
769 | bml::unique_ptr<const volatile A[2]> p(return_const_array_of_t_2<A>()); |
770 | BOOST_TEST(A::count == 2); |
771 | BOOST_TEST(B::count == 0); |
772 | } |
773 | BOOST_TEST(A::count == 0); |
774 | { |
775 | bml::unique_ptr<const volatile A[]> p(return_const_array_of_t_2<A>()); |
776 | BOOST_TEST(A::count == 2); |
777 | BOOST_TEST(B::count == 0); |
778 | } |
779 | BOOST_TEST(A::count == 0); |
780 | } |
781 | |
782 | } //namespace return_unique_array_conversion{ |
783 | |
784 | //////////////////////////////// |
785 | // main |
786 | //////////////////////////////// |
787 | int main() |
788 | { |
789 | //Constructors/Destructor |
790 | unique_ptr_dtor_null::test(); |
791 | unique_ptr_ctor_default_delreq::test(); |
792 | unique_ptr_ctor_default_nocomplete::test(); |
793 | unique_ptr_ctor_pointer_delreq::test(); |
794 | unique_ptr_ctor_pointer_nocomplete::test(); |
795 | unique_ptr_ctor_pointer_convert::test(); |
796 | unique_ptr_ctor_pointer_deleter_movedel::test(); |
797 | unique_ptr_ctor_pointer_deleter_copydel::test(); |
798 | unique_ptr_ctor_pointer_deleter_dfctrdelref::test(); |
799 | unique_ptr_ctor_pointer_deleter_dfctrdelconstref::test(); |
800 | unique_ptr_ctor_pointer_deleter_convert::test(); |
801 | unique_ptr_ctor_pointer_deleter_void::test(); |
802 | return_unique_single_conversion::test(); |
803 | return_unique_array_conversion::test(); |
804 | |
805 | //Test results |
806 | return boost::report_errors(); |
807 | |
808 | } |
809 | |
810 | #include "unique_ptr_test_utils_end.hpp" |
811 | |