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