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/small_vector.hpp>
11#include "vector_test.hpp"
12#include "movable_int.hpp"
13#include "propagate_allocator_test.hpp"
14#include "default_init_test.hpp"
15#include "../../intrusive/test/iterator_test.hpp"
16
17#include <boost/container/allocator_traits.hpp>
18
19#include <iostream>
20
21struct boost_container_small_vector;
22
23namespace boost { namespace container { namespace test {
24
25template<>
26struct alloc_propagate_base<boost_container_small_vector>
27{
28 template <class T, class Allocator>
29 struct apply
30 {
31 typedef boost::container::small_vector<T, 10, Allocator> type;
32 };
33};
34
35}}} //namespace boost::container::test
36
37bool test_small_vector_base_test()
38{
39 typedef boost::container::small_vector_base<int> smb_t;
40 {
41 typedef boost::container::small_vector<int, 5> sm5_t;
42 BOOST_CONTAINER_STATIC_ASSERT(sm5_t::static_capacity == 5);
43 sm5_t sm5;
44 smb_t &smb = sm5;
45 smb.push_back(x: 1);
46 sm5_t sm5_copy(sm5);
47 sm5_copy.push_back(x: 1);
48 if (!boost::container::test::CheckEqualContainers(cont_a: sm5, cont_b: smb))
49 return false;
50 }
51 {
52 typedef boost::container::small_vector<int, 7> sm7_t;
53 BOOST_CONTAINER_STATIC_ASSERT(sm7_t::static_capacity == 7);
54 sm7_t sm7;
55 smb_t &smb = sm7;
56 smb.push_back(x: 2);
57 sm7_t sm7_copy(sm7);
58 sm7_copy.push_back(x: 2);
59 if (!boost::container::test::CheckEqualContainers(cont_a: sm7, cont_b: smb))
60 return false;
61 }
62 {
63 typedef boost::container::small_vector<int, 5> sm5_t;
64 sm5_t sm5;
65 smb_t &smb = sm5;
66 smb.push_back(x: 1);
67 sm5_t sm5_copy(smb);
68 if (!boost::container::test::CheckEqualContainers(cont_a: sm5, cont_b: sm5_copy))
69 return false;
70 smb.push_back(x: 2);
71 if(smb.size() != 2){
72 return false;
73 }
74 sm5_copy = smb;
75 if (!boost::container::test::CheckEqualContainers(cont_a: sm5, cont_b: sm5_copy))
76 return false;
77 sm5_t sm5_move(boost::move(t&: smb));
78 smb.clear();
79 if (!boost::container::test::CheckEqualContainers(cont_a: sm5_move, cont_b: sm5_copy))
80 return false;
81 smb = sm5_copy;
82 sm5_move = boost::move(t&: smb);
83 smb.clear();
84 if (!boost::container::test::CheckEqualContainers(cont_a: sm5_move, cont_b: sm5_copy))
85 return false;
86 }
87
88 return true;
89}
90
91//small vector has internal storage so some special swap cases must be tested
92bool test_swap()
93{
94 typedef boost::container::small_vector<int, 10> vec;
95 { //v bigger than static capacity, w empty
96 vec v;
97 for(std::size_t i = 0, max = v.capacity()+1; i != max; ++i){
98 v.push_back(x: int(i));
99 }
100 vec w;
101 const std::size_t v_size = v.size();
102 const std::size_t w_size = w.size();
103 v.swap(other&: w);
104 if(v.size() != w_size || w.size() != v_size)
105 return false;
106 }
107 { //v smaller than static capacity, w empty
108 vec v;
109 for(std::size_t i = 0, max = v.capacity()-1; i != max; ++i){
110 v.push_back(x: int(i));
111 }
112 vec w;
113 const std::size_t v_size = v.size();
114 const std::size_t w_size = w.size();
115 v.swap(other&: w);
116 if(v.size() != w_size || w.size() != v_size)
117 return false;
118 }
119 { //v & w smaller than static capacity
120 vec v;
121 for(std::size_t i = 0, max = v.capacity()-1; i != max; ++i){
122 v.push_back(x: int(i));
123 }
124 vec w;
125 for(std::size_t i = 0, max = v.capacity()/2; i != max; ++i){
126 w.push_back(x: int(i));
127 }
128 const std::size_t v_size = v.size();
129 const std::size_t w_size = w.size();
130 v.swap(other&: w);
131 if(v.size() != w_size || w.size() != v_size)
132 return false;
133 }
134 { //v & w bigger than static capacity
135 vec v;
136 for(std::size_t i = 0, max = v.capacity()+1; i != max; ++i){
137 v.push_back(x: int(i));
138 }
139 vec w;
140 for(std::size_t i = 0, max = v.capacity()*2; i != max; ++i){
141 w.push_back(x: int(i));
142 }
143 const std::size_t v_size = v.size();
144 const std::size_t w_size = w.size();
145 v.swap(other&: w);
146 if(v.size() != w_size || w.size() != v_size)
147 return false;
148 }
149 return true;
150}
151
152template<class VoidAllocator>
153struct GetAllocatorCont
154{
155 template<class ValueType>
156 struct apply
157 {
158 typedef boost::container::small_vector< ValueType, 10
159 , typename boost::container::allocator_traits<VoidAllocator>
160 ::template portable_rebind_alloc<ValueType>::type
161 > type;
162 };
163};
164
165template<class VoidAllocator>
166int test_cont_variants()
167{
168 using namespace boost::container;
169 typedef typename GetAllocatorCont<VoidAllocator>::template apply<int>::type MyCont;
170 typedef typename GetAllocatorCont<VoidAllocator>::template apply<test::movable_int>::type MyMoveCont;
171 typedef typename GetAllocatorCont<VoidAllocator>::template apply<test::movable_and_copyable_int>::type MyCopyMoveCont;
172 typedef typename GetAllocatorCont<VoidAllocator>::template apply<test::copyable_int>::type MyCopyCont;
173 typedef typename GetAllocatorCont<VoidAllocator>::template apply<test::moveconstruct_int>::type MyMoveConstructCont;
174
175 if (test::vector_test<MyCont>())
176 return 1;
177 if (test::vector_test<MyMoveCont>())
178 return 1;
179 if (test::vector_test<MyCopyMoveCont>())
180 return 1;
181 if (test::vector_test<MyCopyCont>())
182 return 1;
183 if (test::vector_test<MyMoveConstructCont>())
184 return 1;
185
186 return 0;
187}
188
189int main()
190{
191 using namespace boost::container;
192
193 if(!test_swap())
194 return 1;
195
196 if(test::vector_test< small_vector<int, 0> >())
197 return 1;
198
199 if(test::vector_test< small_vector<int, 2000> >())
200 return 1;
201
202 if (test_cont_variants< new_allocator<void> >())
203 return 1;
204
205 ////////////////////////////////////
206 // Default init test
207 ////////////////////////////////////
208 if(!test::default_init_test< small_vector<int, 5, test::default_init_allocator<int> > >()){
209 std::cerr << "Default init test failed" << std::endl;
210 return 1;
211 }
212
213 ////////////////////////////////////
214 // Emplace testing
215 ////////////////////////////////////
216 const test::EmplaceOptions Options = (test::EmplaceOptions)(test::EMPLACE_BACK | test::EMPLACE_BEFORE);
217 if(!boost::container::test::test_emplace< small_vector<test::EmplaceInt, 5>, Options>()){
218 return 1;
219 }
220
221 ////////////////////////////////////
222 // Allocator propagation testing
223 ////////////////////////////////////
224 if(!boost::container::test::test_propagate_allocator<boost_container_small_vector>()){
225 return 1;
226 }
227
228 ////////////////////////////////////
229 // Initializer lists testing
230 ////////////////////////////////////
231 if(!boost::container::test::test_vector_methods_with_initializer_list_as_argument_for
232 < boost::container::small_vector<int, 5> >()) {
233 return 1;
234 }
235
236 ////////////////////////////////////
237 // Small vector base
238 ////////////////////////////////////
239 if (!test_small_vector_base_test()){
240 return 1;
241 }
242
243 ////////////////////////////////////
244 // Iterator testing
245 ////////////////////////////////////
246 {
247 typedef boost::container::small_vector<int, 0> cont_int;
248 cont_int a; a.push_back(x: 0); a.push_back(x: 1); a.push_back(x: 2);
249 boost::intrusive::test::test_iterator_random< cont_int >(c&: a);
250 if(boost::report_errors() != 0) {
251 return 1;
252 }
253 }
254
255 ////////////////////////////////////
256 // has_trivial_destructor_after_move testing
257 ////////////////////////////////////
258 // default allocator
259 {
260 typedef boost::container::small_vector<int, 0> cont;
261 if (boost::has_trivial_destructor_after_move<cont>::value) {
262 std::cerr << "has_trivial_destructor_after_move(default allocator) test failed" << std::endl;
263 return 1;
264 }
265 }
266 // std::allocator
267 {
268 typedef boost::container::small_vector<int, 0, std::allocator<int> > cont;
269 if (boost::has_trivial_destructor_after_move<cont>::value) {
270 std::cerr << "has_trivial_destructor_after_move(std::allocator) test failed" << std::endl;
271 return 1;
272 }
273 }
274
275 return 0;
276}
277

source code of boost/libs/container/test/small_vector_test.cpp