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

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