Compare commits

..

11 Commits

Author SHA1 Message Date
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
Marshall Clow
7259281f5b Merge pull request #15 from danieljames/move-tests
This looks fine to me.  I'll watch the test bots, and merge to master in a week or so.
2016-07-01 08:24:46 -07:00
Daniel
92af4f52e9 Dummy jamfile for the super project's build script. 2016-07-01 09:10:18 +01:00
Daniel
d86f4ebddb Move tests into test subdirectory 2016-07-01 09:08:51 +01:00
ricky65
340822f979 Add capacity(), reserve(), and shrink_to_fit(). 2015-06-03 22:45:16 -07:00
Ahmed Charles
1c5e30fe49 Merge branch 'master' into develop 2015-06-03 22:44:34 -07:00
Ahmed Charles
0f48010783 Merge branch 'develop' 2015-06-03 22:43:44 -07:00
Ahmed Charles
1d59cc4788 Add converting constructor to minimal_allocator. 2015-05-19 00:36:26 -07:00
12 changed files with 337 additions and 7 deletions

3
Jamfile Normal file
View File

@@ -0,0 +1,3 @@
# Empty Jamfile because the super project still expects one to appear here.
# Can be deleted once 'status/Jamfile.v2' has been updated in the super
# project.

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

@@ -7,6 +7,7 @@
Copyright (c) 2001 Jeremy Siek
Copyright (c) 2003-2004, 2008 Gennaro Prota
Copyright (c) 2014 Ahmed Charles
Copyright (c) 2014 Riccardo Marcangelo
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
@@ -219,6 +220,9 @@ public:
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="#capacity">capacity</a>() const noexcept;
void <a href="#reserve">reserve</a>(size_type num_bits);
void <a href="#shrink_to_fit">shrink_to_fit</a>();
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;
@@ -843,7 +847,7 @@ void <a id="pop_back">pop_back</a>();
<b>Precondition:</b> <tt>!this-&gt;empty()</tt>.<br />
<b>Effects:</b> Decreases the size of the bitset by one.<br />
<b>Throws:</b> nothing.
<hr />
<pre>
void <a id="push_back">push_back</a>(bool value);
@@ -1125,6 +1129,40 @@ bool <a id="empty">empty</a>() const;
otherwise. <i>Note</i>: not to be confused with <tt>none()</tt>, that has
different semantics.
<hr />
<pre>
size_type <a id="capacity">capacity</a>() const;
</pre>
<b>Returns:</b> The total number of elements that <tt>*this</tt> can hold without requiring
reallocation.<br />
<b>Throws:</b> nothing.
<hr />
<pre>
void <a id="reserve">reserve</a>(size_type num_bits);
</pre>
<b>Effects:</b> A directive that informs the bitset of a planned change in size, so that it can
manage the storage allocation accordingly. After reserve(), capacity() is greater or equal to the
argument of reserve() if reallocation happens; and equal to the previous value of capacity() otherwise.
Reallocation happens at this point if and only if the current capacity is less than the argument of
reserve(). <br />
<i>Note:</i> It does not change the size() of the bitset.<br />
<b>Postcondtitions:</b> <tt>this->capacity() >= num_bits</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>
void <a id="shrink_to_fit">shrink_to_fit</a>();
</pre>
<b>Effects:</b> shrink_to_fit() is a request to reduce memory use by removing unused capacity.<br />
<i>Note:</i> It does not change the size() of the bitset.<br />
<b>Throws:</b> An allocation error if memory is exhausted
(<tt>std::bad_alloc</tt> if <tt>Allocator=std::allocator</tt>).
<hr />
<pre>
size_type <a id="count">count</a>() const
@@ -1682,6 +1720,10 @@ href="mailto:cda@freshsources.com">cda@freshsources.com</a>)<br
<td>Copyright &copy; 2014</td>
<td>Glen Fernandes (<a href="mailto:glenfe@live.com">glenfe@live.com</a>)</td>
</tr>
<tr>
<td>Copyright &copy; 2014</td>
<td>Riccardo Marcangelo (<a href="mailto:ricky.65@outlook.com">ricky.65@outlook.com</a>)</td>
</tr>
</table>
<br />
<div class="legalnotice">

View File

@@ -305,6 +305,9 @@ public:
size_type num_blocks() const BOOST_NOEXCEPT;
size_type max_size() const BOOST_NOEXCEPT;
bool empty() const BOOST_NOEXCEPT;
size_type capacity() const BOOST_NOEXCEPT;
void reserve(size_type num_bits);
void shrink_to_fit();
bool is_subset_of(const dynamic_bitset& a) const;
bool is_proper_subset_of(const dynamic_bitset& a) const;
@@ -345,6 +348,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);
@@ -750,15 +757,15 @@ push_back(bool bit)
template <typename Block, typename Allocator>
void dynamic_bitset<Block, Allocator>::
pop_back()
pop_back()
{
const size_type old_num_blocks = num_blocks();
const size_type required_blocks = calc_num_blocks(m_num_bits - 1);
if (required_blocks != old_num_blocks) {
m_bits.pop_back();
m_bits.pop_back();
}
--m_num_bits;
m_zero_unused_bits();
}
@@ -1267,6 +1274,27 @@ inline bool dynamic_bitset<Block, Allocator>::empty() const BOOST_NOEXCEPT
return size() == 0;
}
template <typename Block, typename Allocator>
inline typename dynamic_bitset<Block, Allocator>::size_type
dynamic_bitset<Block, Allocator>::capacity() const BOOST_NOEXCEPT
{
return m_bits.capacity() * bits_per_block;
}
template <typename Block, typename Allocator>
inline void dynamic_bitset<Block, Allocator>::reserve(size_type num_bits)
{
m_bits.reserve(calc_num_blocks(num_bits));
}
template <typename Block, typename Allocator>
void dynamic_bitset<Block, Allocator>::shrink_to_fit()
{
if (m_bits.size() < m_bits.capacity()) {
buffer_type(m_bits).swap(m_bits);
}
}
template <typename Block, typename Allocator>
bool dynamic_bitset<Block, Allocator>::
is_subset_of(const dynamic_bitset<Block, Allocator>& a) const

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

@@ -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

@@ -2,7 +2,7 @@
// Copyright (c) 2001 Jeremy Siek
// Copyright (c) 2003-2006, 2008 Gennaro Prota
// Copyright (c) 2014 Ahmed Charles
// Copyright (c) 2014 Riccardo Marcangelo
// Copyright (c) 2014 Riccardo Marcangelo
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
@@ -732,6 +732,67 @@ struct bitset_test {
BOOST_CHECK(Bitset(b).set().count() == b.size());
}
static void capacity_test_one(const Bitset& lhs)
{
//empty bitset
Bitset b(lhs);
BOOST_CHECK(b.capacity() == 0);
}
static void capacity_test_two(const Bitset& lhs)
{
//bitset constructed with size "100"
Bitset b(lhs);
BOOST_CHECK(b.capacity() >= 100);
b.resize(200);
BOOST_CHECK(b.capacity() >= 200);
}
static void reserve_test_one(const Bitset& lhs)
{
//empty bitset
Bitset b(lhs);
b.reserve(16);
BOOST_CHECK(b.capacity() >= 16);
}
static void reserve_test_two(const Bitset& lhs)
{
//bitset constructed with size "100"
Bitset b(lhs);
BOOST_CHECK(b.capacity() >= 100);
b.reserve(60);
BOOST_CHECK(b.size() == 100);
BOOST_CHECK(b.capacity() >= 100);
b.reserve(160);
BOOST_CHECK(b.size() == 100);
BOOST_CHECK(b.capacity() >= 160);
}
static void shrink_to_fit_test_one(const Bitset& lhs)
{
//empty bitset
Bitset b(lhs);
b.shrink_to_fit();
BOOST_CHECK(b.size() == 0);
BOOST_CHECK(b.capacity() == 0);
}
static void shrink_to_fit_test_two(const Bitset& lhs)
{
//bitset constructed with size "100"
Bitset b(lhs);
b.shrink_to_fit();
BOOST_CHECK(b.capacity() >= 100);
BOOST_CHECK(b.size() == 100);
b.reserve(200);
BOOST_CHECK(b.capacity() >= 200);
BOOST_CHECK(b.size() == 100);
b.shrink_to_fit();
BOOST_CHECK(b.capacity() < 200);
BOOST_CHECK(b.size() == 100);
}
static void all(const Bitset& b)
{
BOOST_CHECK(b.all() == (b.count() == b.size()));

View File

@@ -28,6 +28,11 @@ class minimal_allocator {
public:
typedef T value_type;
minimal_allocator() {}
template <typename U>
minimal_allocator(const minimal_allocator<U>&) {}
T* allocate(std::size_t n) {
void* p = std::malloc(sizeof(T) * n);
if (!p) {

View File

@@ -2,6 +2,7 @@
// Copyright (c) 2001 Jeremy Siek
// Copyright (c) 2003-2006 Gennaro Prota
// Copyright (c) 2014 Ahmed Charles
// Copyright (c) 2014 Riccardo Marcangelo
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
@@ -122,6 +123,36 @@ void run_test_cases( BOOST_EXPLICIT_TEMPLATE_TYPE(Block) )
Tests::size(b);
}
//=====================================================================
// Test b.capacity()
{
boost::dynamic_bitset<Block> b;
Tests::capacity_test_one(b);
}
{
boost::dynamic_bitset<Block> b(100);
Tests::capacity_test_two(b);
}
//=====================================================================
// Test b.reserve()
{
boost::dynamic_bitset<Block> b;
Tests::reserve_test_one(b);
}
{
boost::dynamic_bitset<Block> b(100);
Tests::reserve_test_two(b);
}
//=====================================================================
// Test b.shrink_to_fit()
{
boost::dynamic_bitset<Block> b;
Tests::shrink_to_fit_test_one(b);
}
{
boost::dynamic_bitset<Block> b(100);
Tests::shrink_to_fit_test_two(b);
}
//=====================================================================
// Test b.all()
{
boost::dynamic_bitset<Block> b;

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;
}