mirror of
https://github.com/boostorg/dynamic_bitset.git
synced 2026-01-19 04:12:09 +00:00
added specific tests for constructor dispatch and clarified the corresponding comments a bit; minor formatting consistency fixes; updated documentation and added license reference text to it
[SVN r48695]
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
// -----------------------------------------------------------
|
||||
// Copyright (c) 2001 Jeremy Siek
|
||||
// Copyright (c) 2003-2006 Gennaro Prota
|
||||
// Copyright (c) 2003-2006, 2008 Gennaro Prota
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
@@ -108,32 +108,43 @@ bool has_flags(const Stream& s, std::ios::iostate flags)
|
||||
// constructors
|
||||
// default (can't do this generically)
|
||||
|
||||
// from unsigned long
|
||||
|
||||
template <typename Bitset>
|
||||
struct bitset_test {
|
||||
|
||||
typedef typename Bitset::block_type Block;
|
||||
BOOST_STATIC_CONSTANT(int, bits_per_block = Bitset::bits_per_block);
|
||||
|
||||
|
||||
static void from_unsigned_long(std::size_t sz, unsigned long num)
|
||||
// from unsigned long
|
||||
//
|
||||
// Note: this is templatized so that we check that the do-the-right-thing
|
||||
// constructor dispatch is working correctly.
|
||||
//
|
||||
template <typename NumBits, typename Value>
|
||||
static void from_unsigned_long(NumBits num_bits, Value num)
|
||||
{
|
||||
// An object of size N = sz is constructed:
|
||||
// - the first M bit positions are initialized to the corresponding bit
|
||||
// values in num (M being the smaller of N and the width of unsigned
|
||||
// long)
|
||||
// An object of size sz = num_bits is constructed:
|
||||
// - the first m bit positions are initialized to the corresponding
|
||||
// bit values in num (m being the smaller of sz and ulong_width)
|
||||
//
|
||||
// - any remaining bit positions are initialized to zero
|
||||
//
|
||||
// - if M < N remaining bit positions are initialized to zero
|
||||
|
||||
Bitset b(sz, num);
|
||||
Bitset b(num_bits, num);
|
||||
|
||||
// OK, we can now cast to size_type
|
||||
typedef typename Bitset::size_type size_type;
|
||||
const size_type sz = static_cast<size_type>(num_bits);
|
||||
|
||||
BOOST_CHECK(b.size() == sz);
|
||||
|
||||
const std::size_t ulong_width = std::numeric_limits<unsigned long>::digits;
|
||||
std::size_t m = (std::min)(sz, ulong_width);
|
||||
std::size_t i;
|
||||
for (i = 0; i < m; ++i)
|
||||
BOOST_CHECK(b.test(i) == nth_bit(num, i));
|
||||
size_type m = sz;
|
||||
if (ulong_width < sz)
|
||||
m = ulong_width;
|
||||
|
||||
size_type i = 0;
|
||||
for ( ; i < m; ++i)
|
||||
BOOST_CHECK(b.test(i) == nth_bit(static_cast<unsigned long>(num), i));
|
||||
for ( ; i < sz; ++i)
|
||||
BOOST_CHECK(b.test(i) == 0);
|
||||
}
|
||||
@@ -978,7 +989,7 @@ struct bitset_test {
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
// operator<<( [basic_]ostream,
|
||||
template<typename Stream>
|
||||
template <typename Stream>
|
||||
static void stream_inserter(const Bitset & b,
|
||||
Stream & s,
|
||||
const char * file_name
|
||||
@@ -1058,7 +1069,7 @@ struct bitset_test {
|
||||
}
|
||||
|
||||
// operator>>( [basic_]istream
|
||||
template<typename Stream, typename String>
|
||||
template <typename Stream, typename String>
|
||||
static void stream_extractor(Bitset& b,
|
||||
Stream& is,
|
||||
String& str
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
|
||||
#include "boost/detail/workaround.hpp"
|
||||
|
||||
#define BOOST_BITSET_TEST_COUNT_OF(x) (sizeof(x)/sizeof(x[0]))
|
||||
#define BOOST_BITSET_TEST_COUNT(x) (sizeof(x)/sizeof(x[0]))
|
||||
|
||||
|
||||
// Codewarrior 8.3 for Win fails without this.
|
||||
@@ -54,6 +54,43 @@ void run_string_tests(const String& s
|
||||
|
||||
}
|
||||
|
||||
// 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), mi/2, mi,
|
||||
0, 1, 3, 8, 15, ma/2, 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]);
|
||||
|
||||
// can match templated ctor only (so we test dispatching)
|
||||
assert( sizes[s] < (std::numeric_limits<char>::max)() );
|
||||
Tests::from_unsigned_long(static_cast<T>(sizes[s]), numbers[n]);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
template <typename Block>
|
||||
void run_test_cases( BOOST_EXPLICIT_TEMPLATE_TYPE(Block) )
|
||||
{
|
||||
@@ -67,24 +104,52 @@ void run_test_cases( BOOST_EXPLICIT_TEMPLATE_TYPE(Block) )
|
||||
//=====================================================================
|
||||
// Test construction from unsigned long
|
||||
{
|
||||
typedef unsigned long source_type;
|
||||
const std::size_t source_width = std::numeric_limits<source_type>::digits;
|
||||
const source_type source_max =(std::numeric_limits<source_type>::max)();
|
||||
typedef typename bitset_type::size_type size_type;
|
||||
|
||||
source_type numbers[] = { 0, 1, 40247, source_max >> 1, source_max };
|
||||
std::size_t sizes[] =
|
||||
{ 0, 7 * source_width / 10, source_width, 13 * source_width / 10,
|
||||
7 * bits_per_block / 10, bits_per_block, 13 * bits_per_block / 10,
|
||||
3 * bits_per_block };
|
||||
|
||||
const std::size_t value_count = BOOST_BITSET_TEST_COUNT_OF(numbers);
|
||||
const std::size_t size_count = BOOST_BITSET_TEST_COUNT_OF(sizes);
|
||||
// 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 v = 0; v < value_count; ++v) {
|
||||
for (std::size_t s = 0; s < size_count; ++s) {
|
||||
Tests::from_unsigned_long(sizes[s], numbers[v]);
|
||||
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
|
||||
|
||||
@@ -574,11 +574,20 @@ Constructible</a>.)
|
||||
|
||||
<b>Effects:</b> Constructs a bitset from an integer. The first
|
||||
<tt>M</tt> bits are initialized to the corresponding bits in
|
||||
<tt>val</tt> and all other bits, if any, to zero (where <tt>M =
|
||||
<tt>value</tt> and all other bits, if any, to zero (where <tt>M =
|
||||
min(num_bits, std::numeric_limits<unsigned long>::digits)</tt>). A copy of
|
||||
the <tt>alloc</tt> object will be used in subsequent bitset
|
||||
operations such as <tt>resize</tt> to allocate memory.<br />
|
||||
<b>Postconditions:</b>
|
||||
operations such as <tt>resize</tt> to allocate memory. Note that, e.g., the
|
||||
following
|
||||
<br /><br />
|
||||
<tt>
|
||||
dynamic_bitset b<>( 16, 7 );
|
||||
</tt><br /><br />
|
||||
will match the <a href="#cons4">constructor from an iterator range</a> (not this
|
||||
one), but the underlying implementation will still "do the right thing" and
|
||||
construct a bitset of 16 bits, from the value 7.
|
||||
<br />
|
||||
<b>Postconditions:</b>
|
||||
|
||||
<ul>
|
||||
<li><tt>this->size() == num_bits</tt></li>
|
||||
@@ -620,24 +629,56 @@ explicit
|
||||
const Allocator& alloc = Allocator());
|
||||
</pre>
|
||||
|
||||
<b>Effects:</b> Constructs a bitset based on a range of blocks.
|
||||
Let <tt>*first</tt> be block number 0, <tt>*++first</tt> block
|
||||
number 1, etc. Block number <tt>b</tt> is used to initialize the
|
||||
bits of the dynamic_bitset in the position range
|
||||
<tt>[b*bits_per_block, (b+1)*bits_per_block)</tt>. For each block
|
||||
number <tt>b</tt> with value <tt>bval</tt>, the bit <tt>(bval
|
||||
>> i) & 1</tt> corresponds to the bit at position
|
||||
<tt>(b * bits_per_block + i)</tt> in the bitset (where <tt>i</tt>
|
||||
goes through the range <tt>[0, bits_per_block)</tt>).<br />
|
||||
<b>Requires:</b> The type <tt>BlockInputIterator</tt> must be a
|
||||
model of <a href=
|
||||
"http://www.sgi.com/tech/stl/InputIterator.html">Input
|
||||
Iterator</a> and its <tt>value_type</tt> must be the same type as
|
||||
<tt>Block</tt>.<br />
|
||||
<b>Throws:</b> An allocation error if memory is exhausted
|
||||
(<tt>std::bad_alloc</tt> if
|
||||
<tt>Allocator=std::allocator</tt>).<br />
|
||||
<b>Effects:</b>
|
||||
<ul>
|
||||
<li>
|
||||
If this constructor is called with a type <tt>BlockInputIterator</tt> which
|
||||
<i>is actually an integral type</i>, the library behaves as if the constructor
|
||||
from <tt>unsigned long</tt> had been called, with arguments
|
||||
<tt>static_cast<size_type>(first), last and alloc</tt>, in that order.
|
||||
|
||||
Example:
|
||||
<pre>
|
||||
// b is constructed as if by calling the constructor
|
||||
//
|
||||
// dynamic_bitset(size_type num_bits,
|
||||
// unsigned long value = 0,
|
||||
// const Allocator& alloc = Allocator())
|
||||
//
|
||||
// with arguments
|
||||
//
|
||||
// static_cast<dynamic_bitset<unsigned short>::size_type>(8),
|
||||
// 7,
|
||||
// Allocator()
|
||||
//
|
||||
dynamic_bitset<unsigned short> b(8, 7);
|
||||
</pre><br />
|
||||
<i>Note:</i><br/>
|
||||
This is analogous to what the standard mandates for sequence containers (namely,
|
||||
that if the type on which the template constructor is intantiated "does not
|
||||
qualify as an input iterator" then the other constructor is called; "the extent
|
||||
to which an implementation determines that a type cannot be an input iterator is
|
||||
unspecified, except that as a minimum integral types shall not qualify as input
|
||||
iterators").<br /><br />
|
||||
</li>
|
||||
<li>
|
||||
<i>Otherwise</i> (<i>i.e.</i> if the template argument is not an integral
|
||||
type), constructs—under the condition in the <tt>requires</tt>
|
||||
clause—a bitset based on a range of blocks. Let <tt>*first</tt> be block
|
||||
number 0, <tt>*++first</tt> block number 1, etc. Block number <tt>b</tt> is used
|
||||
to initialize the bits of the dynamic_bitset in the position range
|
||||
<tt>[b*bits_per_block, (b+1)*bits_per_block)</tt>. For each block number
|
||||
<tt>b</tt> with value <tt>bval</tt>, the bit <tt>(bval >> i) & 1</tt>
|
||||
corresponds to the bit at position <tt>(b * bits_per_block + i)</tt> in the
|
||||
bitset (where <tt>i</tt> goes through the range <tt>[0, bits_per_block)</tt>).
|
||||
</li>
|
||||
</ul>
|
||||
<br />
|
||||
<b>Requires:</b> <tt>BlockInputIterator</tt> must be either an integral type or
|
||||
a model of <a href= "http://www.sgi.com/tech/stl/InputIterator.html">Input
|
||||
Iterator</a> whose <tt>value_type</tt> is the same type as
|
||||
<tt>Block</tt>.<br /> <b>Throws:</b> An allocation error if memory is exhausted
|
||||
(<tt>std::bad_alloc</tt> if <tt>Allocator=std::allocator</tt>).<br />
|
||||
|
||||
<hr />
|
||||
<pre>
|
||||
@@ -1436,11 +1477,17 @@ from the stream.
|
||||
<h3><a id="exception-guarantees">Exception guarantees</a></h3>
|
||||
|
||||
All of <tt>dynamic_bitset</tt> functions offer at least the basic
|
||||
exception guarantee.
|
||||
exception guarantee.
|
||||
|
||||
<hr />
|
||||
<h3><a id="changes-from-previous-ver">Changes from previous version(s)</a></h3>
|
||||
|
||||
<h4><i>Changes in Boost 1.37.0</i></h4>
|
||||
<ul>
|
||||
<li>The constructor from a block-range implements a <i>do-the-right-thing</i>
|
||||
behavior, a la standard sequences.</li>
|
||||
</ul>
|
||||
|
||||
<!-- Changes from Boost 1.31.0 -->
|
||||
<h4><i>Changes from Boost 1.31.0</i></h4>
|
||||
<ul>
|
||||
@@ -1514,9 +1561,19 @@ href="http://freshsources.com">Chuck Allison</a>, Senior Editor,
|
||||
C/C++ Users Journal (<a
|
||||
href="mailto:cda@freshsources.com">cda@freshsources.com</a>)<br
|
||||
/></td> </tr> <tr>
|
||||
<td>Copyright © 2003-2004, 2008</td> <td>Gennaro Prota</td>
|
||||
<td>Copyright © 2003-2004, 2008</td> <td><a
|
||||
href="http://gennaro-prota.50webs.com/">Gennaro Prota</a>
|
||||
(name.surname yahoo.com)</td>
|
||||
</tr>
|
||||
</table>
|
||||
<br />
|
||||
<div class="legalnotice">
|
||||
Distributed under the Boost Software License, Version 1.0.
|
||||
(See accompanying file <a href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</a>
|
||||
or copy at <a class="ulink" href="http://www.boost.org/LICENSE_1_0.txt">
|
||||
http://www.boost.org/LICENSE_1_0.txt</a>)
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user