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

source code of boost/libs/container/test/slist_test.cpp