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