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.hpp>
18
19 #include <iostream>
20
21 struct boost_container_small_vector;
22
23 namespace boost { namespace container { namespace test {
24
25 template<>
26 struct 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
test_small_vector_base_test()37 bool 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_STATIC_ASSERT(sm5_t::static_capacity == 5);
43 sm5_t sm5;
44 smb_t &smb = sm5;
45 smb.push_back(1);
46 sm5_t sm5_copy(sm5);
47 sm5_copy.push_back(1);
48 if (!boost::container::test::CheckEqualContainers(sm5, smb))
49 return false;
50 }
51 {
52 typedef boost::container::small_vector<int, 7> sm7_t;
53 BOOST_STATIC_ASSERT(sm7_t::static_capacity == 7);
54 sm7_t sm7;
55 smb_t &smb = sm7;
56 smb.push_back(2);
57 sm7_t sm7_copy(sm7);
58 sm7_copy.push_back(2);
59 if (!boost::container::test::CheckEqualContainers(sm7, 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(1);
67 sm5_t sm5_copy(smb);
68 if (!boost::container::test::CheckEqualContainers(sm5, sm5_copy))
69 return false;
70 smb.push_back(2);
71 if(smb.size() != 2){
72 return false;
73 }
74 sm5_copy = smb;
75 if (!boost::container::test::CheckEqualContainers(sm5, sm5_copy))
76 return false;
77 sm5_t sm5_move(boost::move(smb));
78 smb.clear();
79 if (!boost::container::test::CheckEqualContainers(sm5_move, sm5_copy))
80 return false;
81 smb = sm5_copy;
82 sm5_move = boost::move(smb);
83 smb.clear();
84 if (!boost::container::test::CheckEqualContainers(sm5_move, 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
test_swap()92 bool 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(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(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(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(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(int(i));
123 }
124 vec w;
125 for(std::size_t i = 0, max = v.capacity()/2; i != max; ++i){
126 w.push_back(int(i));
127 }
128 const std::size_t v_size = v.size();
129 const std::size_t w_size = w.size();
130 v.swap(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(int(i));
138 }
139 vec w;
140 for(std::size_t i = 0, max = v.capacity()*2; i != max; ++i){
141 w.push_back(int(i));
142 }
143 const std::size_t v_size = v.size();
144 const std::size_t w_size = w.size();
145 v.swap(w);
146 if(v.size() != w_size || w.size() != v_size)
147 return false;
148 }
149 return true;
150 }
151
main()152 int main()
153 {
154 using namespace boost::container;
155
156 if(!test_swap())
157 return 1;
158
159 if(test::vector_test< small_vector<int, 0> >())
160 return 1;
161
162 if(test::vector_test< small_vector<int, 2000> >())
163 return 1;
164
165 ////////////////////////////////////
166 // Default init test
167 ////////////////////////////////////
168 if(!test::default_init_test< small_vector<int, 5, test::default_init_allocator<int> > >()){
169 std::cerr << "Default init test failed" << std::endl;
170 return 1;
171 }
172
173 ////////////////////////////////////
174 // Emplace testing
175 ////////////////////////////////////
176 const test::EmplaceOptions Options = (test::EmplaceOptions)(test::EMPLACE_BACK | test::EMPLACE_BEFORE);
177 if(!boost::container::test::test_emplace< small_vector<test::EmplaceInt, 5>, Options>()){
178 return 1;
179 }
180
181 ////////////////////////////////////
182 // Allocator propagation testing
183 ////////////////////////////////////
184 if(!boost::container::test::test_propagate_allocator<boost_container_small_vector>()){
185 return 1;
186 }
187
188 ////////////////////////////////////
189 // Initializer lists testing
190 ////////////////////////////////////
191 if(!boost::container::test::test_vector_methods_with_initializer_list_as_argument_for
192 < boost::container::small_vector<int, 5> >()) {
193 return 1;
194 }
195
196 ////////////////////////////////////
197 // Small vector base
198 ////////////////////////////////////
199 if (!test_small_vector_base_test()){
200 return 1;
201 }
202
203 ////////////////////////////////////
204 // Iterator testing
205 ////////////////////////////////////
206 {
207 typedef boost::container::small_vector<int, 0> cont_int;
208 cont_int a; a.push_back(0); a.push_back(1); a.push_back(2);
209 boost::intrusive::test::test_iterator_random< cont_int >(a);
210 if(boost::report_errors() != 0) {
211 return 1;
212 }
213 }
214
215 ////////////////////////////////////
216 // has_trivial_destructor_after_move testing
217 ////////////////////////////////////
218 // default allocator
219 {
220 typedef boost::container::small_vector<int, 0> cont;
221 if (boost::has_trivial_destructor_after_move<cont>::value) {
222 std::cerr << "has_trivial_destructor_after_move(default allocator) test failed" << std::endl;
223 return 1;
224 }
225 }
226 // std::allocator
227 {
228 typedef boost::container::small_vector<int, 0, std::allocator<int> > cont;
229 if (boost::has_trivial_destructor_after_move<cont>::value) {
230 std::cerr << "has_trivial_destructor_after_move(std::allocator) test failed" << std::endl;
231 return 1;
232 }
233 }
234
235 return 0;
236 }
237