mirror of
https://github.com/boostorg/dynamic_bitset.git
synced 2026-01-19 04:12:09 +00:00
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.
339 lines
11 KiB
C++
339 lines
11 KiB
C++
// -----------------------------------------------------------
|
|
// Copyright (c) 2001 Jeremy Siek
|
|
// Copyright (c) 2003-2006, 2025 Gennaro Prota
|
|
//
|
|
// 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 <assert.h>
|
|
#include <cstddef>
|
|
#include <fstream>
|
|
#include <stdexcept>
|
|
#include <string>
|
|
|
|
#if !defined (BOOST_NO_STRINGSTREAM)
|
|
# include <sstream>
|
|
#endif
|
|
|
|
|
|
// 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
|
|
|
|
|
|
#if defined BOOST_NO_STD_WSTRING || defined BOOST_NO_STD_LOCALE
|
|
# define BOOST_DYNAMIC_BITSET_NO_WCHAR_T_TESTS
|
|
#endif
|
|
|
|
#if !defined BOOST_DYNAMIC_BITSET_NO_WCHAR_T_TESTS
|
|
std::wstring widen_string( const std::string & str,
|
|
const std::locale & loc = std::locale() )
|
|
{
|
|
std::wstring result;
|
|
const std::string::size_type len = str.length();
|
|
if(len != 0) {
|
|
|
|
typedef std::ctype<wchar_t> ct_type;
|
|
typedef std::wstring::traits_type tr_type;
|
|
const ct_type & ct = BOOST_USE_FACET(ct_type, loc);
|
|
|
|
result.resize(len);
|
|
for (std::size_t i = 0; i < len; ++i)
|
|
tr_type::assign(result[i], ct.widen(str[i]));
|
|
|
|
}
|
|
return result;
|
|
}
|
|
#endif
|
|
|
|
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;
|
|
|
|
//=====================================================================
|
|
// Test stream operator<<
|
|
{
|
|
|
|
// The test "variables" are: the stream type and its state, the
|
|
// exception mask, the width, the fill char and the padding side (left/right)
|
|
|
|
std::ios::iostate masks[] = {
|
|
std::ios::goodbit,
|
|
std::ios::eofbit,
|
|
std::ios::failbit,
|
|
std::ios::eofbit | std::ios::failbit
|
|
};
|
|
|
|
static std::string strings[] = {
|
|
std::string(""),
|
|
std::string("0"),
|
|
std::string("1"),
|
|
std::string("11100"),
|
|
get_long_string()
|
|
};
|
|
|
|
char fill_chars[] = { '*', 'x', ' ' };
|
|
|
|
std::size_t num_masks = sizeof(masks) / sizeof(masks[0]);
|
|
std::size_t num_strings = sizeof(strings) / sizeof(strings[0]);
|
|
std::size_t num_chars = sizeof(fill_chars) / sizeof(fill_chars[0]);
|
|
|
|
std::fstream not_good_stream("dynamic_bitset_tests - this file shouldn't exist",
|
|
std::ios::in);
|
|
|
|
|
|
for (std::size_t mi = 0; mi < num_masks; ++mi) {
|
|
for (std::size_t si = 0; si < num_strings; ++si) {
|
|
|
|
std::streamsize slen = (std::streamsize)(strings[si].length());
|
|
|
|
assert( (std::numeric_limits<std::streamsize>::max)()
|
|
>=(std::streamsize)(1+slen*2) );
|
|
|
|
for (std::size_t ci = 0; ci < num_chars; ++ci) {
|
|
|
|
// note how "negative widths" are tested too
|
|
const std::streamsize widths[] = { -1 - slen/2, 0, slen/2, 1 + slen*2 };
|
|
std::size_t num_widths = sizeof(widths) / sizeof(widths[0]);
|
|
|
|
for (std::size_t wi = 0; wi < num_widths; ++wi) {
|
|
std::streamsize w = widths[wi];
|
|
{
|
|
// test 0 - stream !good()
|
|
if(not_good_stream.good())
|
|
throw std::logic_error("Error in operator << tests"
|
|
" - please, double check");
|
|
bitset_type b(strings[si]);
|
|
not_good_stream.width(w);
|
|
not_good_stream.fill(fill_chars[ci]);
|
|
try { not_good_stream.exceptions(masks[mi]); } catch(...) {}
|
|
|
|
Tests::stream_inserter(b, not_good_stream, "<unused_string>");
|
|
}
|
|
{
|
|
// test 1a - file stream
|
|
scoped_temp_file stf;
|
|
bitset_type b(strings[si]);
|
|
std::ofstream file(stf.path().string().c_str(), std::ios::trunc);
|
|
file.width(w);
|
|
file.fill(fill_chars[ci]);
|
|
file.exceptions(masks[mi]);
|
|
Tests::stream_inserter(b, file, stf.path().string().c_str());
|
|
}
|
|
{
|
|
//NOTE: there are NO string stream tests
|
|
}
|
|
#if !defined (BOOST_DYNAMIC_BITSET_NO_WCHAR_T_TESTS)
|
|
{
|
|
// test 1b - wide file stream
|
|
scoped_temp_file stf;
|
|
bitset_type b(strings[si]);
|
|
std::wofstream file(stf.path().string().c_str());
|
|
file.width(w);
|
|
file.fill(fill_chars[ci]);
|
|
file.exceptions(masks[mi]);
|
|
Tests::stream_inserter(b, file, stf.path().string().c_str());
|
|
}
|
|
#endif
|
|
}
|
|
}
|
|
}
|
|
} // for (; mi..)
|
|
|
|
}
|
|
|
|
//=====================================================================
|
|
// Test stream operator>>
|
|
{
|
|
|
|
// The test "variables" are: the stream type, the exception mask,
|
|
// the actual contents (and/or state) of the stream, and width.
|
|
//
|
|
// With few exceptions, each test case consists of writing a different
|
|
// assortment of digits and "whitespaces" to a text stream and then checking
|
|
// that what was written gets read back unchanged. That's NOT guaranteed by
|
|
// the standard, unless the assortment always ends with a '\n' and satisfies
|
|
// other conditions (see C99, 7.19.2/2), however it works in practice and is
|
|
// a good "real life" test. Some characters, such as '\v' and '\f', are not
|
|
// used exactly because they are the ones which will most likely give problems
|
|
// on some systems (for instance '\f' could actually be written as a sequence
|
|
// of new-lines, and we could never be able to read it back)
|
|
//
|
|
// Note how the bitset object is not initially empty. That helps checking
|
|
// that it isn't erroneously clear()ed by operator>>.
|
|
|
|
|
|
std::ios::iostate masks[] = {
|
|
std::ios::goodbit,
|
|
std::ios::eofbit,
|
|
std::ios::failbit,
|
|
std::ios::eofbit | std::ios::failbit
|
|
};
|
|
|
|
const std::string spaces = "\t\n "; //"\t\n\v\f ";
|
|
|
|
const std::string long_string = get_long_string();
|
|
/*const*/ static std::string strings[] = {
|
|
// NOTE: "const" gives the usual problems with Borland
|
|
// (in Tests::stream_extractor instantiation)
|
|
|
|
|
|
#if !(defined BOOST_BORLANDC \
|
|
&& BOOST_WORKAROUND(BOOST_RWSTD_VER, BOOST_TESTED_AT(0x20101)))
|
|
// Borland 5.5.1 with RW library crashes
|
|
// empty string
|
|
std::string(""),
|
|
// no bitset
|
|
spaces,
|
|
#endif
|
|
// no bitset
|
|
std::string("x"),
|
|
std::string("\t xyz"),
|
|
|
|
// bitset of size 1
|
|
std::string("0"),
|
|
std::string("1"),
|
|
|
|
std::string(" 0 "),
|
|
std::string(" 1 "),
|
|
spaces + "1",
|
|
"1" + spaces,
|
|
spaces + "1" + spaces,
|
|
std::string(" x1x "),
|
|
std::string(" 1x "),
|
|
|
|
// long bitset
|
|
long_string,
|
|
" " + long_string + " xyz",
|
|
spaces + long_string,
|
|
spaces + long_string + spaces
|
|
};
|
|
|
|
|
|
//-----------------------------------------------------
|
|
|
|
std::stringstream not_good_stream;
|
|
not_good_stream << "test";
|
|
std::string sink;
|
|
not_good_stream >> sink; // now the stream should be in eof state
|
|
|
|
const std::size_t num_masks = sizeof(masks) / sizeof(masks[0]);
|
|
const std::size_t num_strings = sizeof(strings) / sizeof(strings[0]);
|
|
|
|
for (std::size_t mi = 0; mi < num_masks; ++mi) {
|
|
for (std::size_t si = 0; si < num_strings; ++si) {
|
|
|
|
const std::streamsize slen = (std::streamsize)(strings[si].length());
|
|
assert((std::numeric_limits<std::streamsize>::max)() >= (std::streamsize)(1+slen*2));
|
|
|
|
std::streamsize widths[] = { -1, 0, slen/2, slen, 1 + slen*2 };
|
|
std::size_t num_widths = sizeof(widths) / sizeof(widths[0]);
|
|
|
|
for(std::size_t wi = 0; wi < num_widths; ++wi) {
|
|
const std::streamsize w = widths[wi];
|
|
|
|
// test 0 - !good() stream
|
|
{
|
|
if(not_good_stream.good())
|
|
throw std::logic_error("Error in operator >> tests"
|
|
" - please, double check");
|
|
bitset_type b(1, 15ul); // note: b is not empty
|
|
not_good_stream.width(w);
|
|
try { not_good_stream.exceptions(masks[mi]); } catch(...) {}
|
|
std::string irrelevant;
|
|
Tests::stream_extractor(b, not_good_stream, irrelevant);
|
|
}
|
|
// test 1a - (narrow) file stream
|
|
{
|
|
scoped_temp_file stf;
|
|
bitset_type b(1, 255ul);
|
|
{
|
|
std::ofstream f(stf.path().string().c_str());
|
|
f << strings[si];
|
|
}
|
|
|
|
std::ifstream f(stf.path().string().c_str());
|
|
f.width(w);
|
|
f.exceptions(masks[mi]);
|
|
Tests::stream_extractor(b, f, strings[si]);
|
|
}
|
|
#if !defined(BOOST_NO_STRINGSTREAM)
|
|
// test 2a - stringstream
|
|
{
|
|
bitset_type b(1, 255ul);
|
|
std::istringstream stream(strings[si]);
|
|
stream.width(w);
|
|
stream.exceptions(masks[mi]);
|
|
Tests::stream_extractor(b, stream, strings[si]);
|
|
}
|
|
#endif
|
|
|
|
#if !defined(BOOST_DYNAMIC_BITSET_NO_WCHAR_T_TESTS)
|
|
// test 1b - wchar_t file stream
|
|
{
|
|
scoped_temp_file stf;
|
|
std::wstring wstr = widen_string(strings[si]);
|
|
bitset_type b(1, 255ul);
|
|
{
|
|
std::basic_ofstream<wchar_t> of(stf.path().string().c_str());
|
|
of << wstr;
|
|
}
|
|
|
|
std::basic_ifstream<wchar_t> f(stf.path().string().c_str());
|
|
f.width(w);
|
|
f.exceptions(masks[mi]);
|
|
Tests::stream_extractor(b, f, wstr);
|
|
}
|
|
// test 2b - wstringstream
|
|
{
|
|
bitset_type b(1, 255ul);
|
|
std::wstring wstr = widen_string(strings[si]);
|
|
|
|
std::wistringstream wstream(wstr);
|
|
wstream.width(w);
|
|
wstream.exceptions(masks[mi]);
|
|
Tests::stream_extractor(b, wstream, wstr);
|
|
}
|
|
#endif // BOOST_DYNAMIC_BITSET_NO_WCHAR_T_TESTS
|
|
|
|
}
|
|
}
|
|
|
|
} // for ( mi = 0; ...)
|
|
|
|
|
|
}
|
|
//=====================================================================
|
|
// << Any other tests go here >>
|
|
// .....
|
|
|
|
}
|
|
|
|
|
|
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();
|
|
}
|