1 | //////////////////////////////////////// |
2 | // |
3 | // (C) Copyright Ion Gaztanaga 2006. Distributed under the Boost |
4 | // Software License, Version 1.0. (See accompanying file |
5 | // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
6 | // |
7 | // See http://www.boost.org/libs/container for documentation. |
8 | // |
9 | //////////////////////////////////////// |
10 | |
11 | #ifndef BOOST_CONTAINER_TEST_LIST_TEST_HEADER |
12 | #define |
13 | |
14 | #include <boost/container/detail/config_begin.hpp> |
15 | #include <boost/container/detail/iterator.hpp> |
16 | #include "check_equal_containers.hpp" |
17 | #include "print_container.hpp" |
18 | #include "input_from_forward_iterator.hpp" |
19 | #include <boost/move/utility_core.hpp> |
20 | #include <boost/move/iterator.hpp> |
21 | #include <boost/move/make_unique.hpp> |
22 | |
23 | #include <list> |
24 | #include <functional> //std::greater |
25 | #include <cstddef> //std::size_t |
26 | |
27 | namespace boost{ |
28 | namespace container { |
29 | namespace test{ |
30 | |
31 | template<class V1, class V2> |
32 | bool list_copyable_only(V1 &, V2 &, boost::container::dtl::false_type) |
33 | { |
34 | return true; |
35 | } |
36 | |
37 | //Function to check if both sets are equal |
38 | template<class V1, class V2> |
39 | bool list_copyable_only(V1 &boostlist, V2 &stdlist, boost::container::dtl::true_type) |
40 | { |
41 | typedef typename V1::value_type IntType; |
42 | boostlist.insert(boostlist.end(), 50u, IntType(1)); |
43 | stdlist.insert(stdlist.end(), 50u, 1); |
44 | if(!test::CheckEqualContainers(boostlist, stdlist)) return false; |
45 | |
46 | { |
47 | IntType move_me(1); |
48 | boostlist.insert(boostlist.begin(), 50u, boost::move(move_me)); |
49 | stdlist.insert(stdlist.begin(), 50u, 1); |
50 | if(!test::CheckEqualContainers(boostlist, stdlist)) return false; |
51 | } |
52 | { |
53 | IntType move_me(2); |
54 | boostlist.assign(boostlist.size()/2, boost::move(move_me)); |
55 | stdlist.assign(stdlist.size()/2, 2); |
56 | if(!test::CheckEqualContainers(boostlist, stdlist)) return false; |
57 | } |
58 | { |
59 | IntType move_me(3); |
60 | boostlist.assign(boostlist.size()*3-1, boost::move(move_me)); |
61 | stdlist.assign(stdlist.size()*3-1, 3); |
62 | if(!test::CheckEqualContainers(boostlist, stdlist)) return false; |
63 | } |
64 | |
65 | { |
66 | IntType copy_me(3); |
67 | const IntType ccopy_me(3); |
68 | boostlist.push_front(copy_me); |
69 | stdlist.push_front(int(3)); |
70 | boostlist.push_front(ccopy_me); |
71 | stdlist.push_front(int(3)); |
72 | if(!test::CheckEqualContainers(boostlist, stdlist)) return false; |
73 | } |
74 | { //List(const List &) |
75 | ::boost::movelib::unique_ptr<V1> const pv1 = ::boost::movelib::make_unique<V1>(boostlist); |
76 | ::boost::movelib::unique_ptr<V2> const pv2 = ::boost::movelib::make_unique<V2>(stdlist); |
77 | |
78 | V1 &v1 = *pv1; |
79 | V2 &v2 = *pv2; |
80 | |
81 | boostlist.clear(); |
82 | stdlist.clear(); |
83 | boostlist.assign(v1.begin(), v1.end()); |
84 | stdlist.assign(v2.begin(), v2.end()); |
85 | if(!test::CheckEqualContainers(boostlist, stdlist)) return 1; |
86 | } |
87 | { //List(const List &, alloc) |
88 | ::boost::movelib::unique_ptr<V1> const pv1 = ::boost::movelib::make_unique<V1>(boostlist, typename V1::allocator_type()); |
89 | ::boost::movelib::unique_ptr<V2> const pv2 = ::boost::movelib::make_unique<V2>(stdlist); |
90 | |
91 | V1 &v1 = *pv1; |
92 | V2 &v2 = *pv2; |
93 | |
94 | boostlist.clear(); |
95 | stdlist.clear(); |
96 | boostlist.assign(v1.begin(), v1.end()); |
97 | stdlist.assign(v2.begin(), v2.end()); |
98 | if(!test::CheckEqualContainers(boostlist, stdlist)) return 1; |
99 | } |
100 | |
101 | return true; |
102 | } |
103 | |
104 | template<bool DoublyLinked> |
105 | struct list_push_data_function |
106 | { |
107 | template<class MyBoostList, class MyStdList> |
108 | static int execute(std::size_t max, MyBoostList &boostlist, MyStdList &stdlist) |
109 | { |
110 | typedef typename MyBoostList::value_type IntType; |
111 | for(std::size_t i = 0; i < max; ++i){ |
112 | IntType move_me((int)i); |
113 | boostlist.push_back(boost::move(move_me)); |
114 | stdlist.push_back((int)i); |
115 | boostlist.push_front(IntType(int(i))); |
116 | stdlist.push_front(int(i)); |
117 | } |
118 | if(!CheckEqualContainers(boostlist, stdlist)) |
119 | return 1; |
120 | return 0; |
121 | } |
122 | }; |
123 | |
124 | template<> |
125 | struct list_push_data_function<false> |
126 | { |
127 | template<class MyBoostList, class MyStdList> |
128 | static int execute(std::size_t max, MyBoostList &boostlist, MyStdList &stdlist) |
129 | { |
130 | typedef typename MyBoostList::value_type IntType; |
131 | for(std::size_t i = 0; i < max; ++i){ |
132 | IntType move_me((int)i); |
133 | boostlist.push_front(boost::move(move_me)); |
134 | stdlist.push_front((int)i); |
135 | boostlist.push_front(IntType(int(i))); |
136 | stdlist.push_front(int(i)); |
137 | } |
138 | if(!CheckEqualContainers(boostlist, stdlist)) |
139 | return 1; |
140 | return 0; |
141 | } |
142 | }; |
143 | |
144 | template<bool DoublyLinked> |
145 | struct list_pop_back_function |
146 | { |
147 | template<class MyStdList, class MyBoostList> |
148 | static int execute(MyBoostList &boostlist, MyStdList &stdlist) |
149 | { |
150 | boostlist.pop_back(); |
151 | stdlist.pop_back(); |
152 | if(!CheckEqualContainers(boostlist, stdlist)) |
153 | return 1; |
154 | return 0; |
155 | } |
156 | }; |
157 | |
158 | template<> |
159 | struct list_pop_back_function<false> |
160 | { |
161 | template<class MyStdList, class MyBoostList> |
162 | static int execute(MyBoostList &boostlist, MyStdList &stdlist) |
163 | { |
164 | (void)boostlist; (void)stdlist; |
165 | return 0; |
166 | } |
167 | }; |
168 | |
169 | template<class MyBoostList |
170 | ,bool DoublyLinked> |
171 | int list_test (bool copied_allocators_equal = true) |
172 | { |
173 | typedef std::list<int> MyStdList; |
174 | typedef typename MyBoostList::value_type IntType; |
175 | const std::size_t max = 100u; |
176 | typedef list_push_data_function<DoublyLinked> push_data_t; |
177 | |
178 | { //List(n) |
179 | ::boost::movelib::unique_ptr<MyBoostList> const pboostlist = ::boost::movelib::make_unique<MyBoostList>(100u); |
180 | ::boost::movelib::unique_ptr<MyStdList> const pstdlist = ::boost::movelib::make_unique<MyStdList>(args: 100u); |
181 | if(!test::CheckEqualContainers(*pboostlist, *pstdlist)) return 1; |
182 | } |
183 | { //List(n, alloc) |
184 | ::boost::movelib::unique_ptr<MyBoostList> const pboostlist = ::boost::movelib::make_unique<MyBoostList>(100u, typename MyBoostList::allocator_type()); |
185 | ::boost::movelib::unique_ptr<MyStdList> const pstdlist = ::boost::movelib::make_unique<MyStdList>(args: 100u); |
186 | if(!test::CheckEqualContainers(*pboostlist, *pstdlist)) return 1; |
187 | } |
188 | { //List(List &&) |
189 | ::boost::movelib::unique_ptr<MyStdList> const stdlistp = ::boost::movelib::make_unique<MyStdList>(args: 100u); |
190 | ::boost::movelib::unique_ptr<MyBoostList> const boostlistp = ::boost::movelib::make_unique<MyBoostList>(100u); |
191 | ::boost::movelib::unique_ptr<MyBoostList> const boostlistp2 = ::boost::movelib::make_unique<MyBoostList>(::boost::move(*boostlistp)); |
192 | if(!test::CheckEqualContainers(*boostlistp2, *stdlistp)) return 1; |
193 | } |
194 | { //List(List &&, alloc) |
195 | ::boost::movelib::unique_ptr<MyStdList> const stdlistp = ::boost::movelib::make_unique<MyStdList>(args: 100u); |
196 | ::boost::movelib::unique_ptr<MyBoostList> const boostlistp = ::boost::movelib::make_unique<MyBoostList>(100u); |
197 | ::boost::movelib::unique_ptr<MyBoostList> const boostlistp2 = ::boost::movelib::make_unique<MyBoostList> |
198 | (::boost::move(*boostlistp), typename MyBoostList::allocator_type()); |
199 | if(!test::CheckEqualContainers(*boostlistp2, *stdlistp)) return 1; |
200 | } |
201 | { //List operator=(List &&) |
202 | ::boost::movelib::unique_ptr<MyStdList> const stdlistp = ::boost::movelib::make_unique<MyStdList>(args: 100u); |
203 | ::boost::movelib::unique_ptr<MyBoostList> const boostlistp = ::boost::movelib::make_unique<MyBoostList>(100u); |
204 | ::boost::movelib::unique_ptr<MyBoostList> const boostlistp2 = ::boost::movelib::make_unique<MyBoostList>(); |
205 | *boostlistp2 = ::boost::move(*boostlistp); |
206 | if(!test::CheckEqualContainers(*boostlistp2, *stdlistp)) return 1; |
207 | } |
208 | |
209 | ::boost::movelib::unique_ptr<MyBoostList> const pboostlist = ::boost::movelib::make_unique<MyBoostList>(); |
210 | ::boost::movelib::unique_ptr<MyStdList> const pstdlist = ::boost::movelib::make_unique<MyStdList>(); |
211 | |
212 | MyBoostList &boostlist = *pboostlist; |
213 | MyStdList &stdlist = *pstdlist; |
214 | |
215 | if(push_data_t::execute(max, boostlist, stdlist)){ |
216 | return 1; |
217 | } |
218 | |
219 | boostlist.erase(boostlist.begin()++); |
220 | stdlist.erase(position: stdlist.begin()++); |
221 | if(!CheckEqualContainers(boostlist, stdlist)) return 1; |
222 | |
223 | if(list_pop_back_function<DoublyLinked>::execute(boostlist, stdlist)){ |
224 | return 1; |
225 | } |
226 | |
227 | boostlist.pop_front(); |
228 | stdlist.pop_front(); |
229 | if(!CheckEqualContainers(boostlist, stdlist)) return 1; |
230 | |
231 | { |
232 | IntType aux_vect[50]; |
233 | for(int i = 0; i < 50; ++i){ |
234 | IntType move_me(-1); |
235 | aux_vect[i] = boost::move(move_me); |
236 | } |
237 | int aux_vect2[50]; |
238 | for(int i = 0; i < 50; ++i){ |
239 | aux_vect2[i] = -1; |
240 | } |
241 | boostlist.assign(boost::make_move_iterator(&aux_vect[0]) |
242 | ,boost::make_move_iterator(&aux_vect[50])); |
243 | stdlist.assign(first: &aux_vect2[0], last: &aux_vect2[50]); |
244 | if(!CheckEqualContainers(boostlist, stdlist)) return 1; |
245 | |
246 | for(int i = 0; i < 50; ++i){ |
247 | IntType move_me(-1); |
248 | aux_vect[i] = boost::move(move_me); |
249 | } |
250 | |
251 | for(int i = 0; i < 50; ++i){ |
252 | aux_vect2[i] = -1; |
253 | } |
254 | boostlist.assign(boost::make_move_iterator(make_input_from_forward_iterator(&aux_vect[0])) |
255 | ,boost::make_move_iterator(make_input_from_forward_iterator(&aux_vect[50]))); |
256 | stdlist.assign(first: &aux_vect2[0], last: &aux_vect2[50]); |
257 | if(!CheckEqualContainers(boostlist, stdlist)) return 1; |
258 | } |
259 | |
260 | if(copied_allocators_equal){ |
261 | boostlist.sort(); |
262 | stdlist.sort(); |
263 | if(!CheckEqualContainers(boostlist, stdlist)) return 1; |
264 | } |
265 | |
266 | boostlist.reverse(); |
267 | stdlist.reverse(); |
268 | if(!CheckEqualContainers(boostlist, stdlist)) return 1; |
269 | |
270 | boostlist.reverse(); |
271 | stdlist.reverse(); |
272 | if(!CheckEqualContainers(boostlist, stdlist)) return 1; |
273 | |
274 | { |
275 | IntType aux_vect[50]; |
276 | for(int i = 0; i < 50; ++i){ |
277 | IntType move_me(-1); |
278 | aux_vect[i] = boost::move(move_me); |
279 | } |
280 | int aux_vect2[50]; |
281 | for(int i = 0; i < 50; ++i){ |
282 | aux_vect2[i] = -1; |
283 | } |
284 | typename MyBoostList::iterator old_begin = boostlist.begin(); |
285 | typename MyBoostList::iterator it_insert = |
286 | boostlist.insert(boostlist.begin() |
287 | ,boost::make_move_iterator(&aux_vect[0]) |
288 | ,boost::make_move_iterator(&aux_vect[50])); |
289 | if(it_insert != boostlist.begin() || boost::container::iterator_distance(it_insert, old_begin) != 50) |
290 | return 1; |
291 | |
292 | stdlist.insert(position: stdlist.begin(), first: &aux_vect2[0], last: &aux_vect2[50]); |
293 | if(!CheckEqualContainers(boostlist, stdlist)) |
294 | return 1; |
295 | |
296 | for(int i = 0; i < 50; ++i){ |
297 | IntType move_me(-1); |
298 | aux_vect[i] = boost::move(move_me); |
299 | } |
300 | |
301 | for(int i = 0; i < 50; ++i){ |
302 | aux_vect2[i] = -1; |
303 | } |
304 | |
305 | old_begin = boostlist.begin(); |
306 | it_insert = boostlist.insert(boostlist.end() |
307 | ,boost::make_move_iterator(make_input_from_forward_iterator(&aux_vect[0])) |
308 | ,boost::make_move_iterator(make_input_from_forward_iterator(&aux_vect[50]))); |
309 | if(boost::container::iterator_distance(it_insert, boostlist.end()) != 50) |
310 | return 1; |
311 | stdlist.insert(position: stdlist.end(), first: &aux_vect2[0], last: &aux_vect2[50]); |
312 | if(!CheckEqualContainers(boostlist, stdlist)) |
313 | return 1; |
314 | } |
315 | |
316 | boostlist.unique(); |
317 | stdlist.unique(); |
318 | if(!CheckEqualContainers(boostlist, stdlist)) |
319 | return 1; |
320 | |
321 | if(copied_allocators_equal){ |
322 | boostlist.sort(std::greater<IntType>()); |
323 | stdlist.sort(comp: std::greater<int>()); |
324 | if(!CheckEqualContainers(boostlist, stdlist)) |
325 | return 1; |
326 | } |
327 | |
328 | for(std::size_t i = 0; i < max; ++i){ |
329 | IntType new_int((int)i); |
330 | boostlist.insert(boostlist.end(), boost::move(new_int)); |
331 | stdlist.insert(position: stdlist.end(), x: (int)i); |
332 | if(!test::CheckEqualContainers(boostlist, stdlist)) return 1; |
333 | } |
334 | if(!test::CheckEqualContainers(boostlist, stdlist)) return 1; |
335 | |
336 | boostlist.resize(25); |
337 | stdlist.resize(new_size: 25); |
338 | boostlist.resize(50); |
339 | stdlist.resize(new_size: 50); |
340 | boostlist.resize(0); |
341 | stdlist.resize(new_size: 0); |
342 | if(!CheckEqualContainers(boostlist, stdlist)) |
343 | return 1; |
344 | |
345 | //some comparison operators |
346 | if(!(boostlist == boostlist)) |
347 | return 1; |
348 | if(boostlist != boostlist) |
349 | return 1; |
350 | if(boostlist < boostlist) |
351 | return 1; |
352 | if(boostlist > boostlist) |
353 | return 1; |
354 | if(!(boostlist <= boostlist)) |
355 | return 1; |
356 | if(!(boostlist >= boostlist)) |
357 | return 1; |
358 | |
359 | if(push_data_t::execute(max, boostlist, stdlist)){ |
360 | return 1; |
361 | } |
362 | { |
363 | MyBoostList otherboostlist(boostlist.get_allocator()); |
364 | MyStdList otherstdlist; |
365 | |
366 | std::size_t listsize = boostlist.size(); |
367 | |
368 | if(push_data_t::execute(listsize, boostlist, stdlist)){ |
369 | return 1; |
370 | } |
371 | |
372 | if(copied_allocators_equal){ |
373 | boostlist.splice(boostlist.begin(), otherboostlist); |
374 | stdlist.splice(position: stdlist.begin(), x&: otherstdlist); |
375 | if(!CheckEqualContainers(boostlist, stdlist)) |
376 | return 1; |
377 | } |
378 | |
379 | listsize = boostlist.size(); |
380 | |
381 | if(push_data_t::execute(listsize, boostlist, stdlist)){ |
382 | return 1; |
383 | } |
384 | |
385 | if(push_data_t::execute(listsize, otherboostlist, otherstdlist)){ |
386 | return 1; |
387 | } |
388 | |
389 | if(copied_allocators_equal){ |
390 | boostlist.sort(std::greater<IntType>()); |
391 | stdlist.sort(comp: std::greater<int>()); |
392 | if(!CheckEqualContainers(boostlist, stdlist)) |
393 | return 1; |
394 | |
395 | otherboostlist.sort(std::greater<IntType>()); |
396 | otherstdlist.sort(comp: std::greater<int>()); |
397 | if(!CheckEqualContainers(otherboostlist, otherstdlist)) |
398 | return 1; |
399 | |
400 | boostlist.merge(otherboostlist, std::greater<IntType>()); |
401 | stdlist.merge(x&: otherstdlist, comp: std::greater<int>()); |
402 | if(!CheckEqualContainers(boostlist, stdlist)) |
403 | return 1; |
404 | } |
405 | |
406 | if(!list_copyable_only(boostlist, stdlist |
407 | ,dtl::bool_<boost::container::test::is_copyable<IntType>::value>())){ |
408 | return 1; |
409 | } |
410 | } |
411 | return 0; |
412 | } |
413 | |
414 | template<class List> |
415 | bool test_list_methods_with_initializer_list_as_argument_for() |
416 | { |
417 | #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) |
418 | const std::initializer_list<int> il = {5, 10, 15}; |
419 | const List expected_list(il.begin(), il.end()); |
420 | { |
421 | List sl = il; |
422 | if(sl != expected_list) |
423 | return false; |
424 | } |
425 | |
426 | { |
427 | List sl = {1, 2}; |
428 | sl = il; |
429 | if(sl != expected_list) |
430 | return false; |
431 | } |
432 | { |
433 | List sl({ 1, 2 }, typename List::allocator_type()); |
434 | sl = il; |
435 | if (sl != expected_list) |
436 | return false; |
437 | } |
438 | { |
439 | List sl = {4, 5}; |
440 | sl.assign(il); |
441 | if(sl != expected_list) |
442 | return false; |
443 | } |
444 | |
445 | { |
446 | List sl = {15}; |
447 | sl.insert(sl.cbegin(), {5, 10}); |
448 | if(sl != expected_list) |
449 | return false; |
450 | } |
451 | |
452 | { |
453 | List sl = {5}; |
454 | sl.insert_after(sl.cbegin(), {10, 15}); |
455 | if(sl != expected_list) |
456 | return false; |
457 | } |
458 | return true; |
459 | #endif |
460 | return true; |
461 | } |
462 | |
463 | |
464 | } //namespace test{ |
465 | } //namespace container { |
466 | } //namespace boost{ |
467 | |
468 | #include <boost/container/detail/config_end.hpp> |
469 | |
470 | #endif |
471 | |