Apply patch for [CVE-2012-2677][boost] ordered_malloc() overflow
[external/boost.git] / libs / dynamic_bitset / dyn_bitset_unit_tests1.cpp
1 // -----------------------------------------------------------
2 //              Copyright (c) 2001 Jeremy Siek
3 //           Copyright (c) 2003-2006 Gennaro Prota
4 //
5 // Distributed under the Boost Software License, Version 1.0.
6 //    (See accompanying file LICENSE_1_0.txt or copy at
7 //          http://www.boost.org/LICENSE_1_0.txt)
8 //
9 // -----------------------------------------------------------
10
11 #include "bitset_test.hpp"
12 #include "boost/dynamic_bitset/dynamic_bitset.hpp"
13 #include "boost/limits.hpp"
14 #include "boost/config.hpp"
15
16 #include "boost/detail/workaround.hpp"
17
18 #define BOOST_BITSET_TEST_COUNT(x) (sizeof(x)/sizeof(x[0]))
19
20
21 // Codewarrior 8.3 for Win fails without this.
22 // Thanks Howard Hinnant ;)
23 #if defined __MWERKS__ && BOOST_WORKAROUND(__MWERKS__, <= 0x3003) // 8.x
24 # pragma parse_func_templ off
25 #endif
26
27
28 template <typename Tests, typename String>
29 void run_string_tests(const String& s
30                       BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(Tests)
31                      )
32 {
33
34   const std::size_t len = s.length();
35   const std::size_t step = len/4 ? len/4 : 1;
36
37   // bitset length determined by the string-related arguments
38   std::size_t i;
39   for (i = 0; i <= len/2 ; i += step) {
40     Tests::from_string(s, i, len/2);     // len/2 - i bits
41     Tests::from_string(s, i, len);       // len - i   bits
42     Tests::from_string(s, i, 1 + len*2); // len - i   bits
43   }
44
45   // bitset length explicitly specified
46   for (i = 0; i <= len/2; i += step) {
47     for (std::size_t sz = 0; sz <= len*4; sz+= step*2) {
48       Tests::from_string(s, i, len/2, sz);
49       Tests::from_string(s, i, len,   sz);
50       Tests::from_string(s, i, 1 + len*2, sz);
51
52       }
53   }
54
55 }
56
57 // tests the do-the-right-thing constructor dispatch
58 template <typename Tests, typename T>
59 void run_numeric_ctor_tests( BOOST_EXPLICIT_TEMPLATE_TYPE(Tests)
60                              BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(T) )
61 {
62
63     const int bits_per_block = Tests::bits_per_block;
64     const int width = std::numeric_limits<T>::digits;
65     const T ma = (std::numeric_limits<T>::max)();
66     const T mi = (std::numeric_limits<T>::min)();
67
68     int sizes[] = {
69         0, 7*width/10,          width,          13*width/10,          3*width,
70            7*bits_per_block/10, bits_per_block, 13*bits_per_block/10, 3*bits_per_block
71     };
72
73     const T numbers[] = {
74               T(-1), T(-3), T(-8), T(-15), T(mi/2), T(mi),
75         T(0), T(1),  T(3),  T(8),  T(15),  T(ma/2), T(ma)
76     };
77
78     for (std::size_t s = 0; s < BOOST_BITSET_TEST_COUNT(sizes); ++s) {
79       for (std::size_t n = 0; n < BOOST_BITSET_TEST_COUNT(numbers); ++n ) {
80
81           // can match ctor from ulong or templated one
82           Tests::from_unsigned_long(sizes[s], numbers[n]);
83
84           typedef std::size_t compare_type;
85           const compare_type sz = sizes[s];
86           // this condition is to be sure that size is representable in T, so
87           // that for signed T's we avoid implementation-defined behavior [if ma
88           // is larger than what std::size_t can hold then this is ok for our
89           // purposes: our sizes are anyhow < max(size_t)], which in turn could
90           // make the first argument of from_unsigned_long() a small negative,
91           // later converted to a very large unsigned. Example: signed 8-bit
92           // char (CHAR_MAX=127), bits_per_block=64, sz = 192 > 127.
93           const bool fits =
94               sz <= static_cast<compare_type>(ma);
95
96           if (fits) {
97             // can match templated ctor only (so we test dispatching)
98             Tests::from_unsigned_long(static_cast<T>(sizes[s]), numbers[n]);
99           }
100
101       }
102     }
103
104 }
105
106
107 template <typename Block>
108 void run_test_cases( BOOST_EXPLICIT_TEMPLATE_TYPE(Block) )
109 {
110   typedef boost::dynamic_bitset<Block> bitset_type;
111   typedef bitset_test<bitset_type> Tests;
112   const int bits_per_block = bitset_type::bits_per_block;
113
114   const std::string long_string = get_long_string();
115   const Block all_1s = static_cast<Block>(-1);
116
117   //=====================================================================
118   // Test construction from unsigned long
119   {
120     typedef typename bitset_type::size_type size_type;
121
122
123     // NOTE:
124     //
125     // 1. keep this in sync with the numeric types supported
126     //    for constructor dispatch (of course)
127     // 2. bool is tested separately; ugly and inelegant, but
128     //    we don't have much time to think of a better solution
129     //    which is likely to work on broken compilers
130     //
131     const int sizes[] = {
132         0,                     1,                                  3,
133            7*bits_per_block/10, bits_per_block, 13*bits_per_block/10, 3*bits_per_block 
134     };
135     
136     const bool values[] = { false, true };
137
138     for (std::size_t s = 0; s < BOOST_BITSET_TEST_COUNT(sizes); ++s) {
139       for (std::size_t v = 0; v < BOOST_BITSET_TEST_COUNT(values); ++v) {
140           Tests::from_unsigned_long(sizes[s], values[v]);
141           Tests::from_unsigned_long(sizes[s] != 0, values[v]);
142       }
143     }
144
145     run_numeric_ctor_tests<Tests, char>();
146
147 #if !defined(BOOST_NO_INTRINSIC_WCHAR_T)
148     run_numeric_ctor_tests<Tests, wchar_t>();
149 #endif
150
151     run_numeric_ctor_tests<Tests, signed char>();
152     run_numeric_ctor_tests<Tests, short int>();
153     run_numeric_ctor_tests<Tests, int>();
154     run_numeric_ctor_tests<Tests, long int>();
155
156     run_numeric_ctor_tests<Tests, unsigned char>();
157     run_numeric_ctor_tests<Tests, unsigned short>();
158     run_numeric_ctor_tests<Tests, unsigned int>();
159     run_numeric_ctor_tests<Tests, unsigned long>();
160
161 #if defined(BOOST_HAS_LONG_LONG)
162     run_numeric_ctor_tests<Tests, ::boost::long_long_type>();
163     run_numeric_ctor_tests<Tests, ::boost::ulong_long_type>();
164 #endif
165
166   }
167   //=====================================================================
168   // Test construction from a string
169   {
170
171     run_string_tests<Tests>(std::string("")); // empty string
172     run_string_tests<Tests>(std::string("1"));
173
174     run_string_tests<Tests>(long_string);
175
176 # if !defined BOOST_NO_STD_WSTRING
177     // I need to decide what to do for non "C" locales here. On
178     // one hand I should have better tests. On the other one
179     // I don't want tests for dynamic_bitset to cope with locales,
180     // ctype::widen, etc. (but that's what you deserve when you
181     // don't separate concerns at the library level)
182     //
183     run_string_tests<Tests>(
184         std::wstring(L"11111000000111111111010101010101010101010111111"));
185 # endif
186
187     // Note that these are _valid_ arguments
188     Tests::from_string(std::string("x11y"), 1, 2);
189     Tests::from_string(std::string("x11"), 1, 10);
190     Tests::from_string(std::string("x11"), 1, 10, 10);
191
192   }
193   //=====================================================================
194   // test from_block_range
195   {
196     std::vector<Block> blocks;
197     Tests::from_block_range(blocks);
198   }
199   {
200     std::vector<Block> blocks(3);
201     blocks[0] = static_cast<Block>(0);
202     blocks[1] = static_cast<Block>(1);
203     blocks[2] = all_1s;
204     Tests::from_block_range(blocks);
205   }
206   {
207     const unsigned int n = (std::numeric_limits<unsigned char>::max)();
208     std::vector<Block> blocks(n);
209     for (typename std::vector<Block>::size_type i = 0; i < n; ++i)
210       blocks[i] = static_cast<Block>(i);
211     Tests::from_block_range(blocks);
212   }
213   //=====================================================================
214   // test to_block_range
215   {
216     bitset_type b;
217     Tests::to_block_range(b);
218   }
219   {
220     bitset_type b(1, 1ul);
221     Tests::to_block_range(b);
222   }
223   {
224     bitset_type b(long_string);
225     Tests::to_block_range(b);
226   }
227
228   //=====================================================================
229   // Test copy constructor
230   {
231     boost::dynamic_bitset<Block> b;
232     Tests::copy_constructor(b);
233   }
234   {
235     boost::dynamic_bitset<Block> b(std::string("0"));
236     Tests::copy_constructor(b);
237   }
238   {
239     boost::dynamic_bitset<Block> b(long_string);
240     Tests::copy_constructor(b);
241   }
242   //=====================================================================
243   // Test assignment operator
244   {
245     bitset_type a, b;
246     Tests::assignment_operator(a, b);
247   }
248   {
249     bitset_type a(std::string("1")), b(std::string("0"));
250     Tests::assignment_operator(a, b);
251   }
252   {
253     bitset_type a(long_string), b(long_string);
254     Tests::assignment_operator(a, b);
255   }
256   {
257     bitset_type a;
258     bitset_type b(long_string); // b greater than a, a empty
259     Tests::assignment_operator(a, b);
260   }
261   {
262     bitset_type a(std::string("0"));
263     bitset_type b(long_string); // b greater than a
264     Tests::assignment_operator(a, b);
265   }
266   //=====================================================================
267   // Test swap
268   {
269     bitset_type a;
270     bitset_type b(std::string("1"));
271     Tests::swap(a, b);
272     Tests::swap(b, a);
273     Tests::swap(a, a);
274   }
275   {
276     bitset_type a;
277     bitset_type b(long_string);
278     Tests::swap(a, b);
279     Tests::swap(b, a);
280   }
281   {
282     bitset_type a(std::string("0"));
283     bitset_type b(long_string);
284     Tests::swap(a, b);
285     Tests::swap(b, a);
286     Tests::swap(a, a);
287     Tests::swap(b, b);
288   }
289   //=====================================================================
290   // Test resize
291   {
292     boost::dynamic_bitset<Block> a;
293     Tests::resize(a);
294   }
295   {
296     boost::dynamic_bitset<Block> a(std::string("0"));
297     Tests::resize(a);
298   }
299   {
300     boost::dynamic_bitset<Block> a(std::string("1"));
301     Tests::resize(a);
302   }
303   {
304     boost::dynamic_bitset<Block> a(long_string);
305     Tests::resize(a);
306   }
307   //=====================================================================
308   // Test clear
309   {
310     boost::dynamic_bitset<Block> a;
311     Tests::clear(a);
312   }
313   {
314     boost::dynamic_bitset<Block> a(long_string);
315     Tests::clear(a);
316   }
317   //=====================================================================
318   // Test append bit
319   {
320     boost::dynamic_bitset<Block> a;
321     Tests::append_bit(a);
322   }
323   {
324     boost::dynamic_bitset<Block> a(std::string("0"));
325     Tests::append_bit(a);
326   }
327   {
328     boost::dynamic_bitset<Block> a(std::string("1"));
329     Tests::append_bit(a);
330   }
331   {
332     const int size_to_fill_all_blocks = 4 * bits_per_block;
333     boost::dynamic_bitset<Block> a(size_to_fill_all_blocks, 255ul);
334     Tests::append_bit(a);
335   }
336   {
337     boost::dynamic_bitset<Block> a(long_string);
338     Tests::append_bit(a);
339   }
340   //=====================================================================
341   // Test append block
342   {
343     boost::dynamic_bitset<Block> a;
344     Tests::append_block(a);
345   }
346   {
347     boost::dynamic_bitset<Block> a(std::string("0"));
348     Tests::append_block(a);
349   }
350   {
351     boost::dynamic_bitset<Block> a(std::string("1"));
352     Tests::append_block(a);
353   }
354   {
355     const int size_to_fill_all_blocks = 4 * bits_per_block;
356     boost::dynamic_bitset<Block> a(size_to_fill_all_blocks, 15ul);
357     Tests::append_block(a);
358   }
359   {
360     boost::dynamic_bitset<Block> a(long_string);
361     Tests::append_block(a);
362   }
363   //=====================================================================
364   // Test append block range
365   {
366     boost::dynamic_bitset<Block> a;
367     std::vector<Block> blocks;
368     Tests::append_block_range(a, blocks);
369   }
370   {
371     boost::dynamic_bitset<Block> a(std::string("0"));
372     std::vector<Block> blocks(3);
373     blocks[0] = static_cast<Block>(0);
374     blocks[1] = static_cast<Block>(1);
375     blocks[2] = all_1s;
376     Tests::append_block_range(a, blocks);
377   }
378   {
379     boost::dynamic_bitset<Block> a(std::string("1"));
380     const unsigned int n = (std::numeric_limits<unsigned char>::max)();
381     std::vector<Block> blocks(n);
382     for (typename std::vector<Block>::size_type i = 0; i < n; ++i)
383       blocks[i] = static_cast<Block>(i);
384     Tests::append_block_range(a, blocks);
385   }
386   {
387     boost::dynamic_bitset<Block> a;
388     a.append(Block(1));
389     a.append(Block(2));
390     Block x[] = {3, 4, 5};
391     std::size_t sz = sizeof(x) / sizeof(x[0]);
392     std::vector<Block> blocks(x, x + sz);
393     Tests::append_block_range(a, blocks);
394   }
395   {
396     boost::dynamic_bitset<Block> a(long_string);
397     std::vector<Block> blocks(3);
398     blocks[0] = static_cast<Block>(0);
399     blocks[1] = static_cast<Block>(1);
400     blocks[2] = all_1s;
401     Tests::append_block_range(a, blocks);
402   }
403   //=====================================================================
404   // Test bracket operator
405   {
406     boost::dynamic_bitset<Block> b1;
407     std::vector<bool> bitvec1;
408     Tests::operator_bracket(b1, bitvec1);
409   }
410   {
411     boost::dynamic_bitset<Block> b(std::string("1"));
412     std::vector<bool> bit_vec(1, true);
413     Tests::operator_bracket(b, bit_vec);
414   }
415   {
416     boost::dynamic_bitset<Block> b(long_string);
417     std::size_t n = long_string.size();
418     std::vector<bool> bit_vec(n);
419     for (std::size_t i = 0; i < n; ++i)
420       bit_vec[i] = long_string[n - 1 - i] == '0' ? 0 : 1;
421     Tests::operator_bracket(b, bit_vec);
422   }
423 }
424
425 int
426 test_main(int, char*[])
427 {
428   run_test_cases<unsigned char>();
429   run_test_cases<unsigned short>();
430   run_test_cases<unsigned int>();
431   run_test_cases<unsigned long>();
432 # ifdef BOOST_HAS_LONG_LONG
433   run_test_cases< ::boost::ulong_long_type>();
434 # endif
435
436   return 0;
437 }