]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/libs/container/test/vector_test.cpp
update ceph source to reef 18.1.2
[ceph.git] / ceph / src / boost / libs / container / test / vector_test.cpp
CommitLineData
7c673cae
FG
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//////////////////////////////////////////////////////////////////////////////
11fdf7f2
TL
10
11// the tests trigger deprecation warnings when compiled with msvc in C++17 mode
12#if defined(_MSVC_LANG) && _MSVC_LANG > 201402
13// warning STL4009: std::allocator<void> is deprecated in C++17
14# define _SILENCE_CXX17_ALLOCATOR_VOID_DEPRECATION_WARNING
15#endif
16
7c673cae
FG
17#include <memory>
18#include <iostream>
19
20#include <boost/container/vector.hpp>
21#include <boost/container/allocator.hpp>
22
23#include <boost/move/utility_core.hpp>
24#include "check_equal_containers.hpp"
25#include "movable_int.hpp"
26#include "expand_bwd_test_allocator.hpp"
27#include "expand_bwd_test_template.hpp"
28#include "dummy_test_allocator.hpp"
29#include "propagate_allocator_test.hpp"
30#include "vector_test.hpp"
31#include "default_init_test.hpp"
32#include "../../intrusive/test/iterator_test.hpp"
33
34using namespace boost::container;
35
7c673cae
FG
36int test_expand_bwd()
37{
38 //Now test all back insertion possibilities
39
40 //First raw ints
41 typedef test::expand_bwd_test_allocator<int>
42 int_allocator_type;
43 typedef vector<int, int_allocator_type>
44 int_vector;
45 if(!test::test_all_expand_bwd<int_vector>())
46 return 1;
47
48 //Now user defined copyable int
49 typedef test::expand_bwd_test_allocator<test::copyable_int>
50 copyable_int_allocator_type;
51 typedef vector<test::copyable_int, copyable_int_allocator_type>
52 copyable_int_vector;
53 if(!test::test_all_expand_bwd<copyable_int_vector>())
54 return 1;
55
56 return 0;
57}
58
92f5a8d4
TL
59struct X;
60
61template<typename T>
62struct XRef
63{
1e59de90 64 explicit XRef(T* p) : ptr(p) {}
92f5a8d4
TL
65 operator T*() const { return ptr; }
66 T* ptr;
67};
68
69struct X
70{
71 XRef<X const> operator&() const { return XRef<X const>(this); }
72 XRef<X> operator&() { return XRef<X>(this); }
73};
74
75
76bool test_smart_ref_type()
77{
78 boost::container::vector<X> x(5);
79 return x.empty();
80}
81
7c673cae
FG
82class recursive_vector
83{
84 public:
20effc67
TL
85 recursive_vector (const recursive_vector &x)
86 : vector_(x.vector_)
87 {}
88
7c673cae
FG
89 recursive_vector & operator=(const recursive_vector &x)
90 { this->vector_ = x.vector_; return *this; }
91
92 int id_;
93 vector<recursive_vector> vector_;
94 vector<recursive_vector>::iterator it_;
95 vector<recursive_vector>::const_iterator cit_;
96 vector<recursive_vector>::reverse_iterator rit_;
97 vector<recursive_vector>::const_reverse_iterator crit_;
98};
99
100void recursive_vector_test()//Test for recursive types
101{
102 vector<recursive_vector> recursive_vector_vector;
103}
104
105enum Test
106{
107 zero, one, two, three, four, five, six
108};
109
110template<class VoidAllocator>
111struct GetAllocatorCont
112{
113 template<class ValueType>
114 struct apply
115 {
116 typedef vector< ValueType
117 , typename allocator_traits<VoidAllocator>
118 ::template portable_rebind_alloc<ValueType>::type
119 > type;
120 };
121};
122
123template<class VoidAllocator>
124int test_cont_variants()
125{
126 typedef typename GetAllocatorCont<VoidAllocator>::template apply<int>::type MyCont;
127 typedef typename GetAllocatorCont<VoidAllocator>::template apply<test::movable_int>::type MyMoveCont;
128 typedef typename GetAllocatorCont<VoidAllocator>::template apply<test::movable_and_copyable_int>::type MyCopyMoveCont;
129 typedef typename GetAllocatorCont<VoidAllocator>::template apply<test::copyable_int>::type MyCopyCont;
130
131 if(test::vector_test<MyCont>())
132 return 1;
133 if(test::vector_test<MyMoveCont>())
134 return 1;
135 if(test::vector_test<MyCopyMoveCont>())
136 return 1;
137 if(test::vector_test<MyCopyCont>())
138 return 1;
139
140 return 0;
141}
142
143struct boost_container_vector;
144
145namespace boost { namespace container { namespace test {
146
147template<>
148struct alloc_propagate_base<boost_container_vector>
149{
150 template <class T, class Allocator>
151 struct apply
152 {
153 typedef boost::container::vector<T, Allocator> type;
154 };
155};
156
157}}} //namespace boost::container::test
158
92f5a8d4
TL
159template<typename T>
160class check_dealloc_allocator : public std::allocator<T>
161{
162 public:
163 bool allocate_zero_called_;
164 bool deallocate_called_without_allocate_;
165
166 check_dealloc_allocator()
167 : std::allocator<T>()
168 , allocate_zero_called_(false)
169 , deallocate_called_without_allocate_(false)
170 {}
171
172 T* allocate(std::size_t n)
173 {
174 if (n == 0) {
175 allocate_zero_called_ = true;
176 }
177 return std::allocator<T>::allocate(n);
178 }
179
180 void deallocate(T* p, std::size_t n)
181 {
182 if (n == 0 && !allocate_zero_called_) {
183 deallocate_called_without_allocate_ = true;
184 }
185 return std::allocator<T>::deallocate(p, n);
186 }
187};
188
189bool test_merge_empty_free()
190{
191 vector<int> source;
192 source.emplace_back(1);
193
194 vector< int, check_dealloc_allocator<int> > empty;
195 empty.merge(source.begin(), source.end());
196
1e59de90 197 return !empty.get_stored_allocator().deallocate_called_without_allocate_;
92f5a8d4
TL
198}
199
1e59de90
TL
200#if defined(__cpp_lib_span)
201# define BOOST_VECTOR_TEST_HAS_SPAN
202#endif
203
204#ifdef BOOST_VECTOR_TEST_HAS_SPAN
205#include <span>
206
207bool test_span_conversion()
208{
209 boost::container::vector myVec{1, 2, 3, 4, 5};
210 std::span mySpan1{myVec}; // (1)
211 std::span mySpan2{myVec.data(), myVec.size()}; // (2)
212 return mySpan1.size() == myVec.size() && mySpan1.size() == mySpan2.size();
213}
214
215#else //BOOST_VECTOR_TEST_HAS_SPAN
216bool test_span_conversion()
217{
218 return true;
219}
220
221#endif //BOOST_VECTOR_TEST_HAS_SPAN
222
7c673cae
FG
223int main()
224{
225 {
226 const std::size_t positions_length = 10;
227 std::size_t positions[positions_length];
228 vector<int> vector_int;
229 vector<int> vector_int2(positions_length);
230 for(std::size_t i = 0; i != positions_length; ++i){
231 positions[i] = 0u;
232 }
233 for(std::size_t i = 0, max = vector_int2.size(); i != max; ++i){
234 vector_int2[i] = (int)i;
235 }
236
237 vector_int.insert(vector_int.begin(), 999);
238
239 vector_int.insert_ordered_at(positions_length, positions + positions_length, vector_int2.end());
240
241 for(std::size_t i = 0, max = vector_int.size(); i != max; ++i){
242 std::cout << vector_int[i] << std::endl;
243 }
244 }
245 recursive_vector_test();
246 {
247 //Now test move semantics
248 vector<recursive_vector> original;
249 vector<recursive_vector> move_ctor(boost::move(original));
250 vector<recursive_vector> move_assign;
251 move_assign = boost::move(move_ctor);
252 move_assign.swap(original);
253 }
254
255 ////////////////////////////////////
256 // Testing allocator implementations
257 ////////////////////////////////////
258 // std:allocator
259 if(test_cont_variants< std::allocator<void> >()){
260 std::cerr << "test_cont_variants< std::allocator<void> > failed" << std::endl;
261 return 1;
262 }
263 // boost::container::allocator
264 if(test_cont_variants< allocator<void> >()){
265 std::cerr << "test_cont_variants< allocator<void> > failed" << std::endl;
266 return 1;
267 }
268
269 {
270 typedef vector<Test, std::allocator<Test> > MyEnumCont;
271 MyEnumCont v;
272 Test t;
273 v.push_back(t);
274 v.push_back(::boost::move(t));
275 v.push_back(Test());
276 }
277
92f5a8d4
TL
278 if (test_smart_ref_type())
279 return 1;
280
7c673cae
FG
281 ////////////////////////////////////
282 // Backwards expansion test
283 ////////////////////////////////////
284 if(test_expand_bwd())
285 return 1;
286
287 ////////////////////////////////////
288 // Default init test
289 ////////////////////////////////////
290 if(!test::default_init_test< vector<int, test::default_init_allocator<int> > >()){
291 std::cerr << "Default init test failed" << std::endl;
292 return 1;
293 }
294
295 ////////////////////////////////////
296 // Emplace testing
297 ////////////////////////////////////
298 const test::EmplaceOptions Options = (test::EmplaceOptions)(test::EMPLACE_BACK | test::EMPLACE_BEFORE);
299 if(!boost::container::test::test_emplace< vector<test::EmplaceInt>, Options>()){
300 return 1;
301 }
302
303 ////////////////////////////////////
304 // Allocator propagation testing
305 ////////////////////////////////////
306 if(!boost::container::test::test_propagate_allocator<boost_container_vector>()){
307 return 1;
308 }
309
310 ////////////////////////////////////
311 // Initializer lists testing
312 ////////////////////////////////////
313 if(!boost::container::test::test_vector_methods_with_initializer_list_as_argument_for<
314 boost::container::vector<int>
315 >()) {
316 return 1;
317 }
318
319 ////////////////////////////////////
320 // Iterator testing
321 ////////////////////////////////////
322 {
323 typedef boost::container::vector<int> cont_int;
324 cont_int a; a.push_back(0); a.push_back(1); a.push_back(2);
325 boost::intrusive::test::test_iterator_random< cont_int >(a);
326 if(boost::report_errors() != 0) {
327 return 1;
328 }
329 }
92f5a8d4
TL
330
331#ifndef BOOST_CONTAINER_NO_CXX17_CTAD
332 ////////////////////////////////////
333 // Constructor Template Auto Deduction testing
334 ////////////////////////////////////
335 {
336 auto gold = std::vector{ 1, 2, 3 };
337 auto test = boost::container::vector(gold.begin(), gold.end());
338 if (test.size() != 3) {
339 return 1;
340 }
341 if (!(test[0] == 1 && test[1] == 2 && test[2] == 3)) {
342 return 1;
343 }
344 }
345 {
346 auto gold = std::vector{ 1, 2, 3 };
347 auto test = boost::container::vector(gold.begin(), gold.end(), boost::container::new_allocator<int>());
348 if (test.size() != 3) {
349 return 1;
350 }
351 if (!(test[0] == 1 && test[1] == 2 && test[2] == 3)) {
352 return 1;
353 }
354 }
355#endif
356
1e59de90 357 if (!test_merge_empty_free()) {
92f5a8d4
TL
358 std::cerr << "Merge into empty vector test failed" << std::endl;
359 return 1;
360 }
361
1e59de90
TL
362 if (!test_span_conversion()) {
363 std::cerr << "Span conversion failed" << std::endl;
364 return 1;
365 }
366
92f5a8d4
TL
367 ////////////////////////////////////
368 // has_trivial_destructor_after_move testing
369 ////////////////////////////////////
370 // default allocator
371 {
372 typedef boost::container::vector<int> cont;
373 typedef cont::allocator_type allocator_type;
374 typedef boost::container::allocator_traits<allocator_type>::pointer pointer;
20effc67
TL
375 BOOST_STATIC_ASSERT_MSG
376 ( !boost::has_trivial_destructor_after_move<pointer>::value ||
377 (boost::has_trivial_destructor_after_move<cont>::value ==
378 boost::has_trivial_destructor_after_move<allocator_type>::value)
379 , "has_trivial_destructor_after_move(default allocator) test failed"
380 );
92f5a8d4
TL
381 }
382 // std::allocator
383 {
384 typedef boost::container::vector<int, std::allocator<int> > cont;
385 typedef cont::allocator_type allocator_type;
386 typedef boost::container::allocator_traits<allocator_type>::pointer pointer;
20effc67
TL
387 BOOST_STATIC_ASSERT_MSG
388 ( !boost::has_trivial_destructor_after_move<pointer>::value ||
389 (boost::has_trivial_destructor_after_move<cont>::value ==
390 boost::has_trivial_destructor_after_move<allocator_type>::value)
391 , "has_trivial_destructor_after_move(std::allocator) test failed"
392 );
92f5a8d4
TL
393 }
394
7c673cae
FG
395 return 0;
396}