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/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 
34 namespace bml = ::boost::movelib;
35 
36 ////////////////////////////////
37 //   unique_ptr_dtor_null
38 ////////////////////////////////
39 
40 namespace unique_ptr_dtor_null{
41 
42 // The deleter is not called if get() == 0
43 
test()44 void test()
45 {
46    //Single unique_ptr
47    {
48    def_constr_deleter<int> d;
49    BOOST_TEST(d.state() == 5);
50    {
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);
54    }
55    BOOST_TEST(d.state() == 5);
56    }
57    {
58    //Unbounded array unique_ptr
59    def_constr_deleter<int[]> d;
60    BOOST_TEST(d.state() == 5);
61    {
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);
65    }
66    BOOST_TEST(d.state() == 5);
67    }
68    {
69    //Bounded array unique_ptr
70    def_constr_deleter<int[2]> d;
71    BOOST_TEST(d.state() == 5);
72    {
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);
76    }
77    BOOST_TEST(d.state() == 5);
78    }
79 }
80 
81 }  //namespace unique_ptr_dtor_null{
82 
83 ////////////////////////////////
84 //   unique_ptr_ctor_default_delreq
85 ////////////////////////////////
86 
87 namespace unique_ptr_ctor_default_delreq{
88 
89 // default unique_ptr ctor should only require default deleter ctor
90 
test()91 void test()
92 {
93    //Single unique_ptr
94    {
95    bml::unique_ptr<int> p;
96    BOOST_TEST(p.get() == 0);
97    }
98    {
99    bml::unique_ptr<int, def_constr_deleter<int> > p;
100    BOOST_TEST(p.get() == 0);
101    BOOST_TEST(p.get_deleter().state() == 5);
102    }
103    //Unbounded array unique_ptr
104    {
105    bml::unique_ptr<int[]> p;
106    BOOST_TEST(p.get() == 0);
107    }
108    {
109    bml::unique_ptr<int[], def_constr_deleter<int[]> > p;
110    BOOST_TEST(p.get() == 0);
111    BOOST_TEST(p.get_deleter().state() == 5);
112    }
113 
114    //Unbounded array unique_ptr
115    {
116    bml::unique_ptr<int[]> p;
117    BOOST_TEST(p.get() == 0);
118    }
119    {
120    bml::unique_ptr<int[], def_constr_deleter<int[]> > p;
121    BOOST_TEST(p.get() == 0);
122    BOOST_TEST(p.get_deleter().state() == 5);
123    }
124 
125    //Unbounded array unique_ptr
126    {
127    bml::unique_ptr<int[2]> p;
128    BOOST_TEST(p.get() == 0);
129    }
130    {
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);
134    }
135 }
136 
137 }  //namespace unique_ptr_ctor_default_delreq{
138 
139 ////////////////////////////////
140 //   unique_ptr_ctor_default_nocomplete
141 ////////////////////////////////
142 
143 namespace unique_ptr_ctor_default_nocomplete{
144 
145 // default unique_ptr ctor shouldn't require complete type
146 
test()147 void test()
148 {
149    //Single unique_ptr
150    reset_counters();
151    {
152    J<I> s;
153    BOOST_TEST(s.get() == 0);
154    }
155    check(0);
156    {
157    J<I, def_constr_deleter<I> > s;
158    BOOST_TEST(s.get() == 0);
159    BOOST_TEST(s.get_deleter().state() == 5);
160    }
161    check(0);
162    //Unbounded array unique_ptr
163    reset_counters();
164    {
165    J<I[]> s;
166    BOOST_TEST(s.get() == 0);
167    }
168    check(0);
169    {
170    J<I[], def_constr_deleter<I[]> > s;
171    BOOST_TEST(s.get() == 0);
172    BOOST_TEST(s.get_deleter().state() == 5);
173    }
174    check(0);
175 
176    //Bounded array unique_ptr
177    reset_counters();
178    {
179    J<I[2]> s;
180    BOOST_TEST(s.get() == 0);
181    }
182    check(0);
183    {
184    J<I[2], def_constr_deleter<I[2]> > s;
185    BOOST_TEST(s.get() == 0);
186    BOOST_TEST(s.get_deleter().state() == 5);
187    }
188    check(0);
189 }
190 
191 }  //namespace unique_ptr_ctor_default_nocomplete{
192 
193 ////////////////////////////////
194 //   unique_ptr_ctor_pointer_delreq
195 ////////////////////////////////
196 
197 namespace unique_ptr_ctor_pointer_delreq{
198 
199 // unique_ptr(pointer) ctor should only require default deleter ctor
200 
test()201 void test()
202 {
203    //Single unique_ptr
204    reset_counters();
205    {
206    A* p = new A;
207    BOOST_TEST(A::count == 1);
208    bml::unique_ptr<A> s(p);
209    BOOST_TEST(s.get() == p);
210    }
211    BOOST_TEST(A::count == 0);
212    {
213    A* p = new A;
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);
218    }
219    BOOST_TEST(A::count == 0);
220    //Unbounded array unique_ptr
221    reset_counters();
222    {
223    A* p = new A[2];
224    BOOST_TEST(A::count == 2);
225    bml::unique_ptr<A[]> s(p);
226    BOOST_TEST(s.get() == p);
227    }
228    BOOST_TEST(A::count == 0);
229    {
230    A* p = new A[2];
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);
235    }
236    BOOST_TEST(A::count == 0);
237    //Bounded array unique_ptr
238    reset_counters();
239    {
240    A* p = new A[2];
241    BOOST_TEST(A::count == 2);
242    bml::unique_ptr<A[2]> s(p);
243    BOOST_TEST(s.get() == p);
244    }
245    BOOST_TEST(A::count == 0);
246    {
247    A* p = new A[2];
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);
252    }
253    BOOST_TEST(A::count == 0);
254 }
255 
256 }  //namespace unique_ptr_ctor_pointer_delreq{
257 
258 ////////////////////////////////
259 //   unique_ptr_ctor_pointer_nocomplete
260 ////////////////////////////////
261 
262 namespace unique_ptr_ctor_pointer_nocomplete{
263 
264 // unique_ptr(pointer) ctor shouldn't require complete type
265 
test()266 void test()
267 {
268    //Single unique_ptr
269    reset_counters();
270    {
271    I* p = get();
272    check(1);
273    J<I> s(p);
274    BOOST_TEST(s.get() == p);
275    }
276    check(0);
277    {
278    I* p = get();
279    check(1);
280    J<I, def_constr_deleter<I> > s(p);
281    BOOST_TEST(s.get() == p);
282    BOOST_TEST(s.get_deleter().state() == 5);
283    }
284    check(0);
285    //Unbounded array unique_ptr
286    reset_counters();
287    {
288    I* p = get_array(2);
289    check(2);
290    J<I[]> s(p);
291    BOOST_TEST(s.get() == p);
292    }
293    check(0);
294    {
295    I* p = get_array(2);
296    check(2);
297    J<I[], def_constr_deleter<I[]> > s(p);
298    BOOST_TEST(s.get() == p);
299    BOOST_TEST(s.get_deleter().state() == 5);
300    }
301    check(0);
302    //Bounded array unique_ptr
303    reset_counters();
304    {
305    I* p = get_array(2);
306    check(2);
307    J<I[]> s(p);
308    BOOST_TEST(s.get() == p);
309    }
310    check(0);
311    {
312    I* p = get_array(2);
313    check(2);
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);
317    }
318    check(0);
319 }
320 
321 }  //namespace unique_ptr_ctor_pointer_nocomplete{
322 
323 ////////////////////////////////
324 //   unique_ptr_ctor_pointer_convert
325 ////////////////////////////////
326 
327 namespace unique_ptr_ctor_pointer_convert{
328 
329 // unique_ptr(pointer) ctor should work with derived pointers
330 // or same types (cv aside) for unique_ptr<arrays>
331 
test()332 void test()
333 {
334    //Single unique_ptr
335    reset_counters();
336    {
337    B* p = new B;
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);
342    }
343    BOOST_TEST(A::count == 0);
344    BOOST_TEST(B::count == 0);
345    {
346    B* p = new B;
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);
352    }
353    BOOST_TEST(A::count == 0);
354    BOOST_TEST(B::count == 0);
355    //Unbounded array unique_ptr
356    reset_counters();
357    {
358    A* p = new A[2];
359    BOOST_TEST(A::count == 2);
360    bml::unique_ptr<const A[]> s(p);
361    BOOST_TEST(s.get() == p);
362    }
363    BOOST_TEST(A::count == 0);
364    {
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);
370    }
371    BOOST_TEST(A::count == 0);
372    //Bounded array unique_ptr
373    reset_counters();
374    {
375    A* p = new A[2];
376    BOOST_TEST(A::count == 2);
377    bml::unique_ptr<const A[2]> s(p);
378    BOOST_TEST(s.get() == p);
379    }
380    BOOST_TEST(A::count == 0);
381    {
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);
387    }
388    BOOST_TEST(A::count == 0);
389 }
390 
391 }  //namespace unique_ptr_ctor_pointer_convert{
392 
393 ////////////////////////////////
394 //   unique_ptr_ctor_pointer_deleter_movedel
395 ////////////////////////////////
396 
397 namespace unique_ptr_ctor_pointer_deleter_movedel{
398 
399 // test move ctor.  Should only require a MoveConstructible deleter, or if
400 //    deleter is a reference, not even that.
401 
402 // unique_ptr(pointer, deleter()) only requires MoveConstructible deleter
403 
test()404 void test()
405 {
406    //Single unique_ptr
407    reset_counters();
408    {
409    A* p = new A;
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);
418    }
419    BOOST_TEST(A::count == 0);
420    //Unbounded array unique_ptr
421    reset_counters();
422    {
423    A* p = new A[2];
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);
432    }
433    BOOST_TEST(A::count == 0);
434    //Bounded array unique_ptr
435    reset_counters();
436    {
437    A* p = new A[2];
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);
446    }
447    BOOST_TEST(A::count == 0);
448 }
449 
450 }  //namespace unique_ptr_ctor_pointer_deleter_movedel{
451 
452 ////////////////////////////////
453 //   unique_ptr_ctor_pointer_deleter_copydel
454 ////////////////////////////////
455 
456 namespace unique_ptr_ctor_pointer_deleter_copydel{
457 
458 // unique_ptr(pointer, d) requires CopyConstructible deleter
459 
test()460 void test()
461 {
462    //Single unique_ptr
463    reset_counters();
464    {
465    A* p = new A;
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);
471    d.set_state(6);
472    BOOST_TEST(s.get_deleter().state() == 5);
473    }
474    BOOST_TEST(A::count == 0);
475    //Unbounded array unique_ptr
476    reset_counters();
477    {
478    A* p = new A[2];
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);
484    d.set_state(6);
485    BOOST_TEST(s.get_deleter().state() == 5);
486    }
487    BOOST_TEST(A::count == 0);
488    //Bounded array unique_ptr
489    reset_counters();
490    {
491    A* p = new A[2];
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);
497    d.set_state(6);
498    BOOST_TEST(s.get_deleter().state() == 5);
499    }
500    BOOST_TEST(A::count == 0);
501 }
502 
503 }  //namespace unique_ptr_ctor_pointer_deleter_copydel{
504 
505 ////////////////////////////////
506 //   unique_ptr_ctor_pointer_deleter_dfctrdelref
507 ////////////////////////////////
508 
509 namespace unique_ptr_ctor_pointer_deleter_dfctrdelref{
510 
511 // unique_ptr<T, D&>(pointer, d) does not requires CopyConstructible deleter
512 
test()513 void test()
514 {
515    //Single unique_ptr
516    reset_counters();
517    {
518    A* p = new A;
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);
524    d.set_state(6);
525    BOOST_TEST(s.get_deleter().state() == 6);
526    }
527    BOOST_TEST(A::count == 0);
528    //Unbounded array unique_ptr
529    reset_counters();
530    {
531    A* p = new A[2];
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);
537    d.set_state(6);
538    BOOST_TEST(s.get_deleter().state() == 6);
539    }
540    BOOST_TEST(A::count == 0);
541    //Bounded array unique_ptr
542    reset_counters();
543    {
544    A* p = new A[2];
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);
550    d.set_state(6);
551    BOOST_TEST(s.get_deleter().state() == 6);
552    }
553    BOOST_TEST(A::count == 0);
554 }
555 
556 }  //namespace unique_ptr_ctor_pointer_deleter_dfctrdelref{
557 
558 ////////////////////////////////
559 //   unique_ptr_ctor_pointer_deleter_dfctrdelconstref
560 ////////////////////////////////
561 
562 namespace unique_ptr_ctor_pointer_deleter_dfctrdelconstref{
563 
564 // unique_ptr<T, const D&>(pointer, d) does not requires CopyConstructible deleter
565 
test()566 void test()
567 {
568    //Single unique_ptr
569    reset_counters();
570    {
571    A* p = new A;
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);
577    }
578    BOOST_TEST(A::count == 0);
579    //Unbounded array unique_ptr
580    reset_counters();
581    {
582    A* p = new A[2];
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);
588    }
589    BOOST_TEST(A::count == 0);
590    //Bounded array unique_ptr
591    reset_counters();
592    {
593    A* p = new A[2];
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);
599    }
600    BOOST_TEST(A::count == 0);
601 }
602 
603 }  //namespace unique_ptr_ctor_pointer_deleter_dfctrdelconstref{
604 
605 ////////////////////////////////
606 //   unique_ptr_ctor_pointer_deleter_convert
607 ////////////////////////////////
608 
609 namespace unique_ptr_ctor_pointer_deleter_convert{
610 
611 // unique_ptr(pointer, deleter) should work with derived pointers
612 // or same (cv aside) types for array unique_ptrs
613 
test()614 void test()
615 {
616    //Single unique_ptr
617    reset_counters();
618    {
619    B* p = new B;
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);
625    }
626    BOOST_TEST(A::count == 0);
627    BOOST_TEST(B::count == 0);
628    //Unbounded array unique_ptr
629    reset_counters();
630    {
631    A* p = new A[2];
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);
636    }
637    BOOST_TEST(A::count == 0);
638    BOOST_TEST(B::count == 0);
639    //Bounded array unique_ptr
640    reset_counters();
641    {
642    A* p = new A[2];
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);
647    }
648    BOOST_TEST(A::count == 0);
649    BOOST_TEST(B::count == 0);
650 }
651 
652 }  //namespace unique_ptr_ctor_pointer_deleter_convert{
653 
654 ////////////////////////////////
655 //   unique_ptr_ctor_pointer_deleter_void
656 ////////////////////////////////
657 
658 namespace unique_ptr_ctor_pointer_deleter_void{
659 
660 // unique_ptr(pointer, deleter) should work with function pointers
661 // unique_ptr<void> should work
662 
663 bool my_free_called = false;
664 
my_free(void *)665 void my_free(void*)
666 {
667     my_free_called = true;
668 }
669 
test()670 void test()
671 {
672    {
673    int i = 0;
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);
678    }
679    BOOST_TEST(my_free_called);
680 }
681 
682 }  //namespace unique_ptr_ctor_pointer_deleter_void{
683 
684 ////////////////////////////////
685 //   return_unique_single_conversion
686 ////////////////////////////////
687 
688 namespace return_unique_single_conversion{
689 
690 template<class T>
make_unique_ptr_of_t()691 bml::unique_ptr<T> make_unique_ptr_of_t()
692 {
693    return bml::unique_ptr<T>(new T);
694 }
695 
696 template<class T>
return_const_unique_of_t()697 bml::unique_ptr<T const> return_const_unique_of_t()
698 {
699    return bml::unique_ptr<T const> (make_unique_ptr_of_t<T>());
700 }
701 
test()702 void test()
703 {
704    reset_counters();
705    BOOST_TEST(A::count == 0);
706    {
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);
710    }
711    BOOST_TEST(A::count == 0);
712    {
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);
716    }
717    BOOST_TEST(A::count == 0);
718 }
719 
720 }  //namespace return_unique_single_conversion{
721 
722 
723 ////////////////////////////////
724 //   return_unique_array_conversion
725 ////////////////////////////////
726 
727 namespace return_unique_array_conversion{
728 
729 template<class T>
return_unique_array_of_t(std::size_t n)730 bml::unique_ptr<T[]> return_unique_array_of_t(std::size_t n)
731 {
732    return bml::unique_ptr<T[]>(new T[n]);
733 }
734 
735 template<class T>
return_const_array_of_t(std::size_t n)736 bml::unique_ptr<const T[]> return_const_array_of_t(std::size_t n)
737 {
738    return bml::unique_ptr<const T[]>(return_unique_array_of_t<T>(n));
739 }
740 
741 template<class T>
return_unique_array_of_t_2()742 bml::unique_ptr<T[2]> return_unique_array_of_t_2()
743 {
744    return bml::unique_ptr<T[2]>(new T[2]);
745 }
746 
747 template<class T>
return_const_array_of_t_2()748 bml::unique_ptr<const T[2]> return_const_array_of_t_2()
749 {
750    return bml::unique_ptr<const T[2]>(return_unique_array_of_t_2<T>());
751 }
752 
test()753 void test()
754 {
755    reset_counters();
756    BOOST_TEST(A::count == 0);
757    {
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);
761    }
762    BOOST_TEST(A::count == 0);
763    {
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);
767    }
768    BOOST_TEST(A::count == 0);
769    {
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);
773    }
774    BOOST_TEST(A::count == 0);
775    {
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);
779    }
780    BOOST_TEST(A::count == 0);
781 }
782 
783 }  //namespace return_unique_array_conversion{
784 
785 ////////////////////////////////
786 //             main
787 ////////////////////////////////
main()788 int main()
789 {
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();
805 
806    //Test results
807    return boost::report_errors();
808 
809 }
810 
811 #include "unique_ptr_test_utils_end.hpp"
812