1 //////////////////////////////////////////////////////////////////////////////
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)
7 // See http://www.boost.org/libs/container for documentation.
9 //////////////////////////////////////////////////////////////////////////////
10 #include <boost/container/slist.hpp>
11 #include <boost/container/node_allocator.hpp>
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"
21 using namespace boost::container
;
27 slist
<recursive_slist
> slist_
;
28 slist
<recursive_slist
>::iterator it_
;
29 slist
<recursive_slist
>::const_iterator cit_
;
31 recursive_slist
&operator=(const recursive_slist
&o
)
32 { slist_
= o
.slist_
; return *this; }
34 recursive_slist (const recursive_slist
&o
)
39 void recursive_slist_test()//Test for recursive types
41 slist
<recursive_slist
> recursive_list_list
;
44 template<class VoidAllocator
>
45 struct GetAllocatorCont
47 template<class ValueType
>
50 typedef slist
< ValueType
51 , typename allocator_traits
<VoidAllocator
>
52 ::template portable_rebind_alloc
<ValueType
>::type
57 bool test_support_for_initializer_list()
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());
64 if(sl
!= expected_list
)
69 slist
<int> sl
= {1, 2};
71 if(sl
!= expected_list
)
75 slist
<int> sl({ 1, 2 }, slist
<int>::allocator_type());
77 if (sl
!= expected_list
)
81 slist
<int> sl
= {4, 5};
83 if(sl
!= expected_list
)
89 sl
.insert(sl
.cbegin(), {5, 10});
90 if(sl
!= expected_list
)
96 sl
.insert_after(sl
.cbegin(), {10, 15});
97 if(sl
!= expected_list
)
105 bool test_for_splice()
108 slist
<int> list1
; list1
.push_front(3); list1
.push_front(2); list1
.push_front(1); list1
.push_front(0);
110 slist
<int> expected1
; expected1
.push_front(3); expected1
.push_front(2); expected1
.push_front(0);
111 slist
<int> expected2
; expected2
.push_front(1);
113 list2
.splice(list2
.begin(), list1
, ++list1
.begin());
115 if (!(expected1
== list1
&& expected2
== list2
))
119 slist
<int> list1
; list1
.push_front(3); list1
.push_front(2); list1
.push_front(1); list1
.push_front(0);
121 slist
<int> expected1
;
122 slist
<int> expected2
; expected2
.push_front(3); expected2
.push_front(2); expected2
.push_front(1); expected2
.push_front(0);
124 list2
.splice(list2
.begin(), list1
, list1
.begin(), list1
.end());
126 if (!(expected1
== list1
&& expected2
== list2
))
132 struct boost_container_slist
;
135 namespace container
{
139 struct alloc_propagate_base
<boost_container_slist
>
141 template <class T
, class Allocator
>
144 typedef boost::container::slist
<T
, Allocator
> type
;
152 recursive_slist_test();
154 //Now test move semantics
155 slist
<recursive_slist
> original
;
156 slist
<recursive_slist
> move_ctor(boost::move(original
));
157 slist
<recursive_slist
> move_assign
;
158 move_assign
= boost::move(move_ctor
);
159 move_assign
.swap(original
);
161 slist
<recursive_slist
> recursive
, copy
;
162 //Test to test both move emulations
168 ////////////////////////////////////
169 // Testing allocator implementations
170 ////////////////////////////////////
171 if (test::list_test
<slist
<int, std::allocator
<int> >, false>())
173 if (test::list_test
<slist
<int>, false>())
175 if (test::list_test
<slist
<int, node_allocator
<int> >, false>())
177 if (test::list_test
<slist
<test::movable_int
>, false>())
179 if (test::list_test
<slist
<test::movable_and_copyable_int
>, false>())
181 if (test::list_test
<slist
<test::copyable_int
>, false>())
184 ////////////////////////////////////
186 ////////////////////////////////////
187 const test::EmplaceOptions Options
= (test::EmplaceOptions
)
188 (test::EMPLACE_FRONT
| test::EMPLACE_AFTER
| test::EMPLACE_BEFORE
| test::EMPLACE_AFTER
);
190 if(!boost::container::test::test_emplace
191 < slist
<test::EmplaceInt
>, Options
>())
194 ////////////////////////////////////
195 // Allocator propagation testing
196 ////////////////////////////////////
197 if(!boost::container::test::test_propagate_allocator
<boost_container_slist
>())
200 ////////////////////////////////////
202 ////////////////////////////////////
203 if(!test_support_for_initializer_list())
206 ////////////////////////////////////
208 ////////////////////////////////////
209 if(!test_for_splice())
212 ////////////////////////////////////
214 ////////////////////////////////////
216 typedef boost::container::slist
<int> vector_int
;
217 vector_int a
; a
.push_front(2); a
.push_front(1); a
.push_front(0);
218 boost::intrusive::test::test_iterator_forward
< boost::container::slist
<int> >(a
);
219 if(boost::report_errors() != 0) {
223 #ifndef BOOST_CONTAINER_NO_CXX17_CTAD
224 ////////////////////////////////////
225 // Constructor Template Auto Deduction Tests
226 ////////////////////////////////////
228 auto gold
= std::list
{ 1, 2, 3 };
229 auto test
= boost::container::slist(gold
.begin(), gold
.end());
230 if (test
.size() != 3) {
233 if (test
.front() != 1)
236 if (test
.front() != 2)
239 if (test
.front() != 3)
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) {
249 if (test
.front() != 1)
252 if (test
.front() != 2)
255 if (test
.front() != 3)
261 ////////////////////////////////////
262 // has_trivial_destructor_after_move testing
263 ////////////////////////////////////
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_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");
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_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");