1 //////////////////////////////////////////////////////////////////////////////
3 // (C) Copyright Howard Hinnant 2009
4 // (C) Copyright Ion Gaztanaga 2014-2014.
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)
10 // See http://www.boost.org/libs/move for documentation.
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>
18 //////////////////////////////////////////////
20 // The initial implementation of these tests
21 // was written by Howard Hinnant.
23 // These test were later refactored grouping
24 // and porting them to Boost.Move.
26 // Many thanks to Howard for releasing his C++03
27 // unique_ptr implementation with such detailed
30 //////////////////////////////////////////////
32 #include "unique_ptr_test_utils_beg.hpp"
34 namespace bml
= ::boost::movelib
;
36 ////////////////////////////////
37 // unique_ptr_dtor_null
38 ////////////////////////////////
40 namespace unique_ptr_dtor_null
{
42 // The deleter is not called if get() == 0
48 def_constr_deleter
<int> d
;
49 BOOST_TEST(d
.state() == 5);
51 bml::unique_ptr
<int, def_constr_deleter
<int>&> p(0, d
);
52 BOOST_TEST(p
.get() == 0);
53 BOOST_TEST(&p
.get_deleter() == &d
);
55 BOOST_TEST(d
.state() == 5);
58 //Unbounded array unique_ptr
59 def_constr_deleter
<int[]> d
;
60 BOOST_TEST(d
.state() == 5);
62 bml::unique_ptr
<int[], def_constr_deleter
<int[]>&> p(0, d
);
63 BOOST_TEST(p
.get() == 0);
64 BOOST_TEST(&p
.get_deleter() == &d
);
66 BOOST_TEST(d
.state() == 5);
69 //Bounded array unique_ptr
70 def_constr_deleter
<int[2]> d
;
71 BOOST_TEST(d
.state() == 5);
73 bml::unique_ptr
<int[2], def_constr_deleter
<int[2]>&> p(0, d
);
74 BOOST_TEST(p
.get() == 0);
75 BOOST_TEST(&p
.get_deleter() == &d
);
77 BOOST_TEST(d
.state() == 5);
81 } //namespace unique_ptr_dtor_null{
83 ////////////////////////////////
84 // unique_ptr_ctor_default_delreq
85 ////////////////////////////////
87 namespace unique_ptr_ctor_default_delreq
{
89 // default unique_ptr ctor should only require default deleter ctor
95 bml::unique_ptr
<int> p
;
96 BOOST_TEST(p
.get() == 0);
99 bml::unique_ptr
<int, def_constr_deleter
<int> > p
;
100 BOOST_TEST(p
.get() == 0);
101 BOOST_TEST(p
.get_deleter().state() == 5);
103 //Unbounded array unique_ptr
105 bml::unique_ptr
<int[]> p
;
106 BOOST_TEST(p
.get() == 0);
109 bml::unique_ptr
<int[], def_constr_deleter
<int[]> > p
;
110 BOOST_TEST(p
.get() == 0);
111 BOOST_TEST(p
.get_deleter().state() == 5);
114 //Unbounded array unique_ptr
116 bml::unique_ptr
<int[]> p
;
117 BOOST_TEST(p
.get() == 0);
120 bml::unique_ptr
<int[], def_constr_deleter
<int[]> > p
;
121 BOOST_TEST(p
.get() == 0);
122 BOOST_TEST(p
.get_deleter().state() == 5);
125 //Unbounded array unique_ptr
127 bml::unique_ptr
<int[2]> p
;
128 BOOST_TEST(p
.get() == 0);
131 bml::unique_ptr
<int[2], def_constr_deleter
<int[2]> > p
;
132 BOOST_TEST(p
.get() == 0);
133 BOOST_TEST(p
.get_deleter().state() == 5);
137 } //namespace unique_ptr_ctor_default_delreq{
139 ////////////////////////////////
140 // unique_ptr_ctor_default_nocomplete
141 ////////////////////////////////
143 namespace unique_ptr_ctor_default_nocomplete
{
145 // default unique_ptr ctor shouldn't require complete type
153 BOOST_TEST(s
.get() == 0);
157 J
<I
, def_constr_deleter
<I
> > s
;
158 BOOST_TEST(s
.get() == 0);
159 BOOST_TEST(s
.get_deleter().state() == 5);
162 //Unbounded array unique_ptr
166 BOOST_TEST(s
.get() == 0);
170 J
<I
[], def_constr_deleter
<I
[]> > s
;
171 BOOST_TEST(s
.get() == 0);
172 BOOST_TEST(s
.get_deleter().state() == 5);
176 //Bounded array unique_ptr
180 BOOST_TEST(s
.get() == 0);
184 J
<I
[2], def_constr_deleter
<I
[2]> > s
;
185 BOOST_TEST(s
.get() == 0);
186 BOOST_TEST(s
.get_deleter().state() == 5);
191 } //namespace unique_ptr_ctor_default_nocomplete{
193 ////////////////////////////////
194 // unique_ptr_ctor_pointer_delreq
195 ////////////////////////////////
197 namespace unique_ptr_ctor_pointer_delreq
{
199 // unique_ptr(pointer) ctor should only require default deleter ctor
207 BOOST_TEST(A::count
== 1);
208 bml::unique_ptr
<A
> s(p
);
209 BOOST_TEST(s
.get() == p
);
211 BOOST_TEST(A::count
== 0);
214 BOOST_TEST(A::count
== 1);
215 bml::unique_ptr
<A
, def_constr_deleter
<A
> > s(p
);
216 BOOST_TEST(s
.get() == p
);
217 BOOST_TEST(s
.get_deleter().state() == 5);
219 BOOST_TEST(A::count
== 0);
220 //Unbounded array unique_ptr
224 BOOST_TEST(A::count
== 2);
225 bml::unique_ptr
<A
[]> s(p
);
226 BOOST_TEST(s
.get() == p
);
228 BOOST_TEST(A::count
== 0);
231 BOOST_TEST(A::count
== 2);
232 bml::unique_ptr
<A
[], def_constr_deleter
<A
[]> > s(p
);
233 BOOST_TEST(s
.get() == p
);
234 BOOST_TEST(s
.get_deleter().state() == 5);
236 BOOST_TEST(A::count
== 0);
237 //Bounded array unique_ptr
241 BOOST_TEST(A::count
== 2);
242 bml::unique_ptr
<A
[2]> s(p
);
243 BOOST_TEST(s
.get() == p
);
245 BOOST_TEST(A::count
== 0);
248 BOOST_TEST(A::count
== 2);
249 bml::unique_ptr
<A
[2], def_constr_deleter
<A
[2]> > s(p
);
250 BOOST_TEST(s
.get() == p
);
251 BOOST_TEST(s
.get_deleter().state() == 5);
253 BOOST_TEST(A::count
== 0);
256 } //namespace unique_ptr_ctor_pointer_delreq{
258 ////////////////////////////////
259 // unique_ptr_ctor_pointer_nocomplete
260 ////////////////////////////////
262 namespace unique_ptr_ctor_pointer_nocomplete
{
264 // unique_ptr(pointer) ctor shouldn't require complete type
274 BOOST_TEST(s
.get() == p
);
280 J
<I
, def_constr_deleter
<I
> > s(p
);
281 BOOST_TEST(s
.get() == p
);
282 BOOST_TEST(s
.get_deleter().state() == 5);
285 //Unbounded array unique_ptr
291 BOOST_TEST(s
.get() == p
);
297 J
<I
[], def_constr_deleter
<I
[]> > s(p
);
298 BOOST_TEST(s
.get() == p
);
299 BOOST_TEST(s
.get_deleter().state() == 5);
302 //Bounded array unique_ptr
308 BOOST_TEST(s
.get() == p
);
314 J
<I
[2], def_constr_deleter
<I
[2]> > s(p
);
315 BOOST_TEST(s
.get() == p
);
316 BOOST_TEST(s
.get_deleter().state() == 5);
321 } //namespace unique_ptr_ctor_pointer_nocomplete{
323 ////////////////////////////////
324 // unique_ptr_ctor_pointer_convert
325 ////////////////////////////////
327 namespace unique_ptr_ctor_pointer_convert
{
329 // unique_ptr(pointer) ctor should work with derived pointers
330 // or same types (cv aside) for unique_ptr<arrays>
338 BOOST_TEST(A::count
== 1);
339 BOOST_TEST(B::count
== 1);
340 bml::unique_ptr
<A
> s(p
);
341 BOOST_TEST(s
.get() == p
);
343 BOOST_TEST(A::count
== 0);
344 BOOST_TEST(B::count
== 0);
347 BOOST_TEST(A::count
== 1);
348 BOOST_TEST(B::count
== 1);
349 bml::unique_ptr
<A
, def_constr_deleter
<A
> > s(p
);
350 BOOST_TEST(s
.get() == p
);
351 BOOST_TEST(s
.get_deleter().state() == 5);
353 BOOST_TEST(A::count
== 0);
354 BOOST_TEST(B::count
== 0);
355 //Unbounded array unique_ptr
359 BOOST_TEST(A::count
== 2);
360 bml::unique_ptr
<const A
[]> s(p
);
361 BOOST_TEST(s
.get() == p
);
363 BOOST_TEST(A::count
== 0);
365 const A
* p
= new const A
[2];
366 BOOST_TEST(A::count
== 2);
367 bml::unique_ptr
<const volatile A
[], def_constr_deleter
<const volatile A
[]> > s(p
);
368 BOOST_TEST(s
.get() == p
);
369 BOOST_TEST(s
.get_deleter().state() == 5);
371 BOOST_TEST(A::count
== 0);
372 //Bounded array unique_ptr
376 BOOST_TEST(A::count
== 2);
377 bml::unique_ptr
<const A
[2]> s(p
);
378 BOOST_TEST(s
.get() == p
);
380 BOOST_TEST(A::count
== 0);
382 const A
* p
= new const A
[2];
383 BOOST_TEST(A::count
== 2);
384 bml::unique_ptr
<const volatile A
[2], def_constr_deleter
<const volatile A
[2]> > s(p
);
385 BOOST_TEST(s
.get() == p
);
386 BOOST_TEST(s
.get_deleter().state() == 5);
388 BOOST_TEST(A::count
== 0);
391 } //namespace unique_ptr_ctor_pointer_convert{
393 ////////////////////////////////
394 // unique_ptr_ctor_pointer_deleter_movedel
395 ////////////////////////////////
397 namespace unique_ptr_ctor_pointer_deleter_movedel
{
399 // test move ctor. Should only require a MoveConstructible deleter, or if
400 // deleter is a reference, not even that.
402 // unique_ptr(pointer, deleter()) only requires MoveConstructible deleter
410 BOOST_TEST(A::count
== 1);
411 move_constr_deleter
<A
> d
;
412 bml::unique_ptr
<A
, move_constr_deleter
<A
> > s(p
, ::boost::move(d
));
413 BOOST_TEST(s
.get() == p
);
414 BOOST_TEST(s
.get_deleter().state() == 5);
415 bml::unique_ptr
<A
, move_constr_deleter
<A
> > s2(s
.release(), move_constr_deleter
<A
>(6));
416 BOOST_TEST(s2
.get() == p
);
417 BOOST_TEST(s2
.get_deleter().state() == 6);
419 BOOST_TEST(A::count
== 0);
420 //Unbounded array unique_ptr
424 BOOST_TEST(A::count
== 2);
425 move_constr_deleter
<A
[]> d
;
426 bml::unique_ptr
<A
[], move_constr_deleter
<A
[]> > s(p
, ::boost::move(d
));
427 BOOST_TEST(s
.get() == p
);
428 BOOST_TEST(s
.get_deleter().state() == 5);
429 bml::unique_ptr
<A
[], move_constr_deleter
<A
[]> > s2(s
.release(), move_constr_deleter
<A
[]>(6));
430 BOOST_TEST(s2
.get() == p
);
431 BOOST_TEST(s2
.get_deleter().state() == 6);
433 BOOST_TEST(A::count
== 0);
434 //Bounded array unique_ptr
438 BOOST_TEST(A::count
== 2);
439 move_constr_deleter
<A
[2]> d
;
440 bml::unique_ptr
<A
[2], move_constr_deleter
<A
[2]> > s(p
, ::boost::move(d
));
441 BOOST_TEST(s
.get() == p
);
442 BOOST_TEST(s
.get_deleter().state() == 5);
443 bml::unique_ptr
<A
[2], move_constr_deleter
<A
[2]> > s2(s
.release(), move_constr_deleter
<A
[2]>(6));
444 BOOST_TEST(s2
.get() == p
);
445 BOOST_TEST(s2
.get_deleter().state() == 6);
447 BOOST_TEST(A::count
== 0);
450 } //namespace unique_ptr_ctor_pointer_deleter_movedel{
452 ////////////////////////////////
453 // unique_ptr_ctor_pointer_deleter_copydel
454 ////////////////////////////////
456 namespace unique_ptr_ctor_pointer_deleter_copydel
{
458 // unique_ptr(pointer, d) requires CopyConstructible deleter
466 BOOST_TEST(A::count
== 1);
467 copy_constr_deleter
<A
> d
;
468 bml::unique_ptr
<A
, copy_constr_deleter
<A
> > s(p
, d
);
469 BOOST_TEST(s
.get() == p
);
470 BOOST_TEST(s
.get_deleter().state() == 5);
472 BOOST_TEST(s
.get_deleter().state() == 5);
474 BOOST_TEST(A::count
== 0);
475 //Unbounded array unique_ptr
479 BOOST_TEST(A::count
== 2);
480 copy_constr_deleter
<A
[]> d
;
481 bml::unique_ptr
<A
[], copy_constr_deleter
<A
[]> > s(p
, d
);
482 BOOST_TEST(s
.get() == p
);
483 BOOST_TEST(s
.get_deleter().state() == 5);
485 BOOST_TEST(s
.get_deleter().state() == 5);
487 BOOST_TEST(A::count
== 0);
488 //Bounded array unique_ptr
492 BOOST_TEST(A::count
== 2);
493 copy_constr_deleter
<A
[2]> d
;
494 bml::unique_ptr
<A
[2], copy_constr_deleter
<A
[2]> > s(p
, d
);
495 BOOST_TEST(s
.get() == p
);
496 BOOST_TEST(s
.get_deleter().state() == 5);
498 BOOST_TEST(s
.get_deleter().state() == 5);
500 BOOST_TEST(A::count
== 0);
503 } //namespace unique_ptr_ctor_pointer_deleter_copydel{
505 ////////////////////////////////
506 // unique_ptr_ctor_pointer_deleter_dfctrdelref
507 ////////////////////////////////
509 namespace unique_ptr_ctor_pointer_deleter_dfctrdelref
{
511 // unique_ptr<T, D&>(pointer, d) does not requires CopyConstructible deleter
519 BOOST_TEST(A::count
== 1);
520 def_constr_deleter
<A
> d
;
521 bml::unique_ptr
<A
, def_constr_deleter
<A
>&> s(p
, d
);
522 BOOST_TEST(s
.get() == p
);
523 BOOST_TEST(s
.get_deleter().state() == 5);
525 BOOST_TEST(s
.get_deleter().state() == 6);
527 BOOST_TEST(A::count
== 0);
528 //Unbounded array unique_ptr
532 BOOST_TEST(A::count
== 2);
533 def_constr_deleter
<A
[]> d
;
534 bml::unique_ptr
<A
[], def_constr_deleter
<A
[]>&> s(p
, d
);
535 BOOST_TEST(s
.get() == p
);
536 BOOST_TEST(s
.get_deleter().state() == 5);
538 BOOST_TEST(s
.get_deleter().state() == 6);
540 BOOST_TEST(A::count
== 0);
541 //Bounded array unique_ptr
545 BOOST_TEST(A::count
== 2);
546 def_constr_deleter
<A
[2]> d
;
547 bml::unique_ptr
<A
[2], def_constr_deleter
<A
[2]>&> s(p
, d
);
548 BOOST_TEST(s
.get() == p
);
549 BOOST_TEST(s
.get_deleter().state() == 5);
551 BOOST_TEST(s
.get_deleter().state() == 6);
553 BOOST_TEST(A::count
== 0);
556 } //namespace unique_ptr_ctor_pointer_deleter_dfctrdelref{
558 ////////////////////////////////
559 // unique_ptr_ctor_pointer_deleter_dfctrdelconstref
560 ////////////////////////////////
562 namespace unique_ptr_ctor_pointer_deleter_dfctrdelconstref
{
564 // unique_ptr<T, const D&>(pointer, d) does not requires CopyConstructible deleter
572 BOOST_TEST(A::count
== 1);
573 def_constr_deleter
<A
> d
;
574 bml::unique_ptr
<A
, const def_constr_deleter
<A
>&> s(p
, d
);
575 BOOST_TEST(s
.get() == p
);
576 BOOST_TEST(s
.get_deleter().state() == 5);
578 BOOST_TEST(A::count
== 0);
579 //Unbounded array unique_ptr
583 BOOST_TEST(A::count
== 2);
584 def_constr_deleter
<A
[]> d
;
585 bml::unique_ptr
<A
[], const def_constr_deleter
<A
[]>&> s(p
, d
);
586 BOOST_TEST(s
.get() == p
);
587 BOOST_TEST(s
.get_deleter().state() == 5);
589 BOOST_TEST(A::count
== 0);
590 //Bounded array unique_ptr
594 BOOST_TEST(A::count
== 2);
595 def_constr_deleter
<A
[2]> d
;
596 bml::unique_ptr
<A
[2], const def_constr_deleter
<A
[2]>&> s(p
, d
);
597 BOOST_TEST(s
.get() == p
);
598 BOOST_TEST(s
.get_deleter().state() == 5);
600 BOOST_TEST(A::count
== 0);
603 } //namespace unique_ptr_ctor_pointer_deleter_dfctrdelconstref{
605 ////////////////////////////////
606 // unique_ptr_ctor_pointer_deleter_convert
607 ////////////////////////////////
609 namespace unique_ptr_ctor_pointer_deleter_convert
{
611 // unique_ptr(pointer, deleter) should work with derived pointers
612 // or same (cv aside) types for array unique_ptrs
620 BOOST_TEST(A::count
== 1);
621 BOOST_TEST(B::count
== 1);
622 bml::unique_ptr
<A
, copy_constr_deleter
<A
> > s(p
, copy_constr_deleter
<A
>());
623 BOOST_TEST(s
.get() == p
);
624 BOOST_TEST(s
.get_deleter().state() == 5);
626 BOOST_TEST(A::count
== 0);
627 BOOST_TEST(B::count
== 0);
628 //Unbounded array unique_ptr
632 BOOST_TEST(A::count
== 2);
633 bml::unique_ptr
<const A
[], copy_constr_deleter
<const A
[]> > s(p
, copy_constr_deleter
<const A
[]>());
634 BOOST_TEST(s
.get() == p
);
635 BOOST_TEST(s
.get_deleter().state() == 5);
637 BOOST_TEST(A::count
== 0);
638 BOOST_TEST(B::count
== 0);
639 //Bounded array unique_ptr
643 BOOST_TEST(A::count
== 2);
644 bml::unique_ptr
<const A
[2], copy_constr_deleter
<const A
[2]> > s(p
, copy_constr_deleter
<const A
[2]>());
645 BOOST_TEST(s
.get() == p
);
646 BOOST_TEST(s
.get_deleter().state() == 5);
648 BOOST_TEST(A::count
== 0);
649 BOOST_TEST(B::count
== 0);
652 } //namespace unique_ptr_ctor_pointer_deleter_convert{
654 ////////////////////////////////
655 // unique_ptr_ctor_pointer_deleter_void
656 ////////////////////////////////
658 namespace unique_ptr_ctor_pointer_deleter_void
{
660 // unique_ptr(pointer, deleter) should work with function pointers
661 // unique_ptr<void> should work
663 bool my_free_called
= false;
667 my_free_called
= true;
674 bml::unique_ptr
<void, void (*)(void*)> s(&i
, my_free
);
675 BOOST_TEST(s
.get() == &i
);
676 BOOST_TEST(s
.get_deleter() == my_free
);
677 BOOST_TEST(!my_free_called
);
679 BOOST_TEST(my_free_called
);
682 } //namespace unique_ptr_ctor_pointer_deleter_void{
684 ////////////////////////////////
685 // return_unique_single_conversion
686 ////////////////////////////////
688 namespace return_unique_single_conversion
{
691 bml::unique_ptr
<T
> make_unique_ptr_of_t()
693 return bml::unique_ptr
<T
>(new T
);
697 bml::unique_ptr
<T
const> return_const_unique_of_t()
699 return bml::unique_ptr
<T
const> (make_unique_ptr_of_t
<T
>());
705 BOOST_TEST(A::count
== 0);
707 bml::unique_ptr
<const A
> p(return_const_unique_of_t
<A
>());
708 BOOST_TEST(A::count
== 1);
709 BOOST_TEST(B::count
== 0);
711 BOOST_TEST(A::count
== 0);
713 bml::unique_ptr
<const A
> p(return_const_unique_of_t
<B
>());
714 BOOST_TEST(A::count
== 1);
715 BOOST_TEST(B::count
== 1);
717 BOOST_TEST(A::count
== 0);
720 } //namespace return_unique_single_conversion{
723 ////////////////////////////////
724 // return_unique_array_conversion
725 ////////////////////////////////
727 namespace return_unique_array_conversion
{
730 bml::unique_ptr
<T
[]> return_unique_array_of_t(std::size_t n
)
732 return bml::unique_ptr
<T
[]>(new T
[n
]);
736 bml::unique_ptr
<const T
[]> return_const_array_of_t(std::size_t n
)
738 return bml::unique_ptr
<const T
[]>(return_unique_array_of_t
<T
>(n
));
742 bml::unique_ptr
<T
[2]> return_unique_array_of_t_2()
744 return bml::unique_ptr
<T
[2]>(new T
[2]);
748 bml::unique_ptr
<const T
[2]> return_const_array_of_t_2()
750 return bml::unique_ptr
<const T
[2]>(return_unique_array_of_t_2
<T
>());
756 BOOST_TEST(A::count
== 0);
758 bml::unique_ptr
<const A
[]> p(return_unique_array_of_t
<A
>(2));
759 BOOST_TEST(A::count
== 2);
760 BOOST_TEST(B::count
== 0);
762 BOOST_TEST(A::count
== 0);
764 bml::unique_ptr
<const volatile A
[]> p(return_unique_array_of_t
<volatile A
>(2));
765 BOOST_TEST(A::count
== 2);
766 BOOST_TEST(B::count
== 0);
768 BOOST_TEST(A::count
== 0);
770 bml::unique_ptr
<const volatile A
[2]> p(return_const_array_of_t_2
<A
>());
771 BOOST_TEST(A::count
== 2);
772 BOOST_TEST(B::count
== 0);
774 BOOST_TEST(A::count
== 0);
776 bml::unique_ptr
<const volatile A
[]> p(return_const_array_of_t_2
<A
>());
777 BOOST_TEST(A::count
== 2);
778 BOOST_TEST(B::count
== 0);
780 BOOST_TEST(A::count
== 0);
783 } //namespace return_unique_array_conversion{
785 ////////////////////////////////
787 ////////////////////////////////
790 //Constructors/Destructor
791 unique_ptr_dtor_null::test();
792 unique_ptr_ctor_default_delreq::test();
793 unique_ptr_ctor_default_nocomplete::test();
794 unique_ptr_ctor_pointer_delreq::test();
795 unique_ptr_ctor_pointer_nocomplete::test();
796 unique_ptr_ctor_pointer_convert::test();
797 unique_ptr_ctor_pointer_deleter_movedel::test();
798 unique_ptr_ctor_pointer_deleter_copydel::test();
799 unique_ptr_ctor_pointer_deleter_dfctrdelref::test();
800 unique_ptr_ctor_pointer_deleter_dfctrdelconstref::test();
801 unique_ptr_ctor_pointer_deleter_convert::test();
802 unique_ptr_ctor_pointer_deleter_void::test();
803 return_unique_single_conversion::test();
804 return_unique_array_conversion::test();
807 return boost::report_errors();
811 #include "unique_ptr_test_utils_end.hpp"