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/devector.hpp>
11#include <boost/container/allocator.hpp>
12#include <boost/container/detail/next_capacity.hpp>
13#include <boost/core/lightweight_test.hpp>
14
15using namespace boost::container;
16
17template<class Unsigned, class DevectorType>
18void test_stored_size_type_impl()
19{
20 #ifndef BOOST_NO_EXCEPTIONS
21 DevectorType v;
22 typedef typename DevectorType::size_type size_type;
23 typedef typename DevectorType::value_type value_type;
24 size_type const max = Unsigned(-1);
25 v.resize(5);
26 v.resize(max);
27 BOOST_TEST_THROWS(v.resize(max+1), std::exception);
28 BOOST_TEST_THROWS(v.push_back(value_type(1)), std::exception);
29 BOOST_TEST_THROWS(v.insert(v.begin(), value_type(1)), std::exception);
30 BOOST_TEST_THROWS(v.emplace(v.begin(), value_type(1)),std::exception);
31 BOOST_TEST_THROWS(v.reserve(max+1), std::exception);
32 BOOST_TEST_THROWS(DevectorType v2(max+1), std::exception);
33 #endif
34}
35
36template<class Unsigned>
37void test_stored_size_type()
38{
39 #if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES)
40 using options_t = devector_options_t< stored_size<Unsigned> >;
41 #else
42 typedef typename devector_options
43 < stored_size<Unsigned> >::type options_t;
44 #endif
45
46 //Test first with a typical allocator
47 {
48 typedef devector<unsigned char, new_allocator<unsigned char>, options_t> devector_t;
49 test_stored_size_type_impl<Unsigned, devector_t>();
50 }
51 //Test with a V2 allocator
52 {
53 typedef devector<unsigned char, allocator<unsigned char>, options_t> devector_t;
54 test_stored_size_type_impl<Unsigned, devector_t>();
55 }
56 //Test size reduction
57 {
58 typedef devector<unsigned char, void, options_t> devector_t;
59 BOOST_CONTAINER_STATIC_ASSERT( sizeof(Unsigned) >= sizeof(std::size_t) ||
60 sizeof(devector_t) < sizeof(devector<unsigned char>) );
61 }
62
63}
64
65void test_growth_factor_50()
66{
67 #if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES)
68 using options_t = devector_options_t< growth_factor<growth_factor_50> >;
69 #else
70 typedef devector_options
71 < growth_factor<growth_factor_50> >::type options_t;
72 #endif
73
74 devector<int, new_allocator<int>, options_t> v(5u, 0);
75 std::size_t old_capacity = v.size() + v.back_free_capacity() + v.front_free_capacity();
76 v.push_back(x: 0);
77 std::size_t new_capacity = v.size() + v.back_free_capacity() + v.front_free_capacity();
78 BOOST_TEST(new_capacity == old_capacity + old_capacity/2);
79}
80
81void test_growth_factor_60()
82{
83 #if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES)
84 using options_t = devector_options_t< growth_factor<growth_factor_60> >;
85 #else
86 typedef devector_options
87 < growth_factor<growth_factor_60> >::type options_t;
88 #endif
89
90 devector<int, new_allocator<int>, options_t> v(5u, 0);
91
92 std::size_t old_capacity = v.size()+v.back_free_capacity()+v.front_free_capacity();
93 v.push_back(x: 0);
94 std::size_t new_capacity = v.size() + v.back_free_capacity() + v.front_free_capacity();
95 BOOST_TEST(new_capacity == old_capacity + 3*old_capacity/5);
96}
97
98void test_growth_factor_100()
99{
100 #if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES)
101 using options_t = devector_options_t< growth_factor<growth_factor_100> >;
102 #else
103 typedef devector_options
104 < growth_factor<growth_factor_100> >::type options_t;
105 #endif
106
107 devector<int, new_allocator<int>, options_t> v(5,0);
108 std::size_t old_capacity = v.size() + v.back_free_capacity() + v.front_free_capacity();
109 v.push_back(x: 0);
110 std::size_t new_capacity = v.size() + v.back_free_capacity() + v.front_free_capacity();
111 BOOST_TEST(new_capacity == 2*old_capacity);
112}
113
114
115void test_stored_reloc_on_66()
116{
117 #if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES)
118 using options_t = devector_options_t< relocate_on_66 >;
119 #else
120 typedef devector_options
121 < relocate_on_66 >::type options_t;
122 #endif
123 const std::size_t buffer_size = 32u;
124 const std::size_t initial_side = buffer_size/2u;
125
126 devector<int, new_allocator<int>, options_t> v(initial_side, initial_side, reserve_only_tag_t());
127
128 const int* buffer = v.data();
129 const int* buffer_start = v.data() - initial_side;
130 std::size_t old_cp = v.capacity();
131 for ( int i = 0u; i != (int)initial_side; ++i) {
132 v.push_back(x: i);
133 }
134 BOOST_TEST(v.back_free_capacity() == 0);
135 BOOST_TEST(buffer == v.data());
136 v.push_back(x: 0);
137 BOOST_TEST(v.size() == initial_side + 1u);
138 //Relocation -> 9 elements on the left, 8 elements on the right
139 BOOST_TEST(v.front_free_capacity() == (buffer_size - v.size())/2u);
140 BOOST_TEST(v.data() == buffer_start + v.front_free_capacity());
141 BOOST_TEST(v.capacity() == old_cp);
142
143 //Reach the back limit again
144 for (int i = 0u, max = (int)v.back_free_capacity(); i != max; ++i) {
145 v.push_back(x: -i);
146 }
147 BOOST_TEST(v.back_free_capacity() == 0);
148
149 //New insertion should reallocate
150 v.push_back(x: -1);
151 BOOST_TEST(v.back_free_capacity() > initial_side/2u);
152 BOOST_TEST(v.capacity() > old_cp);
153}
154
155void test_stored_reloc_on_90()
156{
157 #if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES)
158 using options_t = devector_options_t< relocate_on_90 >;
159 #else
160 typedef devector_options< relocate_on_90 >::type options_t;
161 #endif
162
163 const std::size_t buffer_size = 32u;
164 const std::size_t initial_side = buffer_size/2u;
165
166 devector<int, new_allocator<int>, options_t> v(initial_side, initial_side, reserve_only_tag_t());
167
168 const int* buffer = v.data();
169 const int* buffer_start = v.data() - initial_side;
170 std::size_t old_cp = v.capacity();
171 for ( int i = 0u; i != (int)initial_side; ++i) {
172 v.push_back(x: i);
173 }
174 BOOST_TEST(v.back_free_capacity() == 0);
175 BOOST_TEST(buffer == v.data());
176 v.push_back(x: 0);
177 BOOST_TEST(v.size() == initial_side + 1u);
178 //Relocation -> 9 elements on the left, 8 elements on the right
179 BOOST_TEST(v.front_free_capacity() == (buffer_size - v.size())/2u);
180 BOOST_TEST(v.data() == buffer_start + v.front_free_capacity());
181 BOOST_TEST(v.capacity() == old_cp);
182
183 //Reach the back limit again
184 for (int i = 0u, max = (int)v.back_free_capacity(); i != max; ++i) {
185 v.push_back(x: -i);
186 }
187 BOOST_TEST(v.back_free_capacity() == 0);
188
189 //New insertion should relocate again
190 v.push_back(x: -1);
191 BOOST_TEST(v.capacity() == old_cp);
192 BOOST_TEST(v.front_free_capacity() == (buffer_size - v.size()) / 2u);
193 BOOST_TEST(v.data() == buffer_start + v.front_free_capacity());
194
195 //Reach the back limit again
196 for (int i = 0u, max = (int)v.back_free_capacity(); i != max; ++i) {
197 v.push_back(x: -i);
198 }
199 BOOST_TEST(v.back_free_capacity() == 0);
200
201 //Last insertion should reallocate
202 v.push_back(x: -1);
203 BOOST_TEST(v.capacity() > old_cp);
204}
205
206int main()
207{
208 test_growth_factor_50();
209 test_growth_factor_60();
210 test_growth_factor_100();
211 test_stored_size_type<unsigned char>();
212 test_stored_size_type<unsigned short>();
213 test_stored_reloc_on_66();
214 test_stored_reloc_on_90();
215 return ::boost::report_errors();
216}
217

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