|
Boost-Commit : |
Subject: [Boost-commit] svn:boost r48695 - trunk/libs/dynamic_bitset
From: gennaro.prota_at_[hidden]
Date: 2008-09-10 06:07:47
Author: gennaro_prota
Date: 2008-09-10 06:07:46 EDT (Wed, 10 Sep 2008)
New Revision: 48695
URL: http://svn.boost.org/trac/boost/changeset/48695
Log:
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
Text files modified:
trunk/libs/dynamic_bitset/bitset_test.hpp | 45 ++++++++++------
trunk/libs/dynamic_bitset/dyn_bitset_unit_tests1.cpp | 99 +++++++++++++++++++++++++++++++------
trunk/libs/dynamic_bitset/dynamic_bitset.html | 103 +++++++++++++++++++++++++++++++--------
3 files changed, 190 insertions(+), 57 deletions(-)
Modified: trunk/libs/dynamic_bitset/bitset_test.hpp
==============================================================================
--- trunk/libs/dynamic_bitset/bitset_test.hpp (original)
+++ trunk/libs/dynamic_bitset/bitset_test.hpp 2008-09-10 06:07:46 EDT (Wed, 10 Sep 2008)
@@ -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 @@
// 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 @@
//-------------------------------------------------------------------------
// 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 @@
}
// operator>>( [basic_]istream
- template<typename Stream, typename String>
+ template <typename Stream, typename String>
static void stream_extractor(Bitset& b,
Stream& is,
String& str
Modified: trunk/libs/dynamic_bitset/dyn_bitset_unit_tests1.cpp
==============================================================================
--- trunk/libs/dynamic_bitset/dyn_bitset_unit_tests1.cpp (original)
+++ trunk/libs/dynamic_bitset/dyn_bitset_unit_tests1.cpp 2008-09-10 06:07:46 EDT (Wed, 10 Sep 2008)
@@ -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 @@
}
+// 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 @@
//=====================================================================
// 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)();
-
- 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);
-
- 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]);
+ typedef typename bitset_type::size_type size_type;
+
+
+ // 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
Modified: trunk/libs/dynamic_bitset/dynamic_bitset.html
==============================================================================
--- trunk/libs/dynamic_bitset/dynamic_bitset.html (original)
+++ trunk/libs/dynamic_bitset/dynamic_bitset.html 2008-09-10 06:07:46 EDT (Wed, 10 Sep 2008)
@@ -574,11 +574,20 @@
<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 constructor from an iterator range (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 @@
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 @@
<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 @@
C/C++ Users Journal (<a
href="mailto:cda_at_[hidden]">cda_at_[hidden]</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 LICENSE_1_0.txt
+ or copy at <a class="ulink" href="http://www.boost.org/LICENSE_1_0.txt">
+http://www.boost.org/LICENSE_1_0.txt>)
+</div>
+
</div>
</div>
Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk