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