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/core/ignore_unused.hpp>
15 #include <boost/move/unique_ptr.hpp>
16 #include <boost/static_assert.hpp>
17 #include <boost/move/adl_move_swap.hpp>
18 #include <boost/core/lightweight_test.hpp>
19
20 //////////////////////////////////////////////
21 //
22 // The initial implementation of these tests
23 // was written by Howard Hinnant.
24 //
25 // These test were later refactored grouping
26 // and porting them to Boost.Move.
27 //
28 // Many thanks to Howard for releasing his C++03
29 // unique_ptr implementation with such detailed
30 // test cases.
31 //
32 //////////////////////////////////////////////
33
34 #include "unique_ptr_test_utils_beg.hpp"
35
36 namespace bml = ::boost::movelib;
37
38 ////////////////////////////////
39 // unique_ptr_modifiers_release
40 ////////////////////////////////
41
42 namespace unique_ptr_modifiers_release{
43
test()44 void test()
45 {
46 //Single unique_ptr
47 {
48 bml::unique_ptr<int> p(new int(3));
49 int* i = p.get();
50 int* j = p.release();
51 BOOST_TEST(p.get() == 0);
52 BOOST_TEST(i == j);
53 p.reset(j);
54 }
55 //Unbounded array unique_ptr
56 {
57 bml::unique_ptr<int[]> p(new int[2]);
58 int* i = p.get();
59 int* j = p.release();
60 BOOST_TEST(p.get() == 0);
61 BOOST_TEST(i == j);
62 p.reset(j);
63 }
64 //Bounded array unique_ptr
65 {
66 bml::unique_ptr<int[2]> p(new int[2]);
67 int* i = p.get();
68 int* j = p.release();
69 BOOST_TEST(p.get() == 0);
70 BOOST_TEST(i == j);
71 p.reset(j);
72 }
73 }
74
75 } //namespace unique_ptr_modifiers_release{
76
77 ////////////////////////////////
78 // unique_ptr_modifiers_reset
79 ////////////////////////////////
80
81 namespace unique_ptr_modifiers_reset{
82
test()83 void test()
84 {
85 //Single unique_ptr
86 {
87 reset_counters();
88 { //reset()
89 bml::unique_ptr<A> p(new A);
90 BOOST_TEST(A::count == 1);
91 A* i = p.get();
92 ::boost::ignore_unused(i);
93 p.reset();
94 BOOST_TEST(A::count == 0);
95 BOOST_TEST(p.get() == 0);
96 }
97 BOOST_TEST(A::count == 0);
98 { //reset(p)
99 bml::unique_ptr<A> p(new A);
100 BOOST_TEST(A::count == 1);
101 A* i = p.get();
102 ::boost::ignore_unused(i);
103 p.reset(new A);
104 BOOST_TEST(A::count == 1);
105 }
106 BOOST_TEST(A::count == 0);
107 { //reset(0)
108 bml::unique_ptr<A> p(new A);
109 BOOST_TEST(A::count == 1);
110 A* i = p.get();
111 ::boost::ignore_unused(i);
112 p.reset(0);
113 BOOST_TEST(A::count == 0);
114 BOOST_TEST(p.get() == 0);
115 }
116 BOOST_TEST(A::count == 0);
117 }
118 //Unbounded array unique_ptr
119 {
120 reset_counters();
121 { //reset()
122 bml::unique_ptr<A[]> p(new A[2]);
123 BOOST_TEST(A::count == 2);
124 A* i = p.get();
125 ::boost::ignore_unused(i);
126 p.reset();
127 BOOST_TEST(A::count == 0);
128 BOOST_TEST(p.get() == 0);
129 }
130 BOOST_TEST(A::count == 0);
131 { //reset(p)
132 bml::unique_ptr<A[]> p(new A[2]);
133 BOOST_TEST(A::count == 2);
134 A* i = p.get();
135 ::boost::ignore_unused(i);
136 p.reset(new A[3]);
137 BOOST_TEST(A::count == 3);
138 }
139 BOOST_TEST(A::count == 0);
140 { //reset(0)
141 bml::unique_ptr<A[]> p(new A[2]);
142 BOOST_TEST(A::count == 2);
143 A* i = p.get();
144 ::boost::ignore_unused(i);
145 p.reset(0);
146 BOOST_TEST(A::count == 0);
147 BOOST_TEST(p.get() == 0);
148 }
149 BOOST_TEST(A::count == 0);
150 }
151 {
152 //Bounded array unique_ptr
153 reset_counters();
154 { //reset()
155 bml::unique_ptr<A[2]> p(new A[2]);
156 BOOST_TEST(A::count == 2);
157 A* i = p.get();
158 ::boost::ignore_unused(i);
159 p.reset();
160 BOOST_TEST(A::count == 0);
161 BOOST_TEST(p.get() == 0);
162 }
163 BOOST_TEST(A::count == 0);
164 { //reset(p)
165 bml::unique_ptr<A[2]> p(new A[2]);
166 BOOST_TEST(A::count == 2);
167 A* i = p.get();
168 ::boost::ignore_unused(i);
169 p.reset(new A[3]);
170 BOOST_TEST(A::count == 3);
171 }
172 BOOST_TEST(A::count == 0);
173 { //reset(0)
174 bml::unique_ptr<A[2]> p(new A[2]);
175 BOOST_TEST(A::count == 2);
176 A* i = p.get();
177 ::boost::ignore_unused(i);
178 p.reset(0);
179 BOOST_TEST(A::count == 0);
180 BOOST_TEST(p.get() == 0);
181 }
182 BOOST_TEST(A::count == 0);
183 }
184 }
185
186 } //namespace unique_ptr_modifiers_reset{
187
188 ////////////////////////////////
189 // unique_ptr_modifiers_reset_convert
190 ////////////////////////////////
191
192 namespace unique_ptr_modifiers_reset_convert{
193
test()194 void test()
195 {
196 //Single unique_ptr
197 reset_counters();
198 {
199 bml::unique_ptr<A> p(new A);
200 BOOST_TEST(A::count == 1);
201 BOOST_TEST(B::count == 0);
202 A* i = p.get();
203 ::boost::ignore_unused(i);
204 p.reset(new B);
205 BOOST_TEST(A::count == 1);
206 BOOST_TEST(B::count == 1);
207 }
208 BOOST_TEST(A::count == 0);
209 BOOST_TEST(B::count == 0);
210 {
211 bml::unique_ptr<A> p(new B);
212 BOOST_TEST(A::count == 1);
213 BOOST_TEST(B::count == 1);
214 A* i = p.get();
215 ::boost::ignore_unused(i);
216 p.reset(new B);
217 BOOST_TEST(A::count == 1);
218 BOOST_TEST(B::count == 1);
219 }
220 BOOST_TEST(A::count == 0);
221 BOOST_TEST(B::count == 0);
222 //Unbounded array unique_ptr
223 reset_counters();
224 {
225 bml::unique_ptr<const volatile A[2]> p(new const A[2]);
226 BOOST_TEST(A::count == 2);
227 const volatile A* i = p.get();
228 ::boost::ignore_unused(i);
229 p.reset(new volatile A[3]);
230 BOOST_TEST(A::count == 3);
231 }
232 BOOST_TEST(A::count == 0);
233 {
234 bml::unique_ptr<const A[2]> p(new A[2]);
235 BOOST_TEST(A::count == 2);
236 const A* i = p.get();
237 ::boost::ignore_unused(i);
238 p.reset(new const A[3]);
239 BOOST_TEST(A::count == 3);
240 }
241 BOOST_TEST(A::count == 0);
242 //Bounded array unique_ptr
243 reset_counters();
244 {
245 bml::unique_ptr<const volatile A[2]> p(new const A[2]);
246 BOOST_TEST(A::count == 2);
247 const volatile A* i = p.get();
248 ::boost::ignore_unused(i);
249 p.reset(new volatile A[3]);
250 BOOST_TEST(A::count == 3);
251 }
252 BOOST_TEST(A::count == 0);
253 {
254 bml::unique_ptr<const A[2]> p(new A[2]);
255 BOOST_TEST(A::count == 2);
256 const A* i = p.get();
257 ::boost::ignore_unused(i);
258 p.reset(new const A[3]);
259 BOOST_TEST(A::count == 3);
260 }
261 BOOST_TEST(A::count == 0);
262 }
263
264 } //unique_ptr_modifiers_reset_convert
265
266
267 ////////////////////////////////
268 // unique_ptr_modifiers
269 ////////////////////////////////
270
271 namespace unique_ptr_modifiers_swap{
272
273 // test swap
274
test()275 void test()
276 {
277 //Single unique_ptr
278 reset_counters();
279 {
280 A* p1 = new A(1);
281 move_constr_deleter<A> d1(1);
282 bml::unique_ptr<A, move_constr_deleter<A> > s1(p1, ::boost::move(d1));
283 A* p2 = new A(2);
284 move_constr_deleter<A> d2(2);
285 bml::unique_ptr<A, move_constr_deleter<A> > s2(p2, ::boost::move(d2));
286 BOOST_TEST(s1.get() == p1);
287 BOOST_TEST(*s1 == A(1));
288 BOOST_TEST(s1.get_deleter().state() == 1);
289 BOOST_TEST(s2.get() == p2);
290 BOOST_TEST(*s2 == A(2));
291 BOOST_TEST(s2.get_deleter().state() == 2);
292 boost::adl_move_swap(s1, s2);
293 BOOST_TEST(s1.get() == p2);
294 BOOST_TEST(*s1 == A(2));
295 BOOST_TEST(s1.get_deleter().state() == 2);
296 BOOST_TEST(s2.get() == p1);
297 BOOST_TEST(*s2 == A(1));
298 BOOST_TEST(s2.get_deleter().state() == 1);
299 }
300 //Unbounded array unique_ptr
301 reset_counters();
302 {
303 A* p1 = new A[2];
304 p1[0].set(1);
305 p1[1].set(2);
306 move_constr_deleter<A[]> d1(1);
307 bml::unique_ptr<A[], move_constr_deleter<A[]> > s1(p1, ::boost::move(d1));
308 A* p2 = new A[2];
309 p2[0].set(3);
310 p2[1].set(4);
311 move_constr_deleter<A[]> d2(2);
312 bml::unique_ptr<A[], move_constr_deleter<A[]> > s2(p2, ::boost::move(d2));
313 BOOST_TEST(s1.get() == p1);
314 BOOST_TEST(s1[0] == A(1));
315 BOOST_TEST(s1[1] == A(2));
316 BOOST_TEST(s1.get_deleter().state() == 1);
317 BOOST_TEST(s2.get() == p2);
318 BOOST_TEST(s2[0] == A(3));
319 BOOST_TEST(s2[1] == A(4));
320 BOOST_TEST(s2.get_deleter().state() == 2);
321 swap(s1, s2);
322 BOOST_TEST(s1.get() == p2);
323 BOOST_TEST(s1[0] == A(3));
324 BOOST_TEST(s1[1] == A(4));
325 BOOST_TEST(s1.get_deleter().state() == 2);
326 BOOST_TEST(s2.get() == p1);
327 BOOST_TEST(s2[0] == A(1));
328 BOOST_TEST(s2[1] == A(2));
329 BOOST_TEST(s2.get_deleter().state() == 1);
330 }
331 //Bounded array unique_ptr
332 reset_counters();
333 {
334 A* p1 = new A[2];
335 p1[0].set(1);
336 p1[1].set(2);
337 move_constr_deleter<A[2]> d1(1);
338 bml::unique_ptr<A[2], move_constr_deleter<A[2]> > s1(p1, ::boost::move(d1));
339 A* p2 = new A[2];
340 p2[0].set(3);
341 p2[1].set(4);
342 move_constr_deleter<A[2]> d2(2);
343 bml::unique_ptr<A[2], move_constr_deleter<A[2]> > s2(p2, ::boost::move(d2));
344 BOOST_TEST(s1.get() == p1);
345 BOOST_TEST(s1[0] == A(1));
346 BOOST_TEST(s1[1] == A(2));
347 BOOST_TEST(s1.get_deleter().state() == 1);
348 BOOST_TEST(s2.get() == p2);
349 BOOST_TEST(s2[0] == A(3));
350 BOOST_TEST(s2[1] == A(4));
351 BOOST_TEST(s2.get_deleter().state() == 2);
352 swap(s1, s2);
353 BOOST_TEST(s1.get() == p2);
354 BOOST_TEST(s1[0] == A(3));
355 BOOST_TEST(s1[1] == A(4));
356 BOOST_TEST(s1.get_deleter().state() == 2);
357 BOOST_TEST(s2.get() == p1);
358 BOOST_TEST(s2[0] == A(1));
359 BOOST_TEST(s2[1] == A(2));
360 BOOST_TEST(s2.get_deleter().state() == 1);
361 }
362 }
363
364 } //namespace unique_ptr_modifiers_swap{
365
366 ////////////////////////////////
367 // main
368 ////////////////////////////////
main()369 int main()
370 {
371 //Modifiers
372 unique_ptr_modifiers_release::test();
373 unique_ptr_modifiers_reset::test();
374 unique_ptr_modifiers_reset_convert::test();
375 unique_ptr_modifiers_swap::test();
376
377 //Test results
378 return boost::report_errors();
379
380 }
381
382 #include "unique_ptr_test_utils_end.hpp"
383