// ----------------------------------------------------------- // Copyright (c) 2001 Jeremy Siek // Copyright (c) 2003-2006 Gennaro Prota // Copyright (c) 2014 Ahmed Charles // Copyright (c) 2014 Riccardo Marcangelo // // Copyright (c) 2014 Glen Joseph Fernandes // (glenjofe@gmail.com) // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // ----------------------------------------------------------- #include "bitset_test.hpp" #include #include #include #include #if !defined(BOOST_NO_CXX11_ALLOCATOR) #include template class minimal_allocator { public: typedef T value_type; minimal_allocator() {} template minimal_allocator(const minimal_allocator&) {} T* allocate(std::size_t n) { void* p = std::malloc(sizeof(T) * n); if (!p) { throw std::bad_alloc(); } return static_cast(p); } void deallocate(T* p, std::size_t) { std::free(p); } }; #endif #define BOOST_BITSET_TEST_COUNT(x) (sizeof(x)/sizeof(x[0])) // Codewarrior 8.3 for Win fails without this. // Thanks Howard Hinnant ;) #if defined __MWERKS__ && BOOST_WORKAROUND(__MWERKS__, <= 0x3003) // 8.x # pragma parse_func_templ off #endif template void run_string_tests(const String& s BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(Tests) ) { const std::size_t len = s.length(); const std::size_t step = len/4 ? len/4 : 1; // bitset length determined by the string-related arguments std::size_t i; for (i = 0; i <= len/2 ; i += step) { Tests::from_string(s, i, len/2); // len/2 - i bits Tests::from_string(s, i, len); // len - i bits Tests::from_string(s, i, 1 + len*2); // len - i bits } // bitset length explicitly specified for (i = 0; i <= len/2; i += step) { for (std::size_t sz = 0; sz <= len*4; sz+= step*2) { Tests::from_string(s, i, len/2, sz); Tests::from_string(s, i, len, sz); Tests::from_string(s, i, 1 + len*2, sz); } } } // tests the do-the-right-thing constructor dispatch template void run_numeric_ctor_tests( BOOST_EXPLICIT_TEMPLATE_TYPE(Tests) BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(T) ) { const int bits_per_block = Tests::bits_per_block; const int width = std::numeric_limits::digits; const T ma = (std::numeric_limits::max)(); const T mi = (std::numeric_limits::min)(); int sizes[] = { 0, 7*width/10, width, 13*width/10, 3*width, 7*bits_per_block/10, bits_per_block, 13*bits_per_block/10, 3*bits_per_block }; const T numbers[] = { T(-1), T(-3), T(-8), T(-15), T(mi/2), T(mi), T(0), T(1), T(3), T(8), T(15), T(ma/2), T(ma) }; for (std::size_t s = 0; s < BOOST_BITSET_TEST_COUNT(sizes); ++s) { for (std::size_t n = 0; n < BOOST_BITSET_TEST_COUNT(numbers); ++n ) { // can match ctor from ulong or templated one Tests::from_unsigned_long(sizes[s], numbers[n]); typedef std::size_t compare_type; const compare_type sz = sizes[s]; // this condition is to be sure that size is representable in T, so // that for signed T's we avoid implementation-defined behavior [if ma // is larger than what std::size_t can hold then this is ok for our // purposes: our sizes are anyhow < max(size_t)], which in turn could // make the first argument of from_unsigned_long() a small negative, // later converted to a very large unsigned. Example: signed 8-bit // char (CHAR_MAX=127), bits_per_block=64, sz = 192 > 127. const bool fits = sz <= static_cast(ma); if (fits) { // can match templated ctor only (so we test dispatching) Tests::from_unsigned_long(static_cast(sizes[s]), numbers[n]); } } } } template void run_test_cases( BOOST_EXPLICIT_TEMPLATE_TYPE(Block) ) { typedef boost::dynamic_bitset bitset_type; typedef bitset_test Tests; const int bits_per_block = bitset_type::bits_per_block; const std::string long_string = get_long_string(); const Block all_1s = static_cast(-1); //===================================================================== // Test construction from unsigned long { // NOTE: // // 1. keep this in sync with the numeric types supported // for constructor dispatch (of course) // 2. bool is tested separately; ugly and inelegant, but // we don't have much time to think of a better solution // which is likely to work on broken compilers // const int sizes[] = { 0, 1, 3, 7*bits_per_block/10, bits_per_block, 13*bits_per_block/10, 3*bits_per_block }; const bool values[] = { false, true }; for (std::size_t s = 0; s < BOOST_BITSET_TEST_COUNT(sizes); ++s) { for (std::size_t v = 0; v < BOOST_BITSET_TEST_COUNT(values); ++v) { Tests::from_unsigned_long(sizes[s], values[v]); Tests::from_unsigned_long(sizes[s] != 0, values[v]); } } run_numeric_ctor_tests(); #if !defined(BOOST_NO_INTRINSIC_WCHAR_T) run_numeric_ctor_tests(); #endif run_numeric_ctor_tests(); run_numeric_ctor_tests(); run_numeric_ctor_tests(); run_numeric_ctor_tests(); run_numeric_ctor_tests(); run_numeric_ctor_tests(); run_numeric_ctor_tests(); run_numeric_ctor_tests(); #if defined(BOOST_HAS_LONG_LONG) run_numeric_ctor_tests(); run_numeric_ctor_tests(); #endif } //===================================================================== // Test construction from a string { run_string_tests(std::string("")); // empty string run_string_tests(std::string("1")); run_string_tests(long_string); # if !defined BOOST_NO_STD_WSTRING // I need to decide what to do for non "C" locales here. On // one hand I should have better tests. On the other one // I don't want tests for dynamic_bitset to cope with locales, // ctype::widen, etc. (but that's what you deserve when you // don't separate concerns at the library level) // run_string_tests( std::wstring(L"11111000000111111111010101010101010101010111111")); # endif // Note that these are _valid_ arguments Tests::from_string(std::string("x11y"), 1, 2); Tests::from_string(std::string("x11"), 1, 10); Tests::from_string(std::string("x11"), 1, 10, 10); } //===================================================================== // test from_block_range { std::vector blocks; Tests::from_block_range(blocks); } { std::vector blocks(3); blocks[0] = static_cast(0); blocks[1] = static_cast(1); blocks[2] = all_1s; Tests::from_block_range(blocks); } { const unsigned int n = (std::numeric_limits::max)(); std::vector blocks(n); for (typename std::vector::size_type i = 0; i < n; ++i) blocks[i] = static_cast(i); Tests::from_block_range(blocks); } //===================================================================== // test to_block_range { bitset_type b; Tests::to_block_range(b); } { bitset_type b(1, 1ul); Tests::to_block_range(b); } { bitset_type b(long_string); Tests::to_block_range(b); } //===================================================================== // Test copy constructor { boost::dynamic_bitset b; Tests::copy_constructor(b); } { boost::dynamic_bitset b(std::string("0")); Tests::copy_constructor(b); } { boost::dynamic_bitset b(long_string); Tests::copy_constructor(b); } //===================================================================== // Test copy assignment operator { bitset_type a, b; Tests::copy_assignment_operator(a, b); } { bitset_type a(std::string("1")), b(std::string("0")); Tests::copy_assignment_operator(a, b); } { bitset_type a(long_string), b(long_string); Tests::copy_assignment_operator(a, b); } { bitset_type a; bitset_type b(long_string); // b greater than a, a empty Tests::copy_assignment_operator(a, b); } { bitset_type a(std::string("0")); bitset_type b(long_string); // b greater than a Tests::copy_assignment_operator(a, b); } #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES //===================================================================== // Test move constructor { boost::dynamic_bitset b; Tests::move_constructor(b); } { boost::dynamic_bitset b(std::string("0")); Tests::move_constructor(b); } { boost::dynamic_bitset b(long_string); Tests::move_constructor(b); } //===================================================================== // Test move assignment operator { bitset_type a, b; Tests::move_assignment_operator(a, b); } { bitset_type a(std::string("1")), b(std::string("0")); Tests::move_assignment_operator(a, b); } { bitset_type a(long_string), b(long_string); Tests::move_assignment_operator(a, b); } { bitset_type a; bitset_type b(long_string); // b greater than a, a empty Tests::move_assignment_operator(a, b); } { bitset_type a(std::string("0")); bitset_type b(long_string); // b greater than a Tests::move_assignment_operator(a, b); } #endif // BOOST_NO_CXX11_RVALUE_REFERENCES //===================================================================== // Test swap { bitset_type a; bitset_type b(std::string("1")); Tests::swap(a, b); Tests::swap(b, a); Tests::swap(a, a); } { bitset_type a; bitset_type b(long_string); Tests::swap(a, b); Tests::swap(b, a); } { bitset_type a(std::string("0")); bitset_type b(long_string); Tests::swap(a, b); Tests::swap(b, a); Tests::swap(a, a); Tests::swap(b, b); } //===================================================================== // Test resize { boost::dynamic_bitset a; Tests::resize(a); } { boost::dynamic_bitset a(std::string("0")); Tests::resize(a); } { boost::dynamic_bitset a(std::string("1")); Tests::resize(a); } { boost::dynamic_bitset a(long_string); Tests::resize(a); } //===================================================================== // Test clear { boost::dynamic_bitset a; Tests::clear(a); } { boost::dynamic_bitset a(long_string); Tests::clear(a); } //===================================================================== // Test pop back { boost::dynamic_bitset a(std::string("01")); Tests::pop_back(a); } { boost::dynamic_bitset a(std::string("10")); Tests::pop_back(a); } { const int size_to_fill_all_blocks = 4 * bits_per_block; boost::dynamic_bitset a(size_to_fill_all_blocks, 255ul); Tests::pop_back(a); } { boost::dynamic_bitset a(long_string); Tests::pop_back(a); } //===================================================================== // Test append bit { boost::dynamic_bitset a; Tests::append_bit(a); } { boost::dynamic_bitset a(std::string("0")); Tests::append_bit(a); } { boost::dynamic_bitset a(std::string("1")); Tests::append_bit(a); } { const int size_to_fill_all_blocks = 4 * bits_per_block; boost::dynamic_bitset a(size_to_fill_all_blocks, 255ul); Tests::append_bit(a); } { boost::dynamic_bitset a(long_string); Tests::append_bit(a); } //===================================================================== // Test append block { boost::dynamic_bitset a; Tests::append_block(a); } { boost::dynamic_bitset a(std::string("0")); Tests::append_block(a); } { boost::dynamic_bitset a(std::string("1")); Tests::append_block(a); } { const int size_to_fill_all_blocks = 4 * bits_per_block; boost::dynamic_bitset a(size_to_fill_all_blocks, 15ul); Tests::append_block(a); } { boost::dynamic_bitset a(long_string); Tests::append_block(a); } //===================================================================== // Test append block range { boost::dynamic_bitset a; std::vector blocks; Tests::append_block_range(a, blocks); } { boost::dynamic_bitset a(std::string("0")); std::vector blocks(3); blocks[0] = static_cast(0); blocks[1] = static_cast(1); blocks[2] = all_1s; Tests::append_block_range(a, blocks); } { boost::dynamic_bitset a(std::string("1")); const unsigned int n = (std::numeric_limits::max)(); std::vector blocks(n); for (typename std::vector::size_type i = 0; i < n; ++i) blocks[i] = static_cast(i); Tests::append_block_range(a, blocks); } { boost::dynamic_bitset a; a.append(Block(1)); a.append(Block(2)); Block x[] = {3, 4, 5}; std::size_t sz = sizeof(x) / sizeof(x[0]); std::vector blocks(x, x + sz); Tests::append_block_range(a, blocks); } { boost::dynamic_bitset a(long_string); std::vector blocks(3); blocks[0] = static_cast(0); blocks[1] = static_cast(1); blocks[2] = all_1s; Tests::append_block_range(a, blocks); } //===================================================================== // Test bracket operator { boost::dynamic_bitset b1; std::vector bitvec1; Tests::operator_bracket(b1, bitvec1); } { boost::dynamic_bitset b(std::string("1")); std::vector bit_vec(1, true); Tests::operator_bracket(b, bit_vec); } { boost::dynamic_bitset b(long_string); std::size_t n = long_string.size(); std::vector bit_vec(n); for (std::size_t i = 0; i < n; ++i) bit_vec[i] = long_string[n - 1 - i] == '0' ? 0 : 1; Tests::operator_bracket(b, bit_vec); } #if !defined(BOOST_NO_CXX11_ALLOCATOR) { typedef boost::dynamic_bitset > Bitset; Bitset b; bitset_test::max_size(b); } #endif // Test copy-initialize with default constructor { boost::dynamic_bitset b[1] = {}; (void)b; } } int main() { run_test_cases(); run_test_cases(); run_test_cases(); run_test_cases(); # ifdef BOOST_HAS_LONG_LONG run_test_cases< ::boost::ulong_long_type>(); # endif return boost::report_errors(); }