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_asgn_move_convert_defdel
38 ////////////////////////////////
39 namespace unique_ptr_asgn_move_convert_defdel {
40 
test()41 void 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 
104 namespace unique_ptr_asgn_move_convert_movedel{
105 
test()106 void 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 
179 namespace unique_ptr_asgn_move_convert_copydelref{
180 
181 // test converting move assignment with reference deleters
182 
test()183 void 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 ////////////////////////////////
258 namespace unique_ptr_asgn_move_defdel {
259 
test()260 void 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 ////////////////////////////////
309 namespace unique_ptr_asgn_move_movedel {
310 
test()311 void 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 ////////////////////////////////
368 namespace unique_ptr_asgn_move_copydelref {
369 
test()370 void 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 ////////////////////////////////
main()430 int 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"
445