8#ifndef Sawyer_BitVector_H 
    9#define Sawyer_BitVector_H 
   11#include <Sawyer/Assert.h> 
   12#include <Sawyer/BitVectorSupport.h> 
   13#include <Sawyer/Optional.h> 
   14#include <Sawyer/Sawyer.h> 
   16#include <boost/algorithm/string/predicate.hpp> 
   17#include <boost/cstdint.hpp> 
   19#ifdef SAWYER_HAVE_BOOST_SERIALIZATION 
   20#include <boost/serialization/vector.hpp> 
   23#ifdef SAWYER_HAVE_CEREAL 
   24#include <cereal/types/vector.hpp> 
   34inline double log2(
double n) {
 
   35    return log(n) / log(2.0);
 
   75    std::vector<Word> words_;
 
   78#ifdef SAWYER_HAVE_BOOST_SERIALIZATION 
   80    friend class boost::serialization::access;
 
   83    void serialize(S &s, 
const unsigned ) {
 
   84        s & BOOST_SERIALIZATION_NVP(size_);
 
   85        s & BOOST_SERIALIZATION_NVP(words_);
 
   89#ifdef SAWYER_HAVE_CEREAL 
   91    friend class cereal::access;
 
   93    template<
class Archive>
 
   94    void CEREAL_SERIALIZE_FUNCTION_NAME(Archive &archive) {
 
   95        archive(CEREAL_NVP(size_));
 
   96        archive(CEREAL_NVP(words_));
 
  110    explicit BitVector(
size_t nbits, 
bool newBits = 
false): size_(0) {
 
 
  127        size_t bitsPerDigit = 0;
 
  128        const char *digits = NULL;
 
  129        if (boost::starts_with(str, 
"0x")) {
 
  131            digits = 
"0123456789abcdefABCDEF";
 
  133        } 
else if (boost::starts_with(str, 
"0b")) {
 
  137        } 
else if (boost::ends_with(str, 
"h")) {
 
  139            digits = 
"0123456789abcdefABCDEF";
 
  140            str = str.substr(0, str.size()-1);
 
  141        } 
else if (boost::starts_with(str, 
"0")) {
 
  147            digits = 
"0123456789";
 
  152        for (
const char *t=str.c_str(); *t; ++t) {
 
  153            if (strchr(digits, *t))
 
  157            throw std::runtime_error(
"BitVector::parse: no valid digits");
 
  162            nBits = bitsPerDigit * nDigits;
 
  164            nBits = ceil(log2(pow(10.0, (
double)nDigits)));
 
  169        switch (bitsPerDigit) {
 
  183                assert(!
"invalid radix");
 
 
  195        words_ = other.words_;
 
 
  208    size_t size()
 const { 
return size_; }
 
  219        } 
else if (newSize > size_) {
 
  220            size_t nwords = BitVectorSupport::numberOfWords<Word>(newSize);
 
  221            words_.resize(nwords, 
Word(0));
 
  225            size_t nwords = BitVectorSupport::numberOfWords<Word>(newSize);
 
  226            words_.resize(nwords);
 
 
  271    bool get(
size_t idx)
 const {
 
 
  946        for (
size_t i = 0; i < 
size(); ++i) {
 
 
  981        for (
size_t i = 0; i < a.
size(); ++i) {
 
  988        if (aIsNeg != bIsNeg)
 
 
 1328        return BitVectorSupport::toBytes(
data(), 
hull());
 
 
 1331        return BitVectorSupport::toBytes(
data(), range);
 
 
 1475        BitVectorSupport::fromBytes(
data(), 
hull(), input);
 
 
 1479        BitVectorSupport::fromBytes(
data(), range, input);
 
 
 1493        ASSERT_always_require(
hull().contains(range)); 
 
 
 1503        return words_.empty() ? NULL : &words_[0];
 
 
 1507        return words_.empty() ? NULL : &words_[0];
 
 
 1515        return words_.size();
 
 
 
unsigned Word
Base storage type.
 
bool isAllSet() const
True if all bits are set.
 
BitVector & rotateLeft(size_t nShift)
Rotate bits left.
 
BitVector & clear(const BitRange &range)
Assign zero to some bits.
 
Optional< size_t > mostSignificantSetBit() const
Find the most significant set bit.
 
BitVector & shiftRight(size_t nShift, bool newBits=0)
Shift bits right.
 
BitVector()
Default construct an empty vector.
 
bool increment(const BitRange &range1)
Increment bits as integer.
 
BitVector & fromHex(const std::string &input)
Obtain bits from a hexadecimal representation.
 
BitVector & multiply10(const BitRange &range)
Multiply by 10.
 
BitVector & fromOctal(const BitRange &range, const std::string &input)
Obtain bits from an octal representation.
 
Optional< size_t > mostSignificantDifference(const BitVector &other) const
Find most significant difference.
 
std::string toOctal() const
Convert to an octal string.
 
bool isAllClear() const
True if all bits are clear.
 
bool increment()
Increment bits as integer.
 
BitVector & shiftRight(const BitRange &range, size_t nShift, bool newBits=0)
Shift bits right.
 
bool isAllClear(const BitRange &range) const
True if all bits are clear.
 
bool decrement()
Decrement bits as integer.
 
Optional< size_t > leastSignificantClearBit(const BitRange &range) const
Find the least significant clear bit.
 
BitVector & fromOctal(const std::string &input)
Obtain bits from an octal representation.
 
BitVector & bitwiseAnd(const BitRange &range1, const BitRange &range2)
Bit-wise AND.
 
BitVector & negate(const BitRange &range1)
Negates bits as integer.
 
size_t capacity() const
Maximum size before reallocation.
 
Optional< size_t > mostSignificantSetBit(const BitRange &range) const
Find the most significant set bit.
 
BitVector multiplySigned(const BitVector &other) const
Multiply two signed integers.
 
boost::uint64_t toInteger(const BitRange &range) const
Interpret bits as an unsigned integer.
 
bool equalTo(const BitRange &range1, const BitRange &range2) const
Checks whether the bits of two ranges are equal.
 
std::string toHex() const
Convert to a hexadecimal string.
 
bool isEqualToZero(const BitRange &range) const
Compare to zero.
 
BitVector & copy(const BitRange &to, const BitRange &from)
Copy some bits.
 
BitVector & negate()
Negates bits as integer.
 
BitVector & fromInteger(const BitRange &range, boost::uint64_t value)
Obtain bits from an integer.
 
BitVector & signExtend(const BitVector &other)
Copy bits and sign extend.
 
int compareSigned(const BitRange &range1, const BitRange &range2) const
Compare bits as signed integers.
 
BitVector & signExtend(const BitRange &range1, const BitVector &other, const BitRange &range2)
Copy bits and sign extend.
 
int compare(const BitVector &other) const
Compare bits as integers.
 
BitVector & bitwiseOr(const BitVector &other)
Bit-wise OR.
 
BitVector & rotateLeft(const BitRange &range, size_t nShift)
Rotate bits left.
 
size_t size() const
Size of vector in bits.
 
size_t nClear() const
Number of clear bits.
 
void checkRange(const BitRange &range) const
Assert valid range.
 
std::vector< uint8_t > toBytes() const
Convert to a vector of bytes.
 
std::string toOctal(const BitRange &range) const
Convert to an octal string.
 
Optional< size_t > leastSignificantSetBit(const BitRange &range) const
Find the least significant set bit.
 
static BitRange hull(size_t minOffset, size_t maxOffset)
Create a bit range from min and max positions.
 
BitVector & swap(const BitRange &range1, BitVector &other, const BitRange &range2)
Swap some bits.
 
boost::int64_t toSignedInteger() const
Interpret bits as a signed integer.
 
bool add(const BitRange &range1, const BitRange &range2)
Add bits as integers.
 
BitVector & multiply10()
Multiply by 10.
 
Optional< size_t > leastSignificantClearBit() const
Find the least significant clear bit.
 
BitVector & set()
Assign true to all bits.
 
bool subtract(const BitRange &range1, const BitVector &other, const BitRange &range2)
Subtract bits as integers.
 
std::string toBinary(const BitRange &range) const
Convert to a binary string.
 
size_t dataSize() const
Raw data size.
 
BitVector(size_t nbits, bool newBits=false)
Create a vector of specified size.
 
Optional< size_t > mostSignificantDifference(const BitRange &range1, const BitVector &other, const BitRange &range2) const
Find most significant difference.
 
BitVector & shiftRightArithmetic(size_t nShift)
Shift bits right.
 
int compareSigned(const BitRange &range1, const BitVector &other, const BitRange &range2) const
Compare bits as signed integers.
 
BitRange hull() const
Interval representing the entire vector.
 
BitVector & bitwiseAnd(const BitVector &other)
Bit-wise AND.
 
BitVector & resize(size_t newSize, bool newBits=false)
Change vector size.
 
BitVector & rotateRight(size_t nShift)
Rotate bits right.
 
static BitRange baseSize(size_t base, size_t size)
Create a bit range from a starting offset and size.
 
BitVector & bitwiseXor(const BitRange &range1, const BitVector &other, const BitRange &range2)
Bit-wise XOR.
 
BitVector & clear()
Assign zero to all bits.
 
Word * data()
Raw data for vector.
 
BitVector & invert(const BitRange &range)
Invert bits.
 
BitVector & setValue(const BitRange &range, bool value)
Assign true/false to some bits.
 
bool decrement(const BitRange &range1)
Decrement bits as integer.
 
bool equalTo(const BitVector &other) const
Checks whether the bits of one vector are equal to the bits of the other.
 
std::vector< uint8_t > toBytes(const BitRange &range) const
Convert to a vector of bytes.
 
BitVector & rotateRight(const BitRange &range, size_t nShift)
Rotate bits right.
 
bool subtract(const BitVector &other)
Subtract bits as integers.
 
BitVector & set(const BitRange &range)
Assign true to some bits.
 
bool get(size_t idx) const
Retrieve one bit.
 
BitVector & signExtend(const BitRange &range1, const BitRange &range2)
Copy bits and sign extend.
 
BitVector & bitwiseOr(const BitRange &range1, const BitVector &other, const BitRange &range2)
Bit-wise OR.
 
BitVector & bitwiseOr(const BitRange &range1, const BitRange &range2)
Bit-wise OR.
 
Optional< size_t > leastSignificantDifference(const BitRange &range1, const BitRange &range2) const
Find least significant difference.
 
BitVector & fromBinary(const BitRange &range, const std::string &input)
Obtain bits from a binary representation.
 
BitVector & fromHex(const BitRange &range, const std::string &input)
Obtain bits from a hexadecimal representation.
 
int compare(const BitRange &range1, const BitRange &range2) const
Compare bits as integers.
 
int compare(const BitRange &range1, const BitVector &other, const BitRange &range2) const
Compare bits as integers.
 
Optional< size_t > mostSignificantDifference(const BitRange &range1, const BitRange &range2) const
Find most significant difference.
 
static BitVector parse(std::string str)
Create a bit vector by reading a string.
 
BitVector(const BitVector &other)
Copy constructor.
 
BitVector & fromBytes(const std::vector< uint8_t > &input)
Obtain bits from a byte vector.
 
boost::uint64_t toInteger() const
Interpret bits as an unsigned integer.
 
BitVector & fromDecimal(const BitRange &range, const std::string &input)
Obtains bits from a decimal representation.
 
bool isEqualToZero() const
Compare to zero.
 
BitVector & setValue(bool value)
Assign true/false to all bits.
 
BitVector & fromInteger(boost::uint64_t value)
Obtain bits from an integer.
 
BitVector & bitwiseXor(const BitVector &other)
Bit-wise XOR.
 
BitVector multiply(const BitVector &other) const
Multiply two bit vectors.
 
Optional< size_t > mostSignificantClearBit() const
Find the most significant clear bit.
 
boost::int64_t toSignedInteger(const BitRange &range) const
Interpret bits as a signed integer.
 
std::string toHex(const BitRange &range) const
Convert to a hexadecimal string.
 
BitVector & operator=(const BitVector &other)
Assignment.
 
BitVector & fromBinary(const std::string &input)
Obtain bits from a binary representation.
 
size_t nSet() const
Number of set bits.
 
Optional< size_t > leastSignificantSetBit() const
Find the least significant set bit.
 
Optional< size_t > leastSignificantDifference(const BitVector &other) const
Find least significant difference.
 
BitVector & bitwiseXor(const BitRange &range1, const BitRange &range2)
Bit-wise XOR.
 
BitVector & shiftRightArithmetic(const BitRange &range, size_t nShift)
Shift bits right.
 
BitVectorSupport::BitRange BitRange
Describes an inclusive interval of bit indices.
 
std::string toBinary() const
Convert to an binary string.
 
bool add(const BitRange &range1, const BitVector &other, const BitRange &range2)
Add bits as integers.
 
bool isAllSet(const BitRange &range) const
True if all bits are set.
 
BitVector & shiftLeft(size_t nShift, bool newBits=0)
Shift bits left.
 
size_t nSet(const BitRange &range) const
Number of set bits.
 
const Word * data() const
Raw data for vector.
 
BitVector & copy(const BitRange &to, const BitVector &other, const BitRange &from)
Copy some bits.
 
bool subtract(const BitRange &range1, const BitRange &range2)
Subtract bits as integers.
 
Optional< size_t > leastSignificantDifference(const BitRange &range1, const BitVector &other, const BitRange &range2) const
Find least significant difference.
 
BitVector & swap(const BitRange &range1, const BitRange &range2)
Swap some bits.
 
BitVector & shiftLeft(const BitRange &range, size_t nShift, bool newBits=0)
Shift bits left.
 
bool add(const BitVector &other)
Add bits as integers.
 
size_t nClear(const BitRange &range) const
Number of clear bits.
 
bool equalTo(const BitRange &range1, BitVector &other, const BitRange &range2) const
Checks whether two ranges are equal.
 
Optional< size_t > mostSignificantClearBit(const BitRange &range) const
Find the most significant clear bit.
 
BitVector & fromBytes(const BitRange &range, const std::vector< uint8_t > &input)
Obtain bits from a byte vector.
 
bool isEmpty() const
Determines if the vector is empty.
 
BitVector & invert()
Invert bits.
 
BitVector & bitwiseAnd(const BitRange &range1, const BitVector &other, const BitRange &range2)
Bit-wise AND.
 
int compareSigned(const BitVector &other) const
Compare bits as signed integers.
 
BitVector & fromDecimal(const std::string &input)
Obtain bits from a decimal representation.
 
static Interval baseSize(size_t lo, size_t size)
Construct an interval from one endpoint and a size.
 
static Interval hull(size_t v1, size_t v2)
Construct an interval from two endpoints.
 
Holds a value or nothing.
 
bool isEqualToZero(const Word *vec1, const BitRange &range1)
Compares with zero.
 
bool isAllSet(const Word *words, const BitRange &range)
True if all bits are set.
 
void rotateLeft(Word *words, const BitRange &range, size_t nShift)
Rotate bits to the left.
 
Optional< size_t > mostSignificantDifference(const Word *vec1, const BitRange &range1, const Word *vec2, const BitRange &range2)
Find most significant different bits.
 
void negate(Word *vec1, const BitRange &range)
Negate bits as an integer.
 
std::string toBinary(const Word *vec, const BitRange &range)
Binary representation.
 
size_t nClear(const Word *words, const BitRange &range)
Number of clear bits.
 
bool signExtend(const Word *vec1, const BitRange &range1, Word *vec2, const BitRange &range2)
Sign extend.
 
bool decrement(Word *vec1, const BitRange &range1)
Decrement.
 
void bitwiseOr(const Word *vec1, const BitRange &range1, Word *vec2, const BitRange &range2)
Bit-wise OR.
 
void shiftLeft(Word *words, const BitRange &range, size_t nShift, bool newBits=0)
Shift bits left.
 
int compare(const Word *vec1, const BitRange &range1, const Word *vec2, const BitRange &range2)
Unsigned comparison.
 
boost::uint64_t toInteger(const Word *words, const BitRange &range)
Convert a bit vector to an integer.
 
void multiply10(Word *vec, const BitRange &range)
Multiply by 10.
 
bool subtract(const Word *vec1, const BitRange &range1, Word *vec2, const BitRange &range2)
Subtract bits.
 
void fromBinary(Word *vec, const BitRange &range, const std::string &input)
Obtain bits from a binary representation.
 
void fromOctal(Word *vec, const BitRange &range, const std::string &input)
Obtain bits from an octal representation.
 
void fromDecimal(Word *vec, const BitRange &range, const std::string &input)
Obtain bits from a decimal representation.
 
void shiftRightArithmetic(Word *words, const BitRange &range, size_t nShift)
Shift bits right arithmetically.
 
Optional< size_t > leastSignificantClearBit(const Word *words, const BitRange &range)
Index of least significant zero bit.
 
void swap(Word *vec1, const BitRange &range1, Word *vec2, const BitRange &range2)
Swap some bits.
 
size_t nSet(const Word *words, const BitRange &range)
Number of set bits.
 
void clear(Word *words, const BitRange &where)
Clear some bits.
 
Optional< size_t > mostSignificantClearBit(const Word *words, const BitRange &range)
Index of most significant clear bit.
 
void bitwiseAnd(const Word *vec1, const BitRange &range1, Word *vec2, const BitRange &range2)
Bit-wise AND.
 
void set(Word *words, const BitRange &where)
Set some bits.
 
void fromHex(Word *vec, const BitRange &range, const std::string &input)
Obtain bits from a hexadecimal representation.
 
bool get(const Word *words, size_t idx)
Return a single bit.
 
void rotateRight(Word *words, const BitRange &range, size_t nShift)
Rotate bits to the right.
 
void bitwiseXor(const Word *vec1, const BitRange &range1, Word *vec2, const BitRange &range2)
Bit-wise XOR.
 
bool equalTo(const Word *vec1, const BitRange &range1, const Word *vec2, const BitRange &range2)
Compare bits for equality.
 
boost::int64_t toSignedInteger(const Word *words, const BitRange &range)
Convert a bit vector to a signed integer.
 
bool increment(Word *vec1, const BitRange &range1)
Increment.
 
int compareSigned(const Word *vec1, const BitRange &range1, const Word *vec2, const BitRange &range2)
Signed comparison.
 
bool add(const Word *vec1, const BitRange &range1, Word *vec2, const BitRange &range2, bool carryIn=false)
Add bits.
 
Optional< size_t > leastSignificantSetBit(const Word *words, const BitRange &range)
Index of least significant set bit.
 
Optional< size_t > mostSignificantSetBit(const Word *words, const BitRange &range)
Index of most significant set bit.
 
std::string toOctal(const Word *vec, const BitRange &range)
Octal representation.
 
void fromInteger(Word *words, const BitRange &range, boost::uint64_t value)
Assign an unsigned value to a bit range.
 
void shiftRight(Word *words, const BitRange &range, size_t nShift, bool newBits=0)
Shift bits right.
 
void invert(Word *words, const BitRange &range)
Invert bits.
 
bool isAllClear(const Word *words, const BitRange &range)
True if all bits are clear.
 
Optional< size_t > leastSignificantDifference(const Word *vec1, const BitRange &range1, const Word *vec2, const BitRange &range2)
Find least significant different bits.
 
std::string toHex(const Word *vec, const BitRange &range)
Hexadecimal representation.
 
void setValue(Word *words, const BitRange &where, bool value)
Set or clear some bits.
 
void copy(const Word *src, const BitRange &srcRange, Word *dst, const BitRange &dstRange)
Copy some bits.