From 340822f979371973fe4a84363623a68b984da57d Mon Sep 17 00:00:00 2001 From: ricky65 Date: Mon, 24 Nov 2014 17:09:22 +0000 Subject: [PATCH] Add capacity(), reserve(), and shrink_to_fit(). --- bitset_test.hpp | 63 ++++++++++++++++++- dyn_bitset_unit_tests3.cpp | 31 +++++++++ dynamic_bitset.html | 44 ++++++++++++- .../boost/dynamic_bitset/dynamic_bitset.hpp | 32 ++++++++-- 4 files changed, 164 insertions(+), 6 deletions(-) diff --git a/bitset_test.hpp b/bitset_test.hpp index 463033a..d3ace8e 100644 --- a/bitset_test.hpp +++ b/bitset_test.hpp @@ -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())); diff --git a/dyn_bitset_unit_tests3.cpp b/dyn_bitset_unit_tests3.cpp index 41e4c4a..cde272a 100644 --- a/dyn_bitset_unit_tests3.cpp +++ b/dyn_bitset_unit_tests3.cpp @@ -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 b; + Tests::capacity_test_one(b); + } + { + boost::dynamic_bitset b(100); + Tests::capacity_test_two(b); + } + //===================================================================== + // Test b.reserve() + { + boost::dynamic_bitset b; + Tests::reserve_test_one(b); + } + { + boost::dynamic_bitset b(100); + Tests::reserve_test_two(b); + } + //===================================================================== + // Test b.shrink_to_fit() + { + boost::dynamic_bitset b; + Tests::shrink_to_fit_test_one(b); + } + { + boost::dynamic_bitset b(100); + Tests::shrink_to_fit_test_two(b); + } + //===================================================================== // Test b.all() { boost::dynamic_bitset b; diff --git a/dynamic_bitset.html b/dynamic_bitset.html index 1039115..538dd76 100644 --- a/dynamic_bitset.html +++ b/dynamic_bitset.html @@ -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 num_blocks() const noexcept; size_type max_size() const noexcept; bool empty() const noexcept; + size_type capacity() const 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; @@ -843,7 +847,7 @@ void pop_back(); Precondition: !this->empty().
Effects: Decreases the size of the bitset by one.
Throws: nothing. - +
 void push_back(bool value);
@@ -1125,6 +1129,40 @@ bool empty() const;
 otherwise. Note: not to be confused with none(), that has
 different semantics.
 
+
+
+size_type capacity() const;
+
+ +Returns: The total number of elements that *this can hold without requiring +reallocation.
+Throws: nothing. + +
+
+void reserve(size_type num_bits);
+
+ +Effects: 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().
+Note: It does not change the size() of the bitset.
+Postcondtitions: this->capacity() >= num_bits.
+Throws: An allocation error if memory is exhausted +(std::bad_alloc if Allocator=std::allocator). + +
+
+void shrink_to_fit();
+
+ +Effects: shrink_to_fit() is a request to reduce memory use by removing unused capacity.
+Note: It does not change the size() of the bitset.
+Throws: An allocation error if memory is exhausted +(std::bad_alloc if Allocator=std::allocator). +
 size_type count() const
@@ -1682,6 +1720,10 @@ href="mailto:cda@freshsources.com">cda@freshsources.com)
Copyright © 2014 Glen Fernandes (glenfe@live.com) + +Copyright © 2014 +Riccardo Marcangelo (ricky.65@outlook.com) +
diff --git a/include/boost/dynamic_bitset/dynamic_bitset.hpp b/include/boost/dynamic_bitset/dynamic_bitset.hpp index f6002d8..86b5428 100644 --- a/include/boost/dynamic_bitset/dynamic_bitset.hpp +++ b/include/boost/dynamic_bitset/dynamic_bitset.hpp @@ -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; @@ -750,15 +753,15 @@ push_back(bool bit) template void dynamic_bitset:: -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 +1270,27 @@ inline bool dynamic_bitset::empty() const BOOST_NOEXCEPT return size() == 0; } +template +inline typename dynamic_bitset::size_type +dynamic_bitset::capacity() const BOOST_NOEXCEPT +{ + return m_bits.capacity() * bits_per_block; +} + +template +inline void dynamic_bitset::reserve(size_type num_bits) +{ + m_bits.reserve(calc_num_blocks(num_bits)); +} + +template +void dynamic_bitset::shrink_to_fit() +{ + if (m_bits.size() < m_bits.capacity()) { + buffer_type(m_bits).swap(m_bits); + } +} + template bool dynamic_bitset:: is_subset_of(const dynamic_bitset& a) const