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