1 // -----------------------------------------------------------
2 // Copyright (c) 2001 Jeremy Siek
3 // Copyright (c) 2003-2006 Gennaro Prota
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)
9 // -----------------------------------------------------------
11 #include "bitset_test.hpp"
12 #include "boost/dynamic_bitset/dynamic_bitset.hpp"
13 #include "boost/limits.hpp"
14 #include "boost/config.hpp"
16 #include "boost/detail/workaround.hpp"
18 #define BOOST_BITSET_TEST_COUNT(x) (sizeof(x)/sizeof(x[0]))
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
28 template <typename Tests, typename String>
29 void run_string_tests(const String& s
30 BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(Tests)
34 const std::size_t len = s.length();
35 const std::size_t step = len/4 ? len/4 : 1;
37 // bitset length determined by the string-related arguments
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
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);
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) )
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)();
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
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)
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 ) {
81 // can match ctor from ulong or templated one
82 Tests::from_unsigned_long(sizes[s], numbers[n]);
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.
94 sz <= static_cast<compare_type>(ma);
97 // can match templated ctor only (so we test dispatching)
98 Tests::from_unsigned_long(static_cast<T>(sizes[s]), numbers[n]);
107 template <typename Block>
108 void run_test_cases( BOOST_EXPLICIT_TEMPLATE_TYPE(Block) )
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;
114 const std::string long_string = get_long_string();
115 const Block all_1s = static_cast<Block>(-1);
117 //=====================================================================
118 // Test construction from unsigned long
120 typedef typename bitset_type::size_type size_type;
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
131 const int sizes[] = {
133 7*bits_per_block/10, bits_per_block, 13*bits_per_block/10, 3*bits_per_block
136 const bool values[] = { false, true };
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]);
145 run_numeric_ctor_tests<Tests, char>();
147 #if !defined(BOOST_NO_INTRINSIC_WCHAR_T)
148 run_numeric_ctor_tests<Tests, wchar_t>();
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>();
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>();
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>();
167 //=====================================================================
168 // Test construction from a string
171 run_string_tests<Tests>(std::string("")); // empty string
172 run_string_tests<Tests>(std::string("1"));
174 run_string_tests<Tests>(long_string);
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)
183 run_string_tests<Tests>(
184 std::wstring(L"11111000000111111111010101010101010101010111111"));
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);
193 //=====================================================================
194 // test from_block_range
196 std::vector<Block> blocks;
197 Tests::from_block_range(blocks);
200 std::vector<Block> blocks(3);
201 blocks[0] = static_cast<Block>(0);
202 blocks[1] = static_cast<Block>(1);
204 Tests::from_block_range(blocks);
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);
213 //=====================================================================
214 // test to_block_range
217 Tests::to_block_range(b);
220 bitset_type b(1, 1ul);
221 Tests::to_block_range(b);
224 bitset_type b(long_string);
225 Tests::to_block_range(b);
228 //=====================================================================
229 // Test copy constructor
231 boost::dynamic_bitset<Block> b;
232 Tests::copy_constructor(b);
235 boost::dynamic_bitset<Block> b(std::string("0"));
236 Tests::copy_constructor(b);
239 boost::dynamic_bitset<Block> b(long_string);
240 Tests::copy_constructor(b);
242 //=====================================================================
243 // Test assignment operator
246 Tests::assignment_operator(a, b);
249 bitset_type a(std::string("1")), b(std::string("0"));
250 Tests::assignment_operator(a, b);
253 bitset_type a(long_string), b(long_string);
254 Tests::assignment_operator(a, b);
258 bitset_type b(long_string); // b greater than a, a empty
259 Tests::assignment_operator(a, b);
262 bitset_type a(std::string("0"));
263 bitset_type b(long_string); // b greater than a
264 Tests::assignment_operator(a, b);
266 //=====================================================================
270 bitset_type b(std::string("1"));
277 bitset_type b(long_string);
282 bitset_type a(std::string("0"));
283 bitset_type b(long_string);
289 //=====================================================================
292 boost::dynamic_bitset<Block> a;
296 boost::dynamic_bitset<Block> a(std::string("0"));
300 boost::dynamic_bitset<Block> a(std::string("1"));
304 boost::dynamic_bitset<Block> a(long_string);
307 //=====================================================================
310 boost::dynamic_bitset<Block> a;
314 boost::dynamic_bitset<Block> a(long_string);
317 //=====================================================================
320 boost::dynamic_bitset<Block> a;
321 Tests::append_bit(a);
324 boost::dynamic_bitset<Block> a(std::string("0"));
325 Tests::append_bit(a);
328 boost::dynamic_bitset<Block> a(std::string("1"));
329 Tests::append_bit(a);
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);
337 boost::dynamic_bitset<Block> a(long_string);
338 Tests::append_bit(a);
340 //=====================================================================
343 boost::dynamic_bitset<Block> a;
344 Tests::append_block(a);
347 boost::dynamic_bitset<Block> a(std::string("0"));
348 Tests::append_block(a);
351 boost::dynamic_bitset<Block> a(std::string("1"));
352 Tests::append_block(a);
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);
360 boost::dynamic_bitset<Block> a(long_string);
361 Tests::append_block(a);
363 //=====================================================================
364 // Test append block range
366 boost::dynamic_bitset<Block> a;
367 std::vector<Block> blocks;
368 Tests::append_block_range(a, blocks);
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);
376 Tests::append_block_range(a, blocks);
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);
387 boost::dynamic_bitset<Block> a;
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);
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);
401 Tests::append_block_range(a, blocks);
403 //=====================================================================
404 // Test bracket operator
406 boost::dynamic_bitset<Block> b1;
407 std::vector<bool> bitvec1;
408 Tests::operator_bracket(b1, bitvec1);
411 boost::dynamic_bitset<Block> b(std::string("1"));
412 std::vector<bool> bit_vec(1, true);
413 Tests::operator_bracket(b, bit_vec);
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);
426 test_main(int, char*[])
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>();