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