• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //////////////////////////////////////////////////////////////////////////////
2 //
3 // (C) Copyright Ion Gaztanaga 2004-2013. 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 #include <boost/container/slist.hpp>
11 #include <boost/container/node_allocator.hpp>
12 
13 #include <memory>
14 #include "dummy_test_allocator.hpp"
15 #include "movable_int.hpp"
16 #include "list_test.hpp"
17 #include "propagate_allocator_test.hpp"
18 #include "emplace_test.hpp"
19 #include "../../intrusive/test/iterator_test.hpp"
20 
21 using namespace boost::container;
22 
23 class recursive_slist
24 {
25 public:
26    int id_;
27    slist<recursive_slist> slist_;
28    slist<recursive_slist>::iterator it_;
29    slist<recursive_slist>::const_iterator cit_;
30 
operator =(const recursive_slist & o)31    recursive_slist &operator=(const recursive_slist &o)
32    { slist_ = o.slist_;  return *this; }
33 };
34 
recursive_slist_test()35 void recursive_slist_test()//Test for recursive types
36 {
37    slist<recursive_slist> recursive_list_list;
38 }
39 
40 template<class VoidAllocator>
41 struct GetAllocatorCont
42 {
43    template<class ValueType>
44    struct apply
45    {
46       typedef slist< ValueType
47                    , typename allocator_traits<VoidAllocator>
48                         ::template portable_rebind_alloc<ValueType>::type
49                    > type;
50    };
51 };
52 
test_support_for_initializer_list()53 bool test_support_for_initializer_list()
54 {
55 #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
56    const std::initializer_list<int> il = {5, 10, 15};
57    const slist<int> expected_list(il.begin(), il.end());
58    {
59       slist<int> sl = il;
60       if(sl != expected_list)
61          return false;
62    }
63 
64    {
65       slist<int> sl = {1, 2};
66       sl = il;
67       if(sl != expected_list)
68          return false;
69    }
70    {
71       slist<int> sl({ 1, 2 }, slist<int>::allocator_type());
72       sl = il;
73       if (sl != expected_list)
74          return false;
75    }
76    {
77       slist<int> sl = {4, 5};
78       sl.assign(il);
79       if(sl != expected_list)
80          return false;
81    }
82 
83    {
84       slist<int> sl = {15};
85       sl.insert(sl.cbegin(), {5, 10});
86       if(sl != expected_list)
87          return false;
88    }
89 
90    {
91        slist<int> sl = {5};
92        sl.insert_after(sl.cbegin(), {10, 15});
93        if(sl != expected_list)
94           return false;
95    }
96    return true;
97 #endif
98    return true;
99 }
100 
test_for_splice()101 bool test_for_splice()
102 {
103    {
104       slist<int> list1; list1.push_front(3); list1.push_front(2); list1.push_front(1); list1.push_front(0);
105       slist<int> list2;
106       slist<int> expected1; expected1.push_front(3); expected1.push_front(2);  expected1.push_front(0);
107       slist<int> expected2; expected2.push_front(1);
108 
109       list2.splice(list2.begin(), list1, ++list1.begin());
110 
111       if (!(expected1 == list1 && expected2 == list2))
112          return false;
113    }
114    {
115       slist<int> list1; list1.push_front(3); list1.push_front(2); list1.push_front(1); list1.push_front(0);
116       slist<int> list2;
117       slist<int> expected1;
118       slist<int> expected2; expected2.push_front(3); expected2.push_front(2); expected2.push_front(1); expected2.push_front(0);
119 
120       list2.splice(list2.begin(), list1, list1.begin(), list1.end());
121 
122       if (!(expected1 == list1 && expected2 == list2))
123          return false;
124    }
125    return true;
126 }
127 
128 struct boost_container_slist;
129 
130 namespace boost {
131 namespace container {
132 namespace test {
133 
134 template<>
135 struct alloc_propagate_base<boost_container_slist>
136 {
137    template <class T, class Allocator>
138    struct apply
139    {
140       typedef boost::container::slist<T, Allocator> type;
141    };
142 };
143 
144 }}}
145 
main()146 int main ()
147 {
148    recursive_slist_test();
149    {
150       //Now test move semantics
151       slist<recursive_slist> original;
152       slist<recursive_slist> move_ctor(boost::move(original));
153       slist<recursive_slist> move_assign;
154       move_assign = boost::move(move_ctor);
155       move_assign.swap(original);
156       {
157          slist<recursive_slist> recursive, copy;
158          //Test to test both move emulations
159          if(!copy.size()){
160             copy = recursive;
161          }
162       }
163    }
164    ////////////////////////////////////
165    //    Testing allocator implementations
166    ////////////////////////////////////
167    if (test::list_test<slist<int, std::allocator<int> >, false>())
168       return 1;
169    if (test::list_test<slist<int>, false>())
170       return 1;
171    if (test::list_test<slist<int, node_allocator<int> >, false>())
172       return 1;
173    if (test::list_test<slist<test::movable_int>, false>())
174       return 1;
175    if (test::list_test<slist<test::movable_and_copyable_int>, false>())
176       return 1;
177    if (test::list_test<slist<test::copyable_int>, false>())
178       return 1;
179 
180    ////////////////////////////////////
181    //    Emplace testing
182    ////////////////////////////////////
183    const test::EmplaceOptions Options = (test::EmplaceOptions)
184       (test::EMPLACE_FRONT | test::EMPLACE_AFTER | test::EMPLACE_BEFORE  | test::EMPLACE_AFTER);
185 
186    if(!boost::container::test::test_emplace
187       < slist<test::EmplaceInt>, Options>())
188       return 1;
189 
190    ////////////////////////////////////
191    //    Allocator propagation testing
192    ////////////////////////////////////
193    if(!boost::container::test::test_propagate_allocator<boost_container_slist>())
194       return 1;
195 
196    ////////////////////////////////////
197    //    Initializer lists
198    ////////////////////////////////////
199    if(!test_support_for_initializer_list())
200       return 1;
201 
202    ////////////////////////////////////
203    //    Splice testing
204    ////////////////////////////////////
205    if(!test_for_splice())
206       return 1;
207 
208    ////////////////////////////////////
209    //    Iterator testing
210    ////////////////////////////////////
211    {
212       typedef boost::container::slist<int> vector_int;
213       vector_int a; a.push_front(2); a.push_front(1); a.push_front(0);
214       boost::intrusive::test::test_iterator_forward< boost::container::slist<int> >(a);
215       if(boost::report_errors() != 0) {
216          return 1;
217       }
218    }
219 #ifndef BOOST_CONTAINER_NO_CXX17_CTAD
220    ////////////////////////////////////
221    //    Constructor Template Auto Deduction Tests
222    ////////////////////////////////////
223    {
224       auto gold = std::list{ 1, 2, 3 };
225       auto test = boost::container::slist(gold.begin(), gold.end());
226       if (test.size() != 3) {
227          return 1;
228       }
229       if (test.front() != 1)
230          return 1;
231       test.pop_front();
232       if (test.front() != 2)
233          return 1;
234       test.pop_front();
235       if (test.front() != 3)
236          return 1;
237       test.pop_front();
238    }
239    {
240       auto gold = std::list{ 1, 2, 3 };
241       auto test = boost::container::slist(gold.begin(), gold.end(), new_allocator<int>());
242       if (test.size() != 3) {
243          return 1;
244       }
245       if (test.front() != 1)
246          return 1;
247       test.pop_front();
248       if (test.front() != 2)
249          return 1;
250       test.pop_front();
251       if (test.front() != 3)
252          return 1;
253       test.pop_front();
254    }
255 #endif
256 
257    ////////////////////////////////////
258    //    has_trivial_destructor_after_move testing
259    ////////////////////////////////////
260    // default allocator
261    {
262       typedef boost::container::slist<int> cont;
263       typedef cont::allocator_type allocator_type;
264       typedef boost::container::allocator_traits<allocator_type>::pointer pointer;
265       if (boost::has_trivial_destructor_after_move<cont>::value !=
266           boost::has_trivial_destructor_after_move<allocator_type>::value &&
267           boost::has_trivial_destructor_after_move<pointer>::value) {
268          std::cerr << "has_trivial_destructor_after_move(default allocator) test failed" << std::endl;
269          return 1;
270       }
271    }
272    // std::allocator
273    {
274       typedef boost::container::slist<int, std::allocator<int> > cont;
275       typedef cont::allocator_type allocator_type;
276       typedef boost::container::allocator_traits<allocator_type>::pointer pointer;
277       if (boost::has_trivial_destructor_after_move<cont>::value !=
278           boost::has_trivial_destructor_after_move<allocator_type>::value &&
279           boost::has_trivial_destructor_after_move<pointer>::value) {
280          std::cerr << "has_trivial_destructor_after_move(std::allocator) test failed" << std::endl;
281          return 1;
282       }
283    }
284 
285    return 0;
286 }
287