Compare commits

..

1 Commits

Author SHA1 Message Date
Beman Dawes
85fbac8591 Release 1.45.0
[SVN r66646]
2010-11-19 15:17:53 +00:00
8 changed files with 92 additions and 480 deletions

View File

@@ -1,7 +1,6 @@
// -----------------------------------------------------------
// Copyright (c) 2001 Jeremy Siek
// Copyright (c) 2003-2006, 2008 Gennaro Prota
// Copyright (c) 2014 Ahmed Charles
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
@@ -130,7 +129,7 @@ struct bitset_test {
// - any remaining bit positions are initialized to zero
//
Bitset b(static_cast<typename Bitset::size_type>(num_bits), static_cast<unsigned long>(num));
Bitset b(num_bits, num);
// OK, we can now cast to size_type
typedef typename Bitset::size_type size_type;
@@ -268,12 +267,11 @@ struct bitset_test {
}
}
// copy assignment operator (absent from std::bitset)
static void copy_assignment_operator(const Bitset& lhs, const Bitset& rhs)
// assignment operator (absent from std::bitset)
static void assignment_operator(const Bitset& lhs, const Bitset& rhs)
{
Bitset b(lhs);
b = rhs;
b = b; // self assignment check
BOOST_CHECK(b == rhs);
// Changes to the copy do not affect the original
@@ -284,32 +282,6 @@ struct bitset_test {
}
}
static void max_size(const Bitset& b)
{
BOOST_CHECK(b.max_size() > 0);
}
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
// move constructor (absent from std::bitset)
static void move_constructor(const Bitset& b)
{
Bitset copy(boost::move(b));
BOOST_CHECK(b == copy);
}
// move assignment operator (absent from std::bitset)
static void move_assignment_operator(const Bitset& lhs, const Bitset& rhs)
{
Bitset b(lhs);
Bitset c(rhs);
b = boost::move(c);
b = boost::move(b); // self assignment check
BOOST_CHECK(b == rhs);
}
#endif // BOOST_NO_CXX11_RVALUE_REFERENCES
static void swap(const Bitset& lhs, const Bitset& rhs)
{
// bitsets must be swapped
@@ -717,21 +689,9 @@ struct bitset_test {
BOOST_CHECK(Bitset(b).set().count() == b.size());
}
static void all(const Bitset& b)
{
BOOST_CHECK(b.all() == (b.count() == b.size()));
bool result = true;
for(std::size_t i = 0; i < b.size(); ++i)
if(!b[i]) {
result = false;
break;
}
BOOST_CHECK(b.all() == result);
}
static void any(const Bitset& b)
{
BOOST_CHECK(b.any() == (b.count() != 0));
//BOOST_CHECK(b.any() == (b.count() > 0));
bool result = false;
for(std::size_t i = 0; i < b.size(); ++i)
if(b[i]) {
@@ -965,25 +925,6 @@ struct bitset_test {
}
}
static void test_set_bit(const Bitset& b, std::size_t pos, bool value)
{
Bitset lhs(b);
std::size_t N = lhs.size();
if (pos < N) {
Bitset prev(lhs);
// Stores a new value in the bit at position pos in lhs.
BOOST_CHECK(lhs.test_set(pos, value) == prev[pos]);
BOOST_CHECK(lhs[pos] == value);
// All other values of lhs remain unchanged
for (std::size_t I = 0; I < N; ++I)
if (I != pos)
BOOST_CHECK(lhs[I] == prev[I]);
} else {
// Not in range, doesn't satisfy precondition.
}
}
static void operator_shift_left(const Bitset& lhs, std::size_t pos)
{
Bitset x(lhs);
@@ -1107,7 +1048,7 @@ struct bitset_test {
// This test require that os be an output _and_ input stream.
// Of course dynamic_bitset's operator << doesn't require that.
size_type total_len = w <= 0 || static_cast<size_type>(w) < b.size()? b.size() : static_cast<size_type>(w);
size_type total_len = w <= 0 || (size_type)(w) < b.size()? b.size() : w;
const string_type padding (total_len - b.size(), fill_char);
string_type expected;
boost::to_string(b, expected);
@@ -1198,7 +1139,7 @@ struct bitset_test {
// {digits} or part of them
const typename Bitset::size_type max_digits =
w > 0 && static_cast<typename Bitset::size_type>(w) < b.max_size()
? static_cast<typename Bitset::size_type>(w) : b.max_size();
? w : b.max_size();
for( ; pos < len && (pos - after_spaces) < max_digits; ++pos) {
if(!is_one_or_zero(is, str[pos]))

View File

@@ -1,10 +1,6 @@
// -----------------------------------------------------------
// Copyright (c) 2001 Jeremy Siek
// Copyright (c) 2003-2006 Gennaro Prota
// Copyright (c) 2014 Ahmed Charles
//
// Copyright (c) 2014 Glen Joseph Fernandes
// glenfe at live dot com
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
@@ -19,28 +15,6 @@
#include "boost/detail/workaround.hpp"
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
#include <cstdlib>
template<class T>
class minimal_allocator {
public:
typedef T value_type;
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]))
@@ -97,8 +71,8 @@ void run_numeric_ctor_tests( BOOST_EXPLICIT_TEMPLATE_TYPE(Tests)
};
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)
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) {
@@ -143,6 +117,9 @@ void run_test_cases( BOOST_EXPLICIT_TEMPLATE_TYPE(Block) )
//=====================================================================
// Test construction from unsigned long
{
typedef typename bitset_type::size_type size_type;
// NOTE:
//
// 1. keep this in sync with the numeric types supported
@@ -263,70 +240,29 @@ void run_test_cases( BOOST_EXPLICIT_TEMPLATE_TYPE(Block) )
Tests::copy_constructor(b);
}
//=====================================================================
// Test copy assignment operator
// Test assignment operator
{
bitset_type a, b;
Tests::copy_assignment_operator(a, b);
Tests::assignment_operator(a, b);
}
{
bitset_type a(std::string("1")), b(std::string("0"));
Tests::copy_assignment_operator(a, b);
Tests::assignment_operator(a, b);
}
{
bitset_type a(long_string), b(long_string);
Tests::copy_assignment_operator(a, b);
Tests::assignment_operator(a, b);
}
{
bitset_type a;
bitset_type b(long_string); // b greater than a, a empty
Tests::copy_assignment_operator(a, b);
Tests::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);
Tests::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
{
@@ -484,14 +420,6 @@ void run_test_cases( BOOST_EXPLICIT_TEMPLATE_TYPE(Block) )
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<Block,
minimal_allocator<Block> > Bitset;
Bitset b;
bitset_test<Bitset>::max_size(b);
}
#endif
}
int

View File

@@ -1,7 +1,6 @@
// -----------------------------------------------------------
// Copyright (c) 2001 Jeremy Siek
// Copyright (c) 2003-2006 Gennaro Prota
// Copyright (c) 2014 Ahmed Charles
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
@@ -195,17 +194,14 @@ void run_test_cases( BOOST_EXPLICIT_TEMPLATE_TYPE(Block) )
{ // case pos >= b.size()
boost::dynamic_bitset<Block> b;
Tests::set_one(b, 0, true);
Tests::set_one(b, 0, false);
}
{ // case pos < b.size()
boost::dynamic_bitset<Block> b(std::string("0"));
Tests::set_one(b, 0, true);
Tests::set_one(b, 0, false);
}
{ // case pos == b.size() / 2
boost::dynamic_bitset<Block> b(long_string);
Tests::set_one(b, long_string.size()/2, true);
Tests::set_one(b, long_string.size()/2, false);
}
//=====================================================================
// Test b.reset()

View File

@@ -1,7 +1,6 @@
// -----------------------------------------------------------
// Copyright (c) 2001 Jeremy Siek
// Copyright (c) 2003-2006 Gennaro Prota
// Copyright (c) 2014 Ahmed Charles
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
@@ -122,73 +121,32 @@ void run_test_cases( BOOST_EXPLICIT_TEMPLATE_TYPE(Block) )
Tests::size(b);
}
//=====================================================================
// Test b.all()
{
boost::dynamic_bitset<Block> b;
Tests::all(b);
Tests::all(~b);
Tests::all(b.set());
Tests::all(b.reset());
}
{
boost::dynamic_bitset<Block> b(std::string("0"));
Tests::all(b);
Tests::all(~b);
Tests::all(b.set());
Tests::all(b.reset());
}
{
boost::dynamic_bitset<Block> b(long_string);
Tests::all(b);
Tests::all(~b);
Tests::all(b.set());
Tests::all(b.reset());
}
//=====================================================================
// Test b.any()
{
boost::dynamic_bitset<Block> b;
Tests::any(b);
Tests::any(~b);
Tests::any(b.set());
Tests::any(b.reset());
}
{
boost::dynamic_bitset<Block> b(std::string("0"));
Tests::any(b);
Tests::any(~b);
Tests::any(b.set());
Tests::any(b.reset());
}
{
boost::dynamic_bitset<Block> b(long_string);
Tests::any(b);
Tests::any(~b);
Tests::any(b.set());
Tests::any(b.reset());
}
//=====================================================================
// Test b.none()
{
boost::dynamic_bitset<Block> b;
Tests::none(b);
Tests::none(~b);
Tests::none(b.set());
Tests::none(b.reset());
}
{
boost::dynamic_bitset<Block> b(std::string("0"));
Tests::none(b);
Tests::none(~b);
Tests::none(b.set());
Tests::none(b.reset());
}
{
boost::dynamic_bitset<Block> b(long_string);
Tests::none(b);
Tests::none(~b);
Tests::none(b.set());
Tests::none(b.reset());
}
//=====================================================================
// Test a.is_subset_of(b)
@@ -611,23 +569,6 @@ void run_test_cases( BOOST_EXPLICIT_TEMPLATE_TYPE(Block) )
Tests::test_bit(b, long_string.size()/2);
}
//=====================================================================
// Test b.test_set(pos)
{ // case pos >= b.size()
boost::dynamic_bitset<Block> b;
Tests::test_set_bit(b, 0, true);
Tests::test_set_bit(b, 0, false);
}
{ // case pos < b.size()
boost::dynamic_bitset<Block> b(std::string("0"));
Tests::test_set_bit(b, 0, true);
Tests::test_set_bit(b, 0, false);
}
{ // case pos == b.size() / 2
boost::dynamic_bitset<Block> b(long_string);
Tests::test_set_bit(b, long_string.size() / 2, true);
Tests::test_set_bit(b, long_string.size() / 2, false);
}
//=====================================================================
// Test b << pos
{ // case pos == 0
std::size_t pos = 0;

View File

@@ -6,7 +6,6 @@
<!--
Copyright (c) 2001 Jeremy Siek
Copyright (c) 2003-2004, 2008 Gennaro Prota
Copyright (c) 2014 Ahmed Charles
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
@@ -164,17 +163,11 @@ public:
<a href=
"#cons5">dynamic_bitset</a>(const dynamic_bitset&amp; b);
<a href=
"#move-cons">dynamic_bitset</a>(dynamic_bitset&amp;&amp; b);
void <a href="#swap">swap</a>(dynamic_bitset&amp; b);
dynamic_bitset&amp; <a href=
"#assign">operator=</a>(const dynamic_bitset&amp; b);
dynamic_bitset&amp; <a href=
"#move-assign">operator=</a>(dynamic_bitset&amp;&amp; b);
allocator_type <a href="#get_allocator">get_allocator()</a> const;
void <a href=
@@ -202,26 +195,23 @@ public:
dynamic_bitset&amp; <a href="#flip2">flip</a>(size_type n);
dynamic_bitset&amp; <a href="#flip1">flip</a>();
bool <a href="#test">test</a>(size_type n) const;
bool <a href="#test">test_set</a>(size_type n, bool val = true);
bool <a href="#all">all</a>() const;
bool <a href="#any">any</a>() const;
bool <a href="#none">none</a>() const;
dynamic_bitset <a href="#op-not">operator~</a>() const;
size_type <a href="#count">count</a>() const noexcept;
size_type <a href="#count">count</a>() const;
reference <a href="#bracket">operator[]</a>(size_type pos);
bool <a href="#const-bracket">operator[]</a>(size_type pos) const;
unsigned long <a href="#to_ulong">to_ulong</a>() const;
size_type <a href="#size">size</a>() const noexcept;
size_type <a href="#num_blocks">num_blocks</a>() const noexcept;
size_type <a href="#max_size">max_size</a>() const noexcept;
bool <a href="#empty">empty</a>() const noexcept;
size_type <a href="#size">size</a>() const;
size_type <a href="#num_blocks">num_blocks</a>() const;
size_type <a href="#max_size">max_size</a>() const;
bool <a href="#empty">empty</a>() const;
bool <a href="#is_subset_of">is_subset_of</a>(const dynamic_bitset&amp; a) const;
bool <a href="#is_proper_subset_of">is_proper_subset_of</a>(const dynamic_bitset&amp; a) const;
bool <a href="#intersects">intersects</a>(const dynamic_bitset&amp; a) const;
size_type <a href="#find_first">find_first</a>() const;
size_type <a href="#find_next">find_next</a>(size_type pos) const;
@@ -630,20 +620,6 @@ allocator in <tt>x</tt>. <br />
(Required by <a href=
"http://www.sgi.com/tech/stl/Assignable.html">Assignable</a>.)
<hr />
<pre>
<a id="move-cons">dynamic_bitset</a>(dynamic_bitset&amp;&amp; x)
</pre>
<b>Effects:</b> Constructs a bitset that is the same as the bitset
<tt>x</tt>, while using the resources from <tt>x</tt>. The allocator
for this bitset is moved from the allocator in <tt>x</tt>. <br />
<b>Postconditions:</b> For all <tt>i</tt> in the range
<tt>[0,x.size())</tt>, <tt>(*this)[i] == x[i]</tt>.<br />
<b>Throws:</b> An allocation error if memory is exhausted
(<tt>std::bad_alloc</tt> if
<tt>Allocator=std::allocator</tt>).
<hr />
<pre>
template &lt;typename BlockInputIterator&gt;
@@ -787,20 +763,6 @@ dynamic_bitset&amp; <a id=
(Required by <a href=
"http://www.sgi.com/tech/stl/Assignable.html">Assignable</a>.)
<hr />
<pre>
dynamic_bitset&amp; <a id=
"move-assign">operator=</a>(dynamic_bitset&amp;&amp; x)
</pre>
<b>Effects:</b> This bitset becomes the same as the bitset
<tt>x</tt>, while using the resources from <tt>x</tt>.<br />
<b>Postconditions:</b> For all <tt>i</tt> in the range
<tt>[0,x.size())</tt>, <tt>(*this)[i] == x[i]</tt>.<br />
<b>Returns:</b> <tt>*this</tt>.<br />
<b>Throws:</b> An allocation error if memory is exhausted
(<tt>std::bad_alloc</tt> if <tt>Allocator=std::allocator</tt>).
<hr />
<pre>
allocator_type <a id="get_allocator">get_allocator()</a> const;
@@ -1124,15 +1086,6 @@ size_type <a id="count">count</a>() const
set.<br />
<b>Throws:</b> nothing.
<hr />
<pre>
bool <a id="all">all</a>() const
</pre>
<b>Returns:</b> <tt>true</tt> if all bits in this bitset are set or
if <tt>size() == 0</tt>, and otherwise returns <tt>false</tt>.<br />
<b>Throws:</b> nothing.
<hr />
<pre>
bool <a id="any">any</a>() const
@@ -1160,18 +1113,6 @@ bool <a id="test">test</a>(size_type n) const
<b>Returns:</b> <tt>true</tt> if bit <tt>n</tt> is set and
<tt>false</tt> is bit <tt>n</tt> is 0.
<hr />
<pre>
bool <a id="test">test_set</a>(size_type n, bool val = true)
</pre>
<b>Precondition:</b> <tt>n &lt; this-&gt;size()</tt>.<br />
<b>Effects:</b> Sets bit <tt>n</tt> if <tt>val</tt> is
<tt>true</tt>, and clears bit <tt>n</tt> if <tt>val</tt> is
<tt>false</tt>. <br />
<b>Returns:</b> <tt>true</tt> if the previous state of bit
<tt>n</tt> was set and <tt>false</tt> is bit <tt>n</tt> is 0.
<hr />
<pre>
reference <a id="bracket">operator[]</a>(size_type n)
@@ -1233,19 +1174,6 @@ also set and if <tt>this-&gt;count() &lt; a.count()</tt>.
Otherwise this function returns false.<br />
<b>Throws:</b> nothing.
<hr />
<pre>
bool <a id=
"intersects">intersects</a>(const dynamic_bitset&amp; a) const
</pre>
<b>Requires:</b> <tt>this-&gt;size() == a.size()</tt><br />
<b>Returns:</b> true if this bitset and <tt>a</tt> intersect.
That is, it returns true if, there is a bit which is set in this
bitset, such that the corresponding bit in bitset <tt>a</tt> is
also set. Otherwise this function returns false.<br />
<b>Throws:</b> nothing.
<hr />
<pre>
size_type <a id = "find_first">find_first</a>() const;
@@ -1567,14 +1495,6 @@ exception guarantee.
<hr />
<h3><a id="changes-from-previous-ver">Changes from previous version(s)</a></h3>
<h4><i>Changes in Boost 1.56.0</i></h4>
<ul>
<li>Support for C++11 move constructors.</li>
<li>Warning fixes on MSVC 2013.</li>
<li>Support for C++11 minimal allocators.</li>
<li>Add noexcept specifications.</li>
</ul>
<h4><i>Changes in Boost 1.37.0</i></h4>
<ul>
<li>The constructor from a block range implements a "do the right thing"
@@ -1627,12 +1547,9 @@ applied to their corresponding <tt>dynamic_bitset</tt>s.
</li>
</ul>
<i>General improvements</i>
<ul>
<li>
<br /><br />
Several optimizations to member and non-member functions and to the
nested class <tt>reference</tt>.
</li>
</ul>
<hr />
<h3><a id="see-also">See also</a></h3>
@@ -1664,14 +1581,6 @@ href="mailto:cda@freshsources.com">cda@freshsources.com</a>)<br
href="http://gennaro-prota.50webs.com/">Gennaro Prota</a>
(name.surname yahoo.com)</td>
</tr>
<tr>
<td>Copyright &copy; 2014</td>
<td>Ahmed Charles (<a href="mailto:acharles@outlook.com">acharles@outlook.com</a>)</td>
</tr>
<tr>
<td>Copyright &copy; 2014</td>
<td>Glen Fernandes (<a href="mailto:glenfe@live.com">glenfe@live.com</a>)</td>
</tr>
</table>
<br />
<div class="legalnotice">

View File

@@ -23,10 +23,6 @@
// table in detail/dynamic_bitset.hpp and report any interesting
// discovery on the list as well.
// You might also want to try both counting methods (by_bytes vs.
// by_blocks) to see if the one that is selected automatically is
// actually the fastest on your system.
//
//
// -----------------------------------------------------------------------//
@@ -59,9 +55,9 @@ namespace {
// see http://gcc.gnu.org/ml/gcc-bugs/1999-03n/msg00884.html
//
class boost_version {
int m_major;
int m_minor;
int m_subminor;
const int m_major;
const int m_minor;
const int m_subminor;
public:
boost_version(unsigned long v = BOOST_VERSION):
@@ -95,11 +91,11 @@ template <typename T>
void timing_test(T* = 0) // dummy parameter to workaround VC6
{
const unsigned long num = 30 * 100000;
const unsigned long num = 100000;
// This variable is printed at the end of the test,
// to prevent the optimizer from removing the call to
// to prevent the optimizer eliminating the call to
// count() in the loop below.
typename boost::dynamic_bitset<T>::size_type dummy = 0;
@@ -127,6 +123,7 @@ void timing_test(T* = 0) // dummy parameter to workaround VC6
int main()
{
prologue();
timing_test<unsigned char>();

View File

@@ -3,9 +3,6 @@
// Copyright (c) 2001-2002 Chuck Allison and Jeremy Siek
// Copyright (c) 2003-2006, 2008 Gennaro Prota
//
// Copyright (c) 2014 Glen Joseph Fernandes
// glenfe at live dot 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)
@@ -15,7 +12,6 @@
#ifndef BOOST_DETAIL_DYNAMIC_BITSET_HPP
#define BOOST_DETAIL_DYNAMIC_BITSET_HPP
#include <memory>
#include <cstddef>
#include "boost/config.hpp"
#include "boost/detail/workaround.hpp"
@@ -159,25 +155,17 @@ namespace boost {
// meaningful info.
//
template <typename T>
inline typename T::size_type vector_max_size_workaround(const T & v)
BOOST_NOEXCEPT
{
typedef typename T::allocator_type allocator_type;
typename T::size_type vector_max_size_workaround(const T & v) {
const allocator_type& alloc = v.get_allocator();
typedef typename T::allocator_type allocator_type;
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
typedef std::allocator_traits<allocator_type> allocator_traits;
const typename allocator_type::size_type alloc_max =
v.get_allocator().max_size();
const typename T::size_type container_max = v.max_size();
const typename allocator_traits::size_type alloc_max =
allocator_traits::max_size(alloc);
#else
const typename allocator_type::size_type alloc_max = alloc.max_size();
#endif
const typename T::size_type container_max = v.max_size();
return alloc_max < container_max ? alloc_max : container_max;
return alloc_max < container_max?
alloc_max :
container_max;
}
// for static_asserts

View File

@@ -2,10 +2,6 @@
//
// Copyright (c) 2001-2002 Chuck Allison and Jeremy Siek
// Copyright (c) 2003-2006, 2008 Gennaro Prota
// Copyright (c) 2014 Ahmed Charles
//
// Copyright (c) 2014 Glen Joseph Fernandes
// glenfe at live dot com
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
@@ -40,13 +36,9 @@
#include "boost/dynamic_bitset_fwd.hpp"
#include "boost/detail/dynamic_bitset.hpp"
#include "boost/detail/iterator.hpp" // used to implement append(Iter, Iter)
#include "boost/move/move.hpp"
#include "boost/static_assert.hpp"
#include "boost/limits.hpp"
#include "boost/pending/lowest_bit.hpp"
#include "boost/static_assert.hpp"
#include "boost/utility/addressof.hpp"
#include "boost/detail/no_exceptions_support.hpp"
#include "boost/throw_exception.hpp"
namespace boost {
@@ -54,22 +46,21 @@ namespace boost {
template <typename Block, typename Allocator>
class dynamic_bitset
{
// Portability note: member function templates are defined inside
// this class definition to avoid problems with VC++. Similarly,
// with the member functions of nested classes.
//
// [October 2008: the note above is mostly historical; new versions
// of VC++ are likely able to digest a more drinking form of the
// code; but changing it now is probably not worth the risks...]
// Portability note: member function templates are defined inside
// this class definition to avoid problems with VC++. Similarly,
// with the member functions of nested classes.
//
// [October 2008: the note above is mostly historical; new versions
// of VC++ are likely able to digest a more drinking form of the
// code; but changing it now is probably not worth the risks...]
BOOST_STATIC_ASSERT((bool)detail::dynamic_bitset_impl::allowed_block_type<Block>::value);
typedef std::vector<Block, Allocator> buffer_type;
BOOST_STATIC_ASSERT(detail::dynamic_bitset_impl::allowed_block_type<Block>::value);
public:
typedef Block block_type;
typedef Allocator allocator_type;
typedef std::size_t size_type;
typedef typename buffer_type::size_type block_width_type;
typedef block_type block_width_type;
BOOST_STATIC_CONSTANT(block_width_type, bits_per_block = (std::numeric_limits<Block>::digits));
BOOST_STATIC_CONSTANT(size_type, npos = static_cast<size_type>(-1));
@@ -216,11 +207,6 @@ public:
void swap(dynamic_bitset& b);
dynamic_bitset& operator=(const dynamic_bitset& b);
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
dynamic_bitset(dynamic_bitset&& src);
dynamic_bitset& operator=(dynamic_bitset&& src);
#endif // BOOST_NO_CXX11_RVALUE_REFERENCES
allocator_type get_allocator() const;
// size changing operations
@@ -284,12 +270,10 @@ public:
dynamic_bitset& flip(size_type n);
dynamic_bitset& flip();
bool test(size_type n) const;
bool test_set(size_type n, bool val = true);
bool all() const;
bool any() const;
bool none() const;
dynamic_bitset operator~() const;
size_type count() const BOOST_NOEXCEPT;
size_type count() const;
// subscript
reference operator[](size_type pos) {
@@ -299,10 +283,10 @@ public:
unsigned long to_ulong() const;
size_type size() const BOOST_NOEXCEPT;
size_type num_blocks() const BOOST_NOEXCEPT;
size_type max_size() const BOOST_NOEXCEPT;
bool empty() const BOOST_NOEXCEPT;
size_type size() const;
size_type num_blocks() const;
size_type max_size() const;
bool empty() const;
bool is_subset_of(const dynamic_bitset& a) const;
bool is_proper_subset_of(const dynamic_bitset& a) const;
@@ -346,16 +330,17 @@ public:
private:
BOOST_STATIC_CONSTANT(block_width_type, ulong_width = std::numeric_limits<unsigned long>::digits);
typedef std::vector<block_type, allocator_type> buffer_type;
void m_zero_unused_bits();
bool m_check_invariants() const;
size_type m_do_find_from(size_type first_block) const;
block_width_type count_extra_bits() const BOOST_NOEXCEPT { return bit_index(size()); }
static size_type block_index(size_type pos) BOOST_NOEXCEPT { return pos / bits_per_block; }
static block_width_type bit_index(size_type pos) BOOST_NOEXCEPT { return static_cast<block_width_type>(pos % bits_per_block); }
static Block bit_mask(size_type pos) BOOST_NOEXCEPT { return Block(1) << bit_index(pos); }
block_width_type count_extra_bits() const { return bit_index(size()); }
static size_type block_index(size_type pos) { return pos / bits_per_block; }
static block_width_type bit_index(size_type pos) { return static_cast<block_width_type>(pos % bits_per_block); }
static Block bit_mask(size_type pos) { return Block(1) << bit_index(pos); }
template <typename CharT, typename Traits, typename Alloc>
void init_from_string(const std::basic_string<CharT, Traits, Alloc>& s,
@@ -648,34 +633,6 @@ operator=(const dynamic_bitset<Block, Allocator>& b)
return *this;
}
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
template <typename Block, typename Allocator>
inline dynamic_bitset<Block, Allocator>::
dynamic_bitset(dynamic_bitset<Block, Allocator>&& b)
: m_bits(boost::move(b.m_bits)), m_num_bits(boost::move(b.m_num_bits))
{
// Required so that assert(m_check_invariants()); works.
assert((b.m_bits = buffer_type()).empty());
b.m_num_bits = 0;
}
template <typename Block, typename Allocator>
inline dynamic_bitset<Block, Allocator>& dynamic_bitset<Block, Allocator>::
operator=(dynamic_bitset<Block, Allocator>&& b)
{
if (boost::addressof(b) == this) { return *this; }
m_bits = boost::move(b.m_bits);
m_num_bits = boost::move(b.m_num_bits);
// Required so that assert(m_check_invariants()); works.
assert((b.m_bits = buffer_type()).empty());
b.m_num_bits = 0;
return *this;
}
#endif // BOOST_NO_CXX11_RVALUE_REFERENCES
template <typename Block, typename Allocator>
inline typename dynamic_bitset<Block, Allocator>::allocator_type
dynamic_bitset<Block, Allocator>::get_allocator() const
@@ -713,7 +670,7 @@ resize(size_type num_bits, bool value) // strong guarantee
if (value && (num_bits > m_num_bits)) {
const block_width_type extra_bits = count_extra_bits();
const size_type extra_bits = count_extra_bits();
if (extra_bits) {
assert(old_num_blocks >= 1 && old_num_blocks <= m_bits.size());
@@ -850,7 +807,7 @@ dynamic_bitset<Block, Allocator>::operator<<=(size_type n)
}
// zero out div blocks at the less significant end
std::fill_n(m_bits.begin(), div, static_cast<block_type>(0));
std::fill_n(b, div, static_cast<block_type>(0));
// zero out any 1 bit that flowed into the unused part
m_zero_unused_bits(); // thanks to Lester Gong
@@ -903,7 +860,7 @@ dynamic_bitset<B, A> & dynamic_bitset<B, A>::operator>>=(size_type n) {
// div blocks are zero filled at the most significant end
std::fill_n(m_bits.begin() + (num_blocks()-div), div, static_cast<block_type>(0));
std::fill_n(b + (num_blocks()-div), div, static_cast<block_type>(0));
}
return *this;
@@ -1009,46 +966,6 @@ bool dynamic_bitset<Block, Allocator>::test(size_type pos) const
return m_unchecked_test(pos);
}
template <typename Block, typename Allocator>
bool dynamic_bitset<Block, Allocator>::test_set(size_type pos, bool val)
{
bool const b = test(pos);
if (b != val) {
set(pos, val);
}
return b;
}
template <typename Block, typename Allocator>
bool dynamic_bitset<Block, Allocator>::all() const
{
if (empty()) {
return true;
}
const block_width_type extra_bits = count_extra_bits();
block_type const all_ones = ~static_cast<Block>(0);
if (extra_bits == 0) {
for (size_type i = 0, e = num_blocks(); i < e; ++i) {
if (m_bits[i] != all_ones) {
return false;
}
}
} else {
for (size_type i = 0, e = num_blocks() - 1; i < e; ++i) {
if (m_bits[i] != all_ones) {
return false;
}
}
block_type const mask = ~(~static_cast<Block>(0) << extra_bits);
if (m_highest_block() != mask) {
return false;
}
}
return true;
}
template <typename Block, typename Allocator>
bool dynamic_bitset<Block, Allocator>::any() const
{
@@ -1075,7 +992,7 @@ dynamic_bitset<Block, Allocator>::operator~() const
template <typename Block, typename Allocator>
typename dynamic_bitset<Block, Allocator>::size_type
dynamic_bitset<Block, Allocator>::count() const BOOST_NOEXCEPT
dynamic_bitset<Block, Allocator>::count() const
{
using detail::dynamic_bitset_impl::table_width;
using detail::dynamic_bitset_impl::access_by_bytes;
@@ -1184,17 +1101,17 @@ to_ulong() const
// Check for overflows. This may be a performance burden on very
// large bitsets but is required by the specification, sorry
if (find_next(ulong_width - 1) != npos)
BOOST_THROW_EXCEPTION(std::overflow_error("boost::dynamic_bitset::to_ulong overflow"));
throw std::overflow_error("boost::dynamic_bitset::to_ulong overflow");
// Ok, from now on we can be sure there's no "on" bit
// beyond the "allowed" positions
typedef unsigned long result_type;
const size_type maximum_size =
const size_type max_size =
(std::min)(m_num_bits, static_cast<size_type>(ulong_width));
const size_type last_block = block_index( maximum_size - 1 );
const size_type last_block = block_index( max_size - 1 );
assert((last_block * bits_per_block) < static_cast<size_type>(ulong_width));
@@ -1209,21 +1126,21 @@ to_ulong() const
template <typename Block, typename Allocator>
inline typename dynamic_bitset<Block, Allocator>::size_type
dynamic_bitset<Block, Allocator>::size() const BOOST_NOEXCEPT
dynamic_bitset<Block, Allocator>::size() const
{
return m_num_bits;
}
template <typename Block, typename Allocator>
inline typename dynamic_bitset<Block, Allocator>::size_type
dynamic_bitset<Block, Allocator>::num_blocks() const BOOST_NOEXCEPT
dynamic_bitset<Block, Allocator>::num_blocks() const
{
return m_bits.size();
}
template <typename Block, typename Allocator>
inline typename dynamic_bitset<Block, Allocator>::size_type
dynamic_bitset<Block, Allocator>::max_size() const BOOST_NOEXCEPT
dynamic_bitset<Block, Allocator>::max_size() const
{
// Semantics of vector<>::max_size() aren't very clear
// (see lib issue 197) and many library implementations
@@ -1244,7 +1161,7 @@ dynamic_bitset<Block, Allocator>::max_size() const BOOST_NOEXCEPT
}
template <typename Block, typename Allocator>
inline bool dynamic_bitset<Block, Allocator>::empty() const BOOST_NOEXCEPT
inline bool dynamic_bitset<Block, Allocator>::empty() const
{
return size() == 0;
}
@@ -1313,7 +1230,7 @@ dynamic_bitset<Block, Allocator>::m_do_find_from(size_type first_block) const
if (i >= num_blocks())
return npos; // not found
return i * bits_per_block + static_cast<size_type>(boost::lowest_bit(m_bits[i]));
return i * bits_per_block + boost::lowest_bit(m_bits[i]);
}
@@ -1340,11 +1257,11 @@ dynamic_bitset<Block, Allocator>::find_next(size_type pos) const
const size_type blk = block_index(pos);
const block_width_type ind = bit_index(pos);
// shift bits upto one immediately after current
const Block fore = m_bits[blk] >> ind;
// mask out bits before pos
const Block fore = m_bits[blk] & ( ~Block(0) << ind );
return fore?
pos + static_cast<size_type>(lowest_bit(fore))
blk * bits_per_block + lowest_bit(fore)
:
m_do_find_from(blk + 1);
@@ -1505,20 +1422,19 @@ operator<<(std::basic_ostream<Ch, Tr>& os,
const Ch zero = BOOST_DYNAMIC_BITSET_WIDEN_CHAR(fac, '0');
const Ch one = BOOST_DYNAMIC_BITSET_WIDEN_CHAR(fac, '1');
BOOST_TRY {
try {
typedef typename dynamic_bitset<Block, Alloc>::size_type bitset_size_type;
typedef typename dynamic_bitset<Block, Alloc>::size_type bitsetsize_type;
typedef basic_streambuf<Ch, Tr> buffer_type;
buffer_type * buf = os.rdbuf();
// careful: os.width() is signed (and can be < 0)
const bitset_size_type width = (os.width() <= 0) ? 0 : static_cast<bitset_size_type>(os.width());
streamsize npad = (width <= b.size()) ? 0 : width - b.size();
size_t npad = os.width() <= 0 // careful: os.width() is signed (and can be < 0)
|| (bitsetsize_type) os.width() <= b.size()? 0 : os.width() - b.size();
const Ch fill_char = os.fill();
const ios_base::fmtflags adjustfield = os.flags() & ios_base::adjustfield;
// if needed fill at left; pad is decreased along the way
// if needed fill at left; pad is decresed along the way
if (adjustfield != ios_base::left) {
for (; 0 < npad; --npad)
if (Tr::eq_int_type(Tr::eof(), buf->sputc(fill_char))) {
@@ -1529,7 +1445,7 @@ operator<<(std::basic_ostream<Ch, Tr>& os,
if (err == ok) {
// output the bitset
for (bitset_size_type i = b.size(); 0 < i; --i) {
for (bitsetsize_type i = b.size(); 0 < i; --i) {
typename buffer_type::int_type
ret = buf->sputc(b.test(i-1)? one : zero);
if (Tr::eq_int_type(Tr::eof(), ret)) {
@@ -1552,14 +1468,13 @@ operator<<(std::basic_ostream<Ch, Tr>& os,
os.width(0);
} BOOST_CATCH (...) { // see std 27.6.1.1/4
} catch (...) { // see std 27.6.1.1/4
bool rethrow = false;
BOOST_TRY { os.setstate(ios_base::failbit); } BOOST_CATCH (...) { rethrow = true; } BOOST_CATCH_END
try { os.setstate(ios_base::failbit); } catch (...) { rethrow = true; }
if (rethrow)
BOOST_RETHROW;
throw;
}
BOOST_CATCH_END
}
if(err != ok)
@@ -1605,7 +1520,7 @@ operator>>(std::istream& is, dynamic_bitset<Block, Alloc>& b)
const std::streamsize w = is.width();
const size_type limit = w > 0 && static_cast<size_type>(w) < b.max_size()
? static_cast<size_type>(w) : b.max_size();
? w : b.max_size();
typename bitset_type::bit_appender appender(b);
std::streambuf * buf = is.rdbuf();
for(int c = buf->sgetc(); appender.get_count() < limit; c = buf->snextc() ) {
@@ -1618,14 +1533,13 @@ operator>>(std::istream& is, dynamic_bitset<Block, Alloc>& b)
break; // non digit character
else {
BOOST_TRY {
try {
appender.do_append(char(c) == '1');
}
BOOST_CATCH(...) {
catch(...) {
is.setstate(std::ios::failbit); // assume this can't throw
BOOST_RETHROW;
throw;
}
BOOST_CATCH_END
}
} // for
@@ -1654,7 +1568,7 @@ operator>>(std::basic_istream<Ch, Tr>& is, dynamic_bitset<Block, Alloc>& b)
const streamsize w = is.width();
const size_type limit = 0 < w && static_cast<size_type>(w) < b.max_size()?
static_cast<size_type>(w) : b.max_size();
w : b.max_size();
ios_base::iostate err = ios_base::goodbit;
typename basic_istream<Ch, Tr>::sentry cerberos(is); // skips whitespaces
@@ -1666,7 +1580,7 @@ operator>>(std::basic_istream<Ch, Tr>& is, dynamic_bitset<Block, Alloc>& b)
const Ch one = BOOST_DYNAMIC_BITSET_WIDEN_CHAR(fac, '1');
b.clear();
BOOST_TRY {
try {
typename bitset_type::bit_appender appender(b);
basic_streambuf <Ch, Tr> * buf = is.rdbuf();
typename Tr::int_type c = buf->sgetc();
@@ -1689,7 +1603,7 @@ operator>>(std::basic_istream<Ch, Tr>& is, dynamic_bitset<Block, Alloc>& b)
} // for
}
BOOST_CATCH (...) {
catch (...) {
// catches from stream buf, or from vector:
//
// bits_stored bits have been extracted and stored, and
@@ -1697,15 +1611,13 @@ operator>>(std::basic_istream<Ch, Tr>& is, dynamic_bitset<Block, Alloc>& b)
// append to the underlying vector (out of memory)
bool rethrow = false; // see std 27.6.1.1/4
BOOST_TRY { is.setstate(ios_base::badbit); }
BOOST_CATCH(...) { rethrow = true; }
BOOST_CATCH_END
try { is.setstate(ios_base::badbit); }
catch(...) { rethrow = true; }
if (rethrow)
BOOST_RETHROW;
throw;
}
BOOST_CATCH_END
}
is.width(0);
@@ -1782,7 +1694,7 @@ inline typename dynamic_bitset<Block, Allocator>::size_type
dynamic_bitset<Block, Allocator>::calc_num_blocks(size_type num_bits)
{
return num_bits / bits_per_block
+ static_cast<size_type>( num_bits % bits_per_block != 0 );
+ static_cast<int>( num_bits % bits_per_block != 0 );
}
// gives a reference to the highest block