25 #ifndef DCCLBITSET20120424H
26 #define DCCLBITSET20120424H
34 #include "exception.h"
41 class Bitset :
public std::deque<bool>
54 explicit Bitset(size_type num_bits,
unsigned long value = 0,
Bitset* parent =
nullptr)
55 : std::deque<
bool>(num_bits, false), parent_(parent)
57 from(value, num_bits);
78 if (rhs.size() != size())
79 throw(
dccl::Exception(
"Bitset operator&= requires this->size() == rhs.size()"));
81 for (size_type i = 0; i != this->size(); ++i) (*
this)[i] &= rhs[i];
93 if (rhs.size() != size())
94 throw(
dccl::Exception(
"Bitset operator|= requires this->size() == rhs.size()"));
96 for (size_type i = 0; i != this->size(); ++i) (*
this)[i] |= rhs[i];
108 if (rhs.size() != size())
109 throw(
dccl::Exception(
"Bitset operator^= requires this->size() == rhs.size()"));
111 for (size_type i = 0; i != this->size(); ++i) (*
this)[i] ^= rhs[i];
125 for (size_type i = 0; i < n; ++i)
141 for (size_type i = 0; i < n; ++i)
185 for (
bool& it : *
this) it =
true;
200 for (
bool& it : *
this) it =
false;
215 for (size_type i = 0, n = size(); i < n; ++i)
flip(i);
223 bool test(size_type n)
const {
return (*
this)[n]; }
234 template <
typename IntType>
235 void from(IntType value, size_type num_bits = std::numeric_limits<IntType>::digits)
237 this->resize(num_bits);
238 for (
int i = 0, n = std::min<size_type>(std::numeric_limits<IntType>::digits, size());
241 if (value & (
static_cast<IntType
>(1) << i))
248 size_type num_bits = std::numeric_limits<unsigned long>::digits)
250 from<unsigned long>(value, num_bits);
257 template <
typename IntType> IntType
to()
const
259 if (size() >
static_cast<size_type
>(std::numeric_limits<IntType>::digits))
260 throw(
Exception(
"Type IntType cannot represent current bitset (this->size() > "
261 "std::numeric_limits<IntType>::digits)"));
264 for (
int i = 0, n = size(); i < n; ++i)
267 out |= (
static_cast<IntType
>(1) << i);
274 unsigned long to_ulong()
const {
return to<unsigned long>(); }
279 std::string s(size(), 0);
281 for (
auto it = rbegin(), n = rend(); it != n; ++it)
283 s[i] = (*it) ?
'1' :
'0';
299 std::string s(this->size() / 8 + (this->size() % 8 ? 1 : 0), 0);
301 for (size_type i = 0, n = this->size(); i < n; ++i)
302 s[i / 8] |=
static_cast<char>((*
this)[i] << (i % 8));
315 size_t len = this->size() / 8 + (this->size() % 8 ? 1 : 0);
319 throw std::length_error(
"max_len must be >= len");
323 std::fill_n(buf, len, 0);
325 for (size_type i = 0, n = this->size(); i < n; ++i)
326 buf[i / 8] |=
static_cast<char>((*
this)[i] << (i % 8));
340 template <
typename CharIterator>
void from_byte_stream(CharIterator begin, CharIterator end)
342 this->resize(std::distance(begin, end) * 8);
344 for (CharIterator it = begin; it != end; ++it)
346 for (size_type j = 0; j < 8; ++j) (*
this)[i * 8 + j] = (*it) & (1 << j);
354 for (
auto it = bits.rbegin(), n = bits.rend(); it != n; ++it) push_front(*it);
362 for (
bool bit : bits) push_back(bit);
368 Bitset relinquish_bits(size_type num_bits,
bool final_child);
374 inline bool operator==(
const Bitset& a,
const Bitset& b)
376 return (a.size() == b.size()) && std::equal(a.begin(), a.end(), b.begin());
379 inline bool operator<(
const Bitset& a,
const Bitset& b)
381 for (
int i = (std::max(a.size(), b.size()) - 1); i >= 0; --i)
383 bool a_bit = (i < static_cast<int>(a.size())) ? a[i] : 0;
384 bool b_bit = (i < static_cast<int>(b.size())) ? b[i] : 0;
388 else if (a_bit < b_bit)
394 inline Bitset operator&(
const Bitset& b1,
const Bitset& b2)
401 inline Bitset operator|(
const Bitset& b1,
const Bitset& b2)
408 inline Bitset operator^(
const Bitset& b1,
const Bitset& b2)
415 inline std::ostream& operator<<(std::ostream& os,
const Bitset& b) {
return (os << b.to_string()); }