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