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 //////////////////////////////////////////////////////////////////////////////
15 #include <boost/container/deque.hpp>
16 #include <boost/container/allocator.hpp>
18 #include "print_container.hpp"
19 #include "check_equal_containers.hpp"
20 #include "dummy_test_allocator.hpp"
21 #include "movable_int.hpp"
22 #include <boost/move/utility_core.hpp>
23 #include <boost/move/iterator.hpp>
24 #include <boost/container/detail/mpl.hpp>
25 #include <boost/container/detail/type_traits.hpp>
27 #include "emplace_test.hpp"
28 #include "propagate_allocator_test.hpp"
29 #include "vector_test.hpp"
30 #include "default_init_test.hpp"
31 #include <boost/core/no_exceptions_support.hpp>
32 #include "../../intrusive/test/iterator_test.hpp"
34 using namespace boost::container
;
36 //Function to check if both sets are equal
37 template<class V1
, class V2
>
38 bool deque_copyable_only(V1
&, V2
&, dtl::false_type
)
43 //Function to check if both sets are equal
44 template<class V1
, class V2
>
45 bool deque_copyable_only(V1
&cntdeque
, V2
&stddeque
, dtl::true_type
)
47 typedef typename
V1::value_type IntType
;
48 std::size_t size
= cntdeque
.size();
49 stddeque
.insert(stddeque
.end(), 50u, 1);
50 cntdeque
.insert(cntdeque
.end(), 50u, IntType(1));
51 if(!test::CheckEqualContainers(cntdeque
, stddeque
)) return false;
54 stddeque
.insert(stddeque
.begin()+std::ptrdiff_t(size
)/2, 50u, 1);
55 cntdeque
.insert(cntdeque
.begin()+std::ptrdiff_t(size
/2), 50u, boost::move(move_me
));
56 if(!test::CheckEqualContainers(cntdeque
, stddeque
)) return false;
60 cntdeque
.assign(cntdeque
.size()/2, boost::move(move_me
));
61 stddeque
.assign(stddeque
.size()/2, 2);
62 if(!test::CheckEqualContainers(cntdeque
, stddeque
)) return false;
68 stddeque
.insert(stddeque
.begin(), 50u, 1);
69 cntdeque
.insert(cntdeque
.begin(), 50u, boost::move(move_me
));
70 if(!test::CheckEqualContainers(cntdeque
, stddeque
)) return false;
71 stddeque
.insert(stddeque
.begin()+20, 50u, 1);
72 cntdeque
.insert(cntdeque
.begin()+20, 50u, boost::move(move_me
));
73 if(!test::CheckEqualContainers(cntdeque
, stddeque
)) return false;
74 stddeque
.insert(stddeque
.begin()+20, 20u, 1);
75 cntdeque
.insert(cntdeque
.begin()+20, 20u, boost::move(move_me
));
76 if(!test::CheckEqualContainers(cntdeque
, stddeque
)) return false;
82 stddeque
.insert(stddeque
.end(), 50u, 1);
83 cntdeque
.insert(cntdeque
.end(), 50u, boost::move(move_me
));
84 if(!test::CheckEqualContainers(cntdeque
, stddeque
)) return false;
85 stddeque
.insert(stddeque
.end()-20, 50u, 1);
86 cntdeque
.insert(cntdeque
.end()-20, 50u, boost::move(move_me
));
87 if(!test::CheckEqualContainers(cntdeque
, stddeque
)) return false;
88 stddeque
.insert(stddeque
.end()-20, 20u, 1);
89 cntdeque
.insert(cntdeque
.end()-20, 20u, boost::move(move_me
));
90 if(!test::CheckEqualContainers(cntdeque
, stddeque
)) return false;
96 //Test recursive structures
101 recursive_deque (const recursive_deque
&x
)
105 recursive_deque
& operator=(const recursive_deque
&x
)
106 { this->deque_
= x
.deque_
; return *this; }
109 deque
<recursive_deque
> deque_
;
110 deque
<recursive_deque
>::iterator it_
;
111 deque
<recursive_deque
>::const_iterator cit_
;
112 deque
<recursive_deque
>::reverse_iterator rit_
;
113 deque
<recursive_deque
>::const_reverse_iterator crit_
;
116 template<class IntType
>
119 //Test for recursive types
121 deque
<recursive_deque
> recursive_deque_deque
;
125 //Now test move semantics
126 deque
<recursive_deque
> original
;
127 deque
<recursive_deque
> move_ctor(boost::move(original
));
128 deque
<recursive_deque
> move_assign
;
129 move_assign
= boost::move(move_ctor
);
130 move_assign
.swap(original
);
134 typedef deque
<IntType
> MyCntDeque
;
135 typedef std::deque
<int> MyStdDeque
;
138 ::boost::movelib::unique_ptr
<MyCntDeque
> const pcntdeque
= ::boost::movelib::make_unique
<MyCntDeque
>();
139 ::boost::movelib::unique_ptr
<MyStdDeque
> const pstddeque
= ::boost::movelib::make_unique
<MyStdDeque
>();
140 MyCntDeque
&cntdeque
= *pcntdeque
;
141 MyStdDeque
&stddeque
= *pstddeque
;
142 for(int i
= 0; i
< max
*100; ++i
){
144 cntdeque
.insert(cntdeque
.end(), boost::move(move_me
));
145 stddeque
.insert(stddeque
.end(), i
);
147 if(!test::CheckEqualContainers(cntdeque
, stddeque
)) return false;
152 for(int i
= 0; i
< max
*100; ++i
){
154 cntdeque
.push_back(boost::move(move_me
));
155 stddeque
.push_back(i
);
157 if(!test::CheckEqualContainers(cntdeque
, stddeque
)) return false;
162 for(int i
= 0; i
< max
*100; ++i
){
164 cntdeque
.push_front(boost::move(move_me
));
165 stddeque
.push_front(i
);
167 if(!test::CheckEqualContainers(cntdeque
, stddeque
)) return false;
169 typename
MyCntDeque::iterator it
;
170 typename
MyCntDeque::const_iterator cit
= it
;
173 cntdeque
.erase(cntdeque
.begin()++);
174 stddeque
.erase(stddeque
.begin()++);
175 if(!test::CheckEqualContainers(cntdeque
, stddeque
)) return false;
177 cntdeque
.erase(cntdeque
.begin());
178 stddeque
.erase(stddeque
.begin());
179 if(!test::CheckEqualContainers(cntdeque
, stddeque
)) return false;
183 IntType aux_vect
[50];
184 for(int i
= 0; i
< 50; ++i
){
185 IntType
move_me (-1);
186 aux_vect
[i
] = boost::move(move_me
);
189 for(int i
= 0; i
< 50; ++i
){
193 cntdeque
.insert(cntdeque
.end()
194 ,boost::make_move_iterator(&aux_vect
[0])
195 ,boost::make_move_iterator(aux_vect
+ 50));
196 stddeque
.insert(stddeque
.end(), aux_vect2
, aux_vect2
+ 50);
197 if(!test::CheckEqualContainers(cntdeque
, stddeque
)) return false;
199 for(int i
= 0; i
< 50; ++i
){
201 aux_vect
[i
] = boost::move(move_me
);
203 for(int i
= 0; i
< 50; ++i
){
207 cntdeque
.insert(cntdeque
.begin()+std::ptrdiff_t(cntdeque
.size())
208 ,boost::make_move_iterator(&aux_vect
[0])
209 ,boost::make_move_iterator(aux_vect
+ 50));
210 stddeque
.insert(stddeque
.begin()+std::ptrdiff_t(stddeque
.size()), aux_vect2
, aux_vect2
+ 50);
211 if(!test::CheckEqualContainers(cntdeque
, stddeque
)) return false;
213 for(int i
= 0, j
= static_cast<int>(cntdeque
.size()); i
< j
; ++i
){
214 cntdeque
.erase(cntdeque
.begin());
215 stddeque
.erase(stddeque
.begin());
217 if(!test::CheckEqualContainers(cntdeque
, stddeque
)) return false;
220 IntType aux_vect
[50];
221 for(int i
= 0; i
< 50; ++i
){
223 aux_vect
[i
] = boost::move(move_me
);
226 for(int i
= 0; i
< 50; ++i
){
229 cntdeque
.insert(cntdeque
.begin()
230 ,boost::make_move_iterator(&aux_vect
[0])
231 ,boost::make_move_iterator(aux_vect
+ 50));
232 stddeque
.insert(stddeque
.begin(), aux_vect2
, aux_vect2
+ 50);
233 if(!test::CheckEqualContainers(cntdeque
, stddeque
)) return false;
236 if(!deque_copyable_only(cntdeque
, stddeque
237 ,dtl::bool_
<boost::container::test::is_copyable
<IntType
>::value
>())){
241 cntdeque
.erase(cntdeque
.begin());
242 stddeque
.erase(stddeque
.begin());
244 if(!test::CheckEqualContainers(cntdeque
, stddeque
)) return false;
246 for(int i
= 0; i
< max
; ++i
){
248 cntdeque
.insert(cntdeque
.begin(), boost::move(move_me
));
249 stddeque
.insert(stddeque
.begin(), i
);
251 if(!test::CheckEqualContainers(cntdeque
, stddeque
)) return false;
253 //Test insertion from list
255 std::list
<int> l(50, int(1));
256 cntdeque
.insert(cntdeque
.begin(), l
.begin(), l
.end());
257 stddeque
.insert(stddeque
.begin(), l
.begin(), l
.end());
258 if(!test::CheckEqualContainers(cntdeque
, stddeque
)) return 1;
259 cntdeque
.assign(l
.begin(), l
.end());
260 stddeque
.assign(l
.begin(), l
.end());
261 if(!test::CheckEqualContainers(cntdeque
, stddeque
)) return 1;
264 cntdeque
.resize(100);
265 stddeque
.resize(100);
266 if(!test::CheckEqualContainers(cntdeque
, stddeque
)) return 1;
268 cntdeque
.resize(200);
269 stddeque
.resize(200);
270 if(!test::CheckEqualContainers(cntdeque
, stddeque
)) return 1;
273 #ifndef BOOST_CONTAINER_NO_CXX17_CTAD
274 //Check Constructor Template Auto Deduction
276 auto gold
= MyStdDeque
{ 1, 2, 3 };
277 auto test
= deque(gold
.begin(), gold
.end());
278 if(!test::CheckEqualContainers(gold
, test
)) return false;
281 auto gold
= MyStdDeque
{ 1, 2, 3 };
282 auto test
= deque(gold
.begin(), gold
.end(), new_allocator
<int>());
283 if(!test::CheckEqualContainers(gold
, test
)) return false;
287 std::cout
<< std::endl
<< "Test OK!" << std::endl
;
291 template<class VoidAllocator
>
292 struct GetAllocatorCont
294 template<class ValueType
>
297 typedef deque
< ValueType
298 , typename allocator_traits
<VoidAllocator
>
299 ::template portable_rebind_alloc
<ValueType
>::type
304 template<class VoidAllocator
>
305 int test_cont_variants()
307 typedef typename GetAllocatorCont
<VoidAllocator
>::template apply
<int>::type MyCont
;
308 typedef typename GetAllocatorCont
<VoidAllocator
>::template apply
<test::movable_int
>::type MyMoveCont
;
309 typedef typename GetAllocatorCont
<VoidAllocator
>::template apply
<test::movable_and_copyable_int
>::type MyCopyMoveCont
;
310 typedef typename GetAllocatorCont
<VoidAllocator
>::template apply
<test::copyable_int
>::type MyCopyCont
;
312 if(test::vector_test
<MyCont
>())
314 if(test::vector_test
<MyMoveCont
>())
316 if(test::vector_test
<MyCopyMoveCont
>())
318 if(test::vector_test
<MyCopyCont
>())
323 struct boost_container_deque
;
325 namespace boost
{ namespace container
{ namespace test
{
328 struct alloc_propagate_base
<boost_container_deque
>
330 template <class T
, class Allocator
>
333 typedef boost::container::deque
<T
, Allocator
> type
;
337 }}} //namespace boost::container::test
344 if(!do_test
<test::movable_int
>())
347 if(!do_test
<test::movable_and_copyable_int
>())
350 if(!do_test
<test::copyable_int
>())
353 //Test non-copy-move operations
355 deque
<test::non_copymovable_int
> d
;
362 ////////////////////////////////////
363 // Allocator implementations
364 ////////////////////////////////////
366 if(test_cont_variants
< std::allocator
<void> >()){
367 std::cerr
<< "test_cont_variants< std::allocator<void> > failed" << std::endl
;
370 // boost::container::allocator
371 if(test_cont_variants
< allocator
<void> >()){
372 std::cerr
<< "test_cont_variants< allocator<void> > failed" << std::endl
;
375 ////////////////////////////////////
377 ////////////////////////////////////
378 if(!test::default_init_test
< deque
<int, test::default_init_allocator
<int> > >()){
379 std::cerr
<< "Default init test failed" << std::endl
;
383 ////////////////////////////////////
385 ////////////////////////////////////
386 const test::EmplaceOptions Options
= (test::EmplaceOptions
)(test::EMPLACE_BACK
| test::EMPLACE_FRONT
| test::EMPLACE_BEFORE
);
388 if(!boost::container::test::test_emplace
389 < deque
<test::EmplaceInt
>, Options
>())
391 ////////////////////////////////////
392 // Allocator propagation testing
393 ////////////////////////////////////
394 if(!boost::container::test::test_propagate_allocator
<boost_container_deque
>())
397 ////////////////////////////////////
398 // Initializer lists testing
399 ////////////////////////////////////
400 if(!boost::container::test::test_vector_methods_with_initializer_list_as_argument_for
401 < boost::container::deque
<int> >()) {
405 ////////////////////////////////////
407 ////////////////////////////////////
409 typedef boost::container::deque
<int> cont_int
;
410 cont_int a
; a
.push_back(0); a
.push_back(1); a
.push_back(2);
411 boost::intrusive::test::test_iterator_random
< cont_int
>(a
);
412 if(boost::report_errors() != 0) {
417 ////////////////////////////////////
418 // has_trivial_destructor_after_move testing
419 ////////////////////////////////////
422 typedef boost::container::deque
<int> cont
;
423 typedef cont::allocator_type allocator_type
;
424 typedef boost::container::allocator_traits
<allocator_type
>::pointer pointer
;
425 BOOST_STATIC_ASSERT_MSG(!(boost::has_trivial_destructor_after_move
<cont
>::value
!=
426 boost::has_trivial_destructor_after_move
<allocator_type
>::value
&&
427 boost::has_trivial_destructor_after_move
<pointer
>::value
)
428 , "has_trivial_destructor_after_move(std::allocator) test failed");
432 typedef boost::container::deque
<int, std::allocator
<int> > cont
;
433 typedef cont::allocator_type allocator_type
;
434 typedef boost::container::allocator_traits
<allocator_type
>::pointer pointer
;
435 BOOST_STATIC_ASSERT_MSG(!(boost::has_trivial_destructor_after_move
<cont
>::value
!=
436 boost::has_trivial_destructor_after_move
<allocator_type
>::value
&&
437 boost::has_trivial_destructor_after_move
<pointer
>::value
)
438 , "has_trivial_destructor_after_move(std::allocator) test failed");