Files
dynamic_bitset/test/dyn_bitset_unit_tests1.cpp
Gennaro Prota e00b0048f9 Clean up all the #include sections
This commit:

- Sorts the #include directives: The #includes of the ""-form come
  first, those of the <>-form come later (this helps checking if any
  include file is not self-sufficient); in each of the two groups, the
  names of the headers or source files are sorted alphabetically (this
  eases searching for a specific #include and avoids duplicates).

- Uses the ""-form when including Boost files; using the <>-form is a
  relic of the past. This was even discussed on the developers list many
  years ago and led to core issue 370. Note that some parts of
  DynamicBitset were already using the ""-form and that has never caused
  any problem, AFAIK.

- Removes some comments attached to the directives themselves which
  seemed pretty useless and prone to get out of sync.
2025-09-11 12:31:09 +02:00

559 lines
16 KiB
C++

// -----------------------------------------------------------
// Copyright (c) 2001 Jeremy Siek
// Copyright (c) 2003-2006, 2025 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 "boost/config.hpp"
#include "boost/config/workaround.hpp"
#include "boost/dynamic_bitset/dynamic_bitset.hpp"
#include "boost/limits.hpp"
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
#include <cstdlib>
template<class T>
class minimal_allocator {
public:
typedef T value_type;
minimal_allocator() {}
template <typename U>
minimal_allocator(const minimal_allocator<U>&) {}
T* allocate(std::size_t n) {
void* p = std::malloc(sizeof(T) * n);
if (!p) {
throw std::bad_alloc();
}
return static_cast<T*>(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 <typename Tests, typename String>
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 <typename Tests, typename T>
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<T>::digits;
const T ma = (std::numeric_limits<T>::max)();
const T mi = (std::numeric_limits<T>::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<compare_type>(ma);
if (fits) {
// can match templated ctor only (so we test dispatching)
Tests::from_unsigned_long(static_cast<T>(sizes[s]), numbers[n]);
}
}
}
}
template <typename Block>
void run_test_cases( BOOST_EXPLICIT_TEMPLATE_TYPE(Block) )
{
typedef boost::dynamic_bitset<Block> bitset_type;
typedef bitset_test<bitset_type> 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<Block>(-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<Tests, char>();
#if !defined(BOOST_NO_INTRINSIC_WCHAR_T)
run_numeric_ctor_tests<Tests, wchar_t>();
#endif
run_numeric_ctor_tests<Tests, signed char>();
run_numeric_ctor_tests<Tests, short int>();
run_numeric_ctor_tests<Tests, int>();
run_numeric_ctor_tests<Tests, long int>();
run_numeric_ctor_tests<Tests, unsigned char>();
run_numeric_ctor_tests<Tests, unsigned short>();
run_numeric_ctor_tests<Tests, unsigned int>();
run_numeric_ctor_tests<Tests, unsigned long>();
#if defined(BOOST_HAS_LONG_LONG)
run_numeric_ctor_tests<Tests, ::boost::long_long_type>();
run_numeric_ctor_tests<Tests, ::boost::ulong_long_type>();
#endif
}
//=====================================================================
// Test construction from a string
{
run_string_tests<Tests>(std::string("")); // empty string
run_string_tests<Tests>(std::string("1"));
run_string_tests<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<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<Block> blocks;
Tests::from_block_range(blocks);
}
{
std::vector<Block> blocks(3);
blocks[0] = static_cast<Block>(0);
blocks[1] = static_cast<Block>(1);
blocks[2] = all_1s;
Tests::from_block_range(blocks);
}
{
const unsigned int n = (std::numeric_limits<unsigned char>::max)();
std::vector<Block> blocks(n);
for (typename std::vector<Block>::size_type i = 0; i < n; ++i)
blocks[i] = static_cast<Block>(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<Block> b;
Tests::copy_constructor(b);
}
{
boost::dynamic_bitset<Block> b(std::string("0"));
Tests::copy_constructor(b);
}
{
boost::dynamic_bitset<Block> 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<Block> b;
Tests::move_constructor(b);
}
{
boost::dynamic_bitset<Block> b(std::string("0"));
Tests::move_constructor(b);
}
{
boost::dynamic_bitset<Block> 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<Block> a;
Tests::resize(a);
}
{
boost::dynamic_bitset<Block> a(std::string("0"));
Tests::resize(a);
}
{
boost::dynamic_bitset<Block> a(std::string("1"));
Tests::resize(a);
}
{
boost::dynamic_bitset<Block> a(long_string);
Tests::resize(a);
}
//=====================================================================
// Test clear
{
boost::dynamic_bitset<Block> a;
Tests::clear(a);
}
{
boost::dynamic_bitset<Block> a(long_string);
Tests::clear(a);
}
//=====================================================================
// Test pop back
{
boost::dynamic_bitset<Block> a(std::string("01"));
Tests::pop_back(a);
}
{
boost::dynamic_bitset<Block> a(std::string("10"));
Tests::pop_back(a);
}
{
const int size_to_fill_all_blocks = 4 * bits_per_block;
boost::dynamic_bitset<Block> a(size_to_fill_all_blocks, 255ul);
Tests::pop_back(a);
}
{
boost::dynamic_bitset<Block> a(long_string);
Tests::pop_back(a);
}
//=====================================================================
// Test append bit
{
boost::dynamic_bitset<Block> a;
Tests::append_bit(a);
}
{
boost::dynamic_bitset<Block> a(std::string("0"));
Tests::append_bit(a);
}
{
boost::dynamic_bitset<Block> a(std::string("1"));
Tests::append_bit(a);
}
{
const int size_to_fill_all_blocks = 4 * bits_per_block;
boost::dynamic_bitset<Block> a(size_to_fill_all_blocks, 255ul);
Tests::append_bit(a);
}
{
boost::dynamic_bitset<Block> a(long_string);
Tests::append_bit(a);
}
//=====================================================================
// Test append block
{
boost::dynamic_bitset<Block> a;
Tests::append_block(a);
}
{
boost::dynamic_bitset<Block> a(std::string("0"));
Tests::append_block(a);
}
{
boost::dynamic_bitset<Block> a(std::string("1"));
Tests::append_block(a);
}
{
const int size_to_fill_all_blocks = 4 * bits_per_block;
boost::dynamic_bitset<Block> a(size_to_fill_all_blocks, 15ul);
Tests::append_block(a);
}
{
boost::dynamic_bitset<Block> a(long_string);
Tests::append_block(a);
}
//=====================================================================
// Test append block range
{
boost::dynamic_bitset<Block> a;
std::vector<Block> blocks;
Tests::append_block_range(a, blocks);
}
{
boost::dynamic_bitset<Block> a(std::string("0"));
std::vector<Block> blocks(3);
blocks[0] = static_cast<Block>(0);
blocks[1] = static_cast<Block>(1);
blocks[2] = all_1s;
Tests::append_block_range(a, blocks);
}
{
boost::dynamic_bitset<Block> a(std::string("1"));
const unsigned int n = (std::numeric_limits<unsigned char>::max)();
std::vector<Block> blocks(n);
for (typename std::vector<Block>::size_type i = 0; i < n; ++i)
blocks[i] = static_cast<Block>(i);
Tests::append_block_range(a, blocks);
}
{
boost::dynamic_bitset<Block> 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<Block> blocks(x, x + sz);
Tests::append_block_range(a, blocks);
}
{
boost::dynamic_bitset<Block> a(long_string);
std::vector<Block> blocks(3);
blocks[0] = static_cast<Block>(0);
blocks[1] = static_cast<Block>(1);
blocks[2] = all_1s;
Tests::append_block_range(a, blocks);
}
//=====================================================================
// Test bracket operator
{
boost::dynamic_bitset<Block> b1;
std::vector<bool> bitvec1;
Tests::operator_bracket(b1, bitvec1);
}
{
boost::dynamic_bitset<Block> b(std::string("1"));
std::vector<bool> bit_vec(1, true);
Tests::operator_bracket(b, bit_vec);
}
{
boost::dynamic_bitset<Block> b(long_string);
std::size_t n = long_string.size();
std::vector<bool> 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);
}
//=====================================================================
// Test at
{
boost::dynamic_bitset<Block> b1;
std::vector<bool> bitvec1;
Tests::at(b1, bitvec1);
}
{
boost::dynamic_bitset<Block> b(std::string("1"));
std::vector<bool> bit_vec(1, true);
Tests::at(b, bit_vec);
}
{
boost::dynamic_bitset<Block> b(long_string);
std::size_t n = long_string.size();
std::vector<bool> bit_vec(n);
for (std::size_t i = 0; i < n; ++i)
bit_vec[i] = long_string[n - 1 - i] == '0' ? 0 : 1;
Tests::at(b, bit_vec);
}
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
{
typedef boost::dynamic_bitset<Block,
minimal_allocator<Block> > Bitset;
Bitset b;
bitset_test<Bitset>::max_size(b);
}
#endif
// Test copy-initialize with default constructor
{
boost::dynamic_bitset<Block> b[1] = {};
(void)b;
}
}
int
main()
{
run_test_cases<unsigned char>();
run_test_cases<unsigned short>();
run_test_cases<unsigned int>();
run_test_cases<unsigned long>();
# ifdef BOOST_HAS_LONG_LONG
run_test_cases< ::boost::ulong_long_type>();
# endif
return boost::report_errors();
}