Compare commits

..

17 Commits

Author SHA1 Message Date
Edward Diener
4f54d83981 Merge pull request #21 from NAThompson/remove_deprecated_header
Replace deprecated header with non-deprecated
2018-02-11 16:50:56 -05:00
Nick Thompson
4cac68e762 Remove deprecated header. 2018-02-11 15:08:19 -06:00
Marshall Clow
d3eb4faf0c Fix some warnings from gcc - https://github.com/boostorg/dynamic_bitset/issues/19 2018-01-31 11:11:12 -08:00
Marshall Clow
3f3662d39d Fix comment block in Jamfile; addresses https://github.com/boostorg/dynamic_bitset/issues/20 2018-01-31 09:27:51 -08:00
Edward Diener
184d1ba7ad Merge pull request #17 from DanielaE/feature/squash-narrowing-warnings
squash compiler warnings due to wrong order of type-cast and integral…
2017-06-27 09:36:10 -04:00
Daniela Engert
5b39db5ba0 squash compiler warnings due to wrong order of type-cast and integral type promotion
Signed-off-by: Daniela Engert <dani@ngrt.de>
2017-05-25 10:29:34 +02:00
Edward Diener
f4e49ff56f Revert masks change 2017-05-18 11:52:03 -04:00
Edward Diener
0c8640efb8 Merge branch 'develop' into LessThanFix 2017-05-17 20:59:44 -04:00
Edward Diener
0ead484c37 Implemented lexigraphic compare when bitsets have different lengths. 2017-05-17 20:59:08 -04:00
Edward Diener
6cafa21c6d Fix for gcc and clang using libstdc++. 2017-05-15 16:29:38 -04:00
Edward Diener
dbfce8e174 Allow different sized bitsets to be compared for <, >, <=, >= 2017-05-15 13:03:15 -04:00
Marshall Clow
684b6117dd Merge pull request #16 from DanielaE/fix/wrong-parameter-type
fix wrong parameter type in constructor of dynamic_bitset::reference
2017-04-16 07:03:51 -07:00
Daniela Engert
572e9d78ff fix wrong parameter type in constructor of dynamic_bitset::reference
Signed-off-by: Daniela Engert <dani@ngrt.de>
2017-03-18 13:49:16 +01:00
Edward Diener
e49b08a289 Added expected doc subdirectory 2017-01-09 03:09:28 -05:00
Edward Diener
d644c83b13 Merge pull request #14 from sehe/develop
Add support for Boost Serialization of dynamic_bitset<>
2017-01-08 23:35:27 -05:00
Seth Heeren
a50768c085 Add tests for serialization support 2017-01-09 03:26:14 +01:00
Seth Heeren
91895380c6 Add optional serialization support
This implemenents non-intrusive serialization support to dynamic_bitset<> based on Boost Serialization

 - it supports archives that require named elements
 - it gets private member access using a nested friend class (to decouple the interface entirely)
 - relies on boost/serialization/vector.hpp for actual implementation
2017-01-09 03:19:57 +01:00
10 changed files with 344 additions and 54 deletions

1
doc/readme Normal file
View File

@@ -0,0 +1 @@
The documentation for the dynamic_bitset library is the top-level index.html file.

View File

@@ -1,11 +1,12 @@
// -----------------------------------------------------------
// Copyright (c) 2002 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)
//
// -----------------------------------------------------------
# -----------------------------------------------------------
# Copyright (c) 2002 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)
#
# -----------------------------------------------------------
exe timing_tests
: timing_tests.cpp
;

View File

@@ -86,7 +86,7 @@ public:
// the one and only non-copy ctor
reference(block_type & b, block_type pos)
reference(block_type & b, block_width_type pos)
:m_block(b),
m_mask( (assert(pos < bits_per_block),
block_type(1) << pos )
@@ -328,6 +328,10 @@ public:
friend bool operator<(const dynamic_bitset<B, A>& a,
const dynamic_bitset<B, A>& b);
template <typename B, typename A>
friend bool oplessthan(const dynamic_bitset<B, A>& a,
const dynamic_bitset<B, A>& b);
template <typename B, typename A, typename BlockOutputIterator>
friend void to_block_range(const dynamic_bitset<B, A>& b,
@@ -348,6 +352,10 @@ public:
#endif
public:
// forward declaration for optional zero-copy serialization support
class serialize_impl;
friend class serialize_impl;
private:
BOOST_STATIC_CONSTANT(block_width_type, ulong_width = std::numeric_limits<unsigned long>::digits);
@@ -969,7 +977,7 @@ template <typename Block, typename Allocator>
dynamic_bitset<Block, Allocator>&
dynamic_bitset<Block, Allocator>::set()
{
std::fill(m_bits.begin(), m_bits.end(), ~Block(0));
std::fill(m_bits.begin(), m_bits.end(), static_cast<Block>(~0));
m_zero_unused_bits();
return *this;
}
@@ -1048,7 +1056,7 @@ bool dynamic_bitset<Block, Allocator>::all() const
}
const block_width_type extra_bits = count_extra_bits();
block_type const all_ones = ~static_cast<Block>(0);
block_type const all_ones = static_cast<Block>(~0);
if (extra_bits == 0) {
for (size_type i = 0, e = num_blocks(); i < e; ++i) {
@@ -1062,7 +1070,7 @@ bool dynamic_bitset<Block, Allocator>::all() const
return false;
}
}
block_type const mask = ~(~static_cast<Block>(0) << extra_bits);
const block_type mask = (block_type(1) << extra_bits) - 1;
if (m_highest_block() != mask) {
return false;
}
@@ -1416,23 +1424,95 @@ template <typename Block, typename Allocator>
bool operator<(const dynamic_bitset<Block, Allocator>& a,
const dynamic_bitset<Block, Allocator>& b)
{
assert(a.size() == b.size());
typedef typename dynamic_bitset<Block, Allocator>::size_type size_type;
// assert(a.size() == b.size());
//if (a.size() == 0)
// return false;
typedef BOOST_DEDUCED_TYPENAME dynamic_bitset<Block, Allocator>::size_type size_type;
size_type asize(a.size());
size_type bsize(b.size());
// Since we are storing the most significant bit
// at pos == size() - 1, we need to do the comparisons in reverse.
//
for (size_type ii = a.num_blocks(); ii > 0; --ii) {
size_type i = ii-1;
if (a.m_bits[i] < b.m_bits[i])
return true;
else if (a.m_bits[i] > b.m_bits[i])
if (!bsize)
{
return false;
}
return false;
}
else if (!asize)
{
return true;
}
else if (asize == bsize)
{
for (size_type ii = a.num_blocks(); ii > 0; --ii)
{
size_type i = ii-1;
if (a.m_bits[i] < b.m_bits[i])
return true;
else if (a.m_bits[i] > b.m_bits[i])
return false;
}
return false;
}
else
{
size_type leqsize(std::min BOOST_PREVENT_MACRO_SUBSTITUTION(asize,bsize));
for (size_type ii = 0; ii < leqsize; ++ii,--asize,--bsize)
{
size_type i = asize-1;
size_type j = bsize-1;
if (a[i] < b[j])
return true;
else if (a[i] > b[j])
return false;
}
return (a.size() < b.size());
}
}
template <typename Block, typename Allocator>
bool oplessthan(const dynamic_bitset<Block, Allocator>& a,
const dynamic_bitset<Block, Allocator>& b)
{
// assert(a.size() == b.size());
typedef BOOST_DEDUCED_TYPENAME dynamic_bitset<Block, Allocator>::size_type size_type;
size_type asize(a.num_blocks());
size_type bsize(b.num_blocks());
assert(asize == 3);
assert(bsize == 4);
if (!bsize)
{
return false;
}
else if (!asize)
{
return true;
}
else
{
size_type leqsize(std::min BOOST_PREVENT_MACRO_SUBSTITUTION(asize,bsize));
assert(leqsize == 3);
//if (a.size() == 0)
// return false;
// Since we are storing the most significant bit
// at pos == size() - 1, we need to do the comparisons in reverse.
//
for (size_type ii = 0; ii < leqsize; ++ii,--asize,--bsize)
{
size_type i = asize-1;
size_type j = bsize-1;
if (a.m_bits[i] < b.m_bits[j])
return true;
else if (a.m_bits[i] > b.m_bits[j])
return false;
}
return (a.num_blocks() < b.num_blocks());
}
}
template <typename Block, typename Allocator>
@@ -1860,8 +1940,7 @@ inline void dynamic_bitset<Block, Allocator>::m_zero_unused_bits()
const block_width_type extra_bits = count_extra_bits();
if (extra_bits != 0)
m_highest_block() &= ~(~static_cast<Block>(0) << extra_bits);
m_highest_block() &= (Block(1) << extra_bits) - 1;
}
// check class invariants
@@ -1870,7 +1949,7 @@ bool dynamic_bitset<Block, Allocator>::m_check_invariants() const
{
const block_width_type extra_bits = count_extra_bits();
if (extra_bits > 0) {
block_type const mask = (~static_cast<Block>(0) << extra_bits);
const block_type mask = block_type(~0) << extra_bits;
if ((m_highest_block() & mask) != 0)
return false;
}

View File

@@ -0,0 +1,46 @@
// -----------------------------------------------------------
//
// Copyright (c) 2015 Seth Heeren
//
// 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)
//
// -----------------------------------------------------------
#ifndef BOOST_DYNAMIC_BITSET_SERIALIZATION_HPP
#define BOOST_DYNAMIC_BITSET_SERIALIZATION_HPP
#include "boost/dynamic_bitset/dynamic_bitset.hpp"
#include <boost/serialization/vector.hpp>
namespace boost {
// implementation for optional zero-copy serialization support
template <typename Block, typename Allocator>
class dynamic_bitset<Block, Allocator>::serialize_impl
{
public:
template <typename Ar>
static void serialize(Ar& ar, dynamic_bitset<Block, Allocator>& bs, unsigned) {
ar & serialization::make_nvp("m_num_bits", bs.m_num_bits)
& serialization::make_nvp("m_bits", bs.m_bits);
}
};
}
// ADL hook to Boost Serialization library
namespace boost {
namespace serialization {
template <typename Ar, typename Block, typename Allocator>
void serialize(Ar& ar, dynamic_bitset<Block, Allocator>& bs, unsigned version) {
dynamic_bitset<Block, Allocator>::serialize_impl::serialize(ar, bs, version);
}
} // namespace serialization
} // namespace boost
#endif // include guard

View File

@@ -15,7 +15,7 @@
#define BOOST_LOWEST_BIT_HPP_GP_20030301
#include <assert.h>
#include "boost/pending/integer_log2.hpp"
#include "boost/integer/integer_log2.hpp"
namespace boost {

View File

@@ -11,4 +11,6 @@ test-suite dynamic_bitset :
[ run dyn_bitset_unit_tests2.cpp ]
[ run dyn_bitset_unit_tests3.cpp ]
[ run dyn_bitset_unit_tests4.cpp ]
;
[ run dyn_bitset_unit_tests5.cpp /boost/serialization//boost_serialization
: : : <define>_SCL_SECURE_NO_WARNINGS=1 ]
;

View File

@@ -28,7 +28,6 @@
#include "boost/dynamic_bitset/dynamic_bitset.hpp"
#include "boost/test/minimal.hpp"
template <typename Block>
inline bool nth_bit(Block num, std::size_t n)
{
@@ -958,23 +957,41 @@ struct bitset_test {
static bool less_than(const Bitset& a, const Bitset& b)
{
// Compare from most significant to least.
// Careful, don't send unsigned int into negative territory!
if (a.size() == 0)
return false;
std::size_t I;
for (I = a.size() - 1; I > 0; --I)
if (a[I] < b[I])
return true;
else if (a[I] > b[I])
typedef BOOST_DEDUCED_TYPENAME Bitset::size_type size_type;
size_type asize(a.size());
size_type bsize(b.size());
if (!bsize)
{
return false;
// if (a[I] = b[I]) skip to next
if (a[0] < b[0])
return true;
}
else if (!asize)
{
return true;
}
else
return false;
{
// Compare from most significant to least.
size_type leqsize(std::min BOOST_PREVENT_MACRO_SUBSTITUTION(asize,bsize));
size_type I;
for (I = 0; I < leqsize; ++I,--asize,--bsize)
{
size_type i = asize-1;
size_type j = bsize-1;
if (a[i] < b[j])
return true;
else if (a[i] > b[j])
return false;
// if (a[i] = b[j]) skip to next
}
return (a.size() < b.size());
}
}
static typename Bitset::size_type next_bit_on(const Bitset& b, typename Bitset::size_type prev)

View File

@@ -16,7 +16,6 @@
#include "boost/limits.hpp"
#include "boost/config.hpp"
template <typename Block>
void run_test_cases( BOOST_EXPLICIT_TEMPLATE_TYPE(Block) )
{
@@ -477,6 +476,14 @@ void run_test_cases( BOOST_EXPLICIT_TEMPLATE_TYPE(Block) )
boost::dynamic_bitset<Block> a(std::string("10")), b(std::string("11"));
Tests::operator_less_than(a, b);
}
{
boost::dynamic_bitset<Block> a(std::string("101")), b(std::string("11"));
Tests::operator_less_than(a, b);
}
{
boost::dynamic_bitset<Block> a(std::string("10")), b(std::string("111"));
Tests::operator_less_than(a, b);
}
{
boost::dynamic_bitset<Block> a(long_string), b(long_string);
Tests::operator_less_than(a, b);
@@ -491,7 +498,7 @@ void run_test_cases( BOOST_EXPLICIT_TEMPLATE_TYPE(Block) )
b[long_string.size()/2].flip();
Tests::operator_less_than(a, b);
}
// check for consistency with ulong behaviour
// check for consistency with ulong behaviour when the sizes are equal
{
boost::dynamic_bitset<Block> a(3, 4ul), b(3, 5ul);
assert(a < b);
@@ -504,6 +511,31 @@ void run_test_cases( BOOST_EXPLICIT_TEMPLATE_TYPE(Block) )
boost::dynamic_bitset<Block> a(3, 5ul), b(3, 4ul);
assert(!(a < b));
}
// when the sizes are not equal lexicographic compare does not necessarily correspond to ulong behavior
{
boost::dynamic_bitset<Block> a(4, 4ul), b(3, 5ul);
assert(a < b);
}
{
boost::dynamic_bitset<Block> a(3, 4ul), b(4, 5ul);
assert(!(a < b));
}
{
boost::dynamic_bitset<Block> a(4, 4ul), b(3, 4ul);
assert(a < b);
}
{
boost::dynamic_bitset<Block> a(3, 4ul), b(4, 4ul);
assert(!(a < b));
}
{
boost::dynamic_bitset<Block> a(4, 5ul), b(3, 4ul);
assert(a < b);
}
{
boost::dynamic_bitset<Block> a(3, 5ul), b(4, 4ul);
assert(!(a < b));
}
//=====================================================================
// Test operator<=
{
@@ -766,6 +798,7 @@ void run_test_cases( BOOST_EXPLICIT_TEMPLATE_TYPE(Block) )
}
}
int
test_main(int, char*[])
{

View File

@@ -176,11 +176,11 @@ void run_test_cases( BOOST_EXPLICIT_TEMPLATE_TYPE(Block) )
std::ios::iostate masks[] = {
std::ios::goodbit,
std::ios::eofbit,
std::ios::failbit,
std::ios::eofbit | std::ios::failbit
};
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 ";

View File

@@ -0,0 +1,111 @@
// -----------------------------------------------------------
// Copyright (c) 2001 Jeremy Siek
// Copyright (c) 2003-2006 Gennaro Prota
//
// Copyright (c) 2015 Seth Heeren
//
// 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 "boost/config.hpp"
#if !defined (BOOST_NO_STRINGSTREAM)
# include <sstream>
#endif
#include "bitset_test.hpp"
#include "boost/dynamic_bitset/serialization.hpp"
#include "boost/detail/workaround.hpp"
// 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
#include <boost/archive/binary_oarchive.hpp>
#include <boost/archive/binary_iarchive.hpp>
#include <boost/archive/xml_oarchive.hpp>
#include <boost/archive/xml_iarchive.hpp>
#include <sstream>
namespace {
template <typename Block>
struct SerializableType {
boost::dynamic_bitset<Block> x;
private:
friend class boost::serialization::access;
template <class Archive> void serialize(Archive &ar, const unsigned int) {
ar & BOOST_SERIALIZATION_NVP(x);
}
};
template <typename Block, typename IArchive, typename OArchive>
void test_serialization( BOOST_EXPLICIT_TEMPLATE_TYPE(Block) )
{
SerializableType<Block> a;
for (int i=0; i<128; ++i)
a.x.resize(11*i, i%2);
#if !defined (BOOST_NO_STRINGSTREAM)
std::stringstream ss;
// test serialization
{
OArchive oa(ss);
oa << BOOST_SERIALIZATION_NVP(a);
}
// test de-serialization
{
IArchive ia(ss);
SerializableType<Block> b;
ia >> BOOST_SERIALIZATION_NVP(b);
assert(a.x == b.x);
}
#else
# error "TODO implement file-based test path?"
#endif
}
template <typename Block>
void test_binary_archive( BOOST_EXPLICIT_TEMPLATE_TYPE(Block) ) {
test_serialization<Block, boost::archive::binary_iarchive, boost::archive::binary_oarchive>();
}
template <typename Block>
void test_xml_archive( BOOST_EXPLICIT_TEMPLATE_TYPE(Block) ) {
test_serialization<Block, boost::archive::xml_iarchive, boost::archive::xml_oarchive>();
}
}
template <typename Block>
void run_test_cases( BOOST_EXPLICIT_TEMPLATE_TYPE(Block) )
{
test_binary_archive<Block>();
test_xml_archive<Block>();
}
int test_main(int, char*[])
{
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 0;
}