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 #define STABLE_VECTOR_ENABLE_INVARIANT_CHECKING
11 #include <memory>
12
13 #include <boost/container/stable_vector.hpp>
14 #include <boost/container/node_allocator.hpp>
15
16 #include "check_equal_containers.hpp"
17 #include "movable_int.hpp"
18 #include "expand_bwd_test_allocator.hpp"
19 #include "expand_bwd_test_template.hpp"
20 #include "dummy_test_allocator.hpp"
21 #include "propagate_allocator_test.hpp"
22 #include "vector_test.hpp"
23 #include "default_init_test.hpp"
24 #include "../../intrusive/test/iterator_test.hpp"
25
26 using namespace boost::container;
27
28 class recursive_vector
29 {
30 public:
31 int id_;
32 stable_vector<recursive_vector> vector_;
33 stable_vector<recursive_vector>::iterator it_;
34 stable_vector<recursive_vector>::const_iterator cit_;
35 stable_vector<recursive_vector>::reverse_iterator rit_;
36 stable_vector<recursive_vector>::const_reverse_iterator crit_;
37
operator =(const recursive_vector & o)38 recursive_vector &operator=(const recursive_vector &o)
39 { vector_ = o.vector_; return *this; }
40 };
41
recursive_vector_test()42 void recursive_vector_test()//Test for recursive types
43 {
44 stable_vector<recursive_vector> recursive, copy;
45 //Test to test both move emulations
46 if(!copy.size()){
47 copy = recursive;
48 }
49 }
50
51 template<class VoidAllocator>
52 struct GetAllocatorCont
53 {
54 template<class ValueType>
55 struct apply
56 {
57 typedef stable_vector< ValueType
58 , typename allocator_traits<VoidAllocator>
59 ::template portable_rebind_alloc<ValueType>::type
60 > type;
61 };
62 };
63
64 template<class VoidAllocator>
test_cont_variants()65 int test_cont_variants()
66 {
67 typedef typename GetAllocatorCont<VoidAllocator>::template apply<int>::type MyCont;
68 typedef typename GetAllocatorCont<VoidAllocator>::template apply<test::movable_int>::type MyMoveCont;
69 typedef typename GetAllocatorCont<VoidAllocator>::template apply<test::movable_and_copyable_int>::type MyCopyMoveCont;
70 typedef typename GetAllocatorCont<VoidAllocator>::template apply<test::copyable_int>::type MyCopyCont;
71
72 if(test::vector_test<MyCont>())
73 return 1;
74 if(test::vector_test<MyMoveCont>())
75 return 1;
76 if(test::vector_test<MyCopyMoveCont>())
77 return 1;
78 if(test::vector_test<MyCopyCont>())
79 return 1;
80
81 return 0;
82 }
83
84 struct boost_container_stable_vector;
85
86 namespace boost { namespace container { namespace test {
87
88 template<>
89 struct alloc_propagate_base<boost_container_stable_vector>
90 {
91 template <class T, class Allocator>
92 struct apply
93 {
94 typedef boost::container::stable_vector<T, Allocator> type;
95 };
96 };
97
98 }}} //namespace boost::container::test
99
100
main()101 int main()
102 {
103 recursive_vector_test();
104 {
105 //Now test move semantics
106 stable_vector<recursive_vector> original;
107 stable_vector<recursive_vector> move_ctor(boost::move(original));
108 stable_vector<recursive_vector> move_assign;
109 move_assign = boost::move(move_ctor);
110 move_assign.swap(original);
111 }
112
113 //Test non-copy-move operations
114 {
115 stable_vector<test::non_copymovable_int> sv;
116 sv.emplace_back();
117 sv.resize(10);
118 sv.resize(1);
119 }
120
121 ////////////////////////////////////
122 // Testing allocator implementations
123 ////////////////////////////////////
124 // std:allocator
125 if(test_cont_variants< std::allocator<void> >()){
126 std::cerr << "test_cont_variants< std::allocator<void> > failed" << std::endl;
127 return 1;
128 }
129 // boost::container::node_allocator
130 if(test_cont_variants< node_allocator<void> >()){
131 std::cerr << "test_cont_variants< node_allocator<void> > failed" << std::endl;
132 return 1;
133 }
134
135 ////////////////////////////////////
136 // Default init test
137 ////////////////////////////////////
138 if(!test::default_init_test< stable_vector<int, test::default_init_allocator<int> > >()){
139 std::cerr << "Default init test failed" << std::endl;
140 return 1;
141 }
142
143 ////////////////////////////////////
144 // Emplace testing
145 ////////////////////////////////////
146 const test::EmplaceOptions Options = (test::EmplaceOptions)(test::EMPLACE_BACK | test::EMPLACE_BEFORE);
147 if(!boost::container::test::test_emplace
148 < stable_vector<test::EmplaceInt>, Options>())
149 return 1;
150
151 ////////////////////////////////////
152 // Allocator propagation testing
153 ////////////////////////////////////
154 if(!boost::container::test::test_propagate_allocator<boost_container_stable_vector>())
155 return 1;
156
157 ////////////////////////////////////
158 // Initializer lists testing
159 ////////////////////////////////////
160 if(!boost::container::test::test_vector_methods_with_initializer_list_as_argument_for
161 < boost::container::stable_vector<int> >())
162 {
163 std::cerr << "test_methods_with_initializer_list_as_argument failed" << std::endl;
164 return 1;
165 }
166
167 ////////////////////////////////////
168 // Iterator testing
169 ////////////////////////////////////
170 {
171 typedef boost::container::stable_vector<int> cont_int;
172 cont_int a; a.push_back(0); a.push_back(1); a.push_back(2);
173 boost::intrusive::test::test_iterator_random< cont_int >(a);
174 if(boost::report_errors() != 0) {
175 return 1;
176 }
177 }
178
179 #ifndef BOOST_CONTAINER_NO_CXX17_CTAD
180 ////////////////////////////////////
181 // Constructor Template Auto Deduction testing
182 ////////////////////////////////////
183 {
184 auto gold = std::vector{ 1, 2, 3 };
185 auto test = boost::container::stable_vector(gold.begin(), gold.end());
186 if (test.size() != 3) {
187 return 1;
188 }
189 if (!(test[0] == 1 && test[1] == 2 && test[2] == 3)) {
190 return 1;
191 }
192 }
193 #endif
194
195 ////////////////////////////////////
196 // has_trivial_destructor_after_move testing
197 ////////////////////////////////////
198 // default allocator
199 {
200 typedef boost::container::stable_vector<int> cont;
201 typedef cont::allocator_type allocator_type;
202 typedef boost::container::allocator_traits<allocator_type>::pointer pointer;
203 if (boost::has_trivial_destructor_after_move<cont>::value !=
204 boost::has_trivial_destructor_after_move<allocator_type>::value &&
205 boost::has_trivial_destructor_after_move<pointer>::value) {
206 std::cerr << "has_trivial_destructor_after_move(default allocator) test failed" << std::endl;
207 return 1;
208 }
209 }
210 // std::allocator
211 {
212 typedef boost::container::stable_vector<int, std::allocator<int> > cont;
213 typedef cont::allocator_type allocator_type;
214 typedef boost::container::allocator_traits<allocator_type>::pointer pointer;
215 if (boost::has_trivial_destructor_after_move<cont>::value !=
216 boost::has_trivial_destructor_after_move<allocator_type>::value &&
217 boost::has_trivial_destructor_after_move<pointer>::value) {
218 std::cerr << "has_trivial_destructor_after_move(std::allocator) test failed" << std::endl;
219 return 1;
220 }
221 }
222
223 return 0;
224 }
225