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>
18 #include <boost/serialization/access.hpp>
19 #include <boost/serialization/nvp.hpp>
20 #include <boost/serialization/vector.hpp>
29 inline double log2(
double n) {
30 return log(n) / log(2.0);
70 std::vector<Word> words_;
74 friend class boost::serialization::access;
76 void serialize(S &s,
const unsigned ) {
77 s & BOOST_SERIALIZATION_NVP(size_);
78 s & BOOST_SERIALIZATION_NVP(words_);
91 explicit BitVector(
size_t nbits,
bool newBits =
false): size_(0) {
108 size_t bitsPerDigit = 0;
109 const char *digits = NULL;
110 if (boost::starts_with(str,
"0x")) {
112 digits =
"0123456789abcdefABCDEF";
114 }
else if (boost::starts_with(str,
"0b")) {
118 }
else if (boost::ends_with(str,
"h")) {
120 digits =
"0123456789abcdefABCDEF";
121 str = str.substr(0, str.size()-1);
122 }
else if (boost::starts_with(str,
"0")) {
128 digits =
"0123456789";
133 for (
const char *t=str.c_str(); *t; ++t) {
134 if (strchr(digits, *t))
138 throw std::runtime_error(
"BitVector::parse: no valid digits");
143 nBits = bitsPerDigit * nDigits;
145 nBits = ceil(log2(pow(10.0, (
double)nDigits)));
150 switch (bitsPerDigit) {
164 assert(!
"invalid radix");
176 words_ = other.words_;
189 size_t size()
const {
return size_; }
200 }
else if (newSize > size_) {
201 size_t nwords = BitVectorSupport::numberOfWords<Word>(newSize);
202 words_.resize(nwords,
Word(0));
206 size_t nwords = BitVectorSupport::numberOfWords<Word>(newSize);
207 words_.resize(nwords);
252 bool get(
size_t idx)
const {
927 for (
size_t i = 0; i <
size(); ++i) {
962 for (
size_t i = 0; i < a.
size(); ++i) {
969 if (aIsNeg != bIsNeg)
1442 ASSERT_always_require(
hull().isContaining(range));
1452 return words_.empty() ? NULL : &words_[0];
1456 return words_.empty() ? NULL : &words_[0];
1464 return words_.size();
bool get(const Word *words, size_t idx)
Return a single bit.
BitVector & shiftRightArithmetic(const BitRange &range, size_t nShift)
Shift bits right.
void rotateLeft(Word *words, const BitRange &range, size_t nShift)
Rotate bits to the left.
int compareSigned(const BitVector &other) const
Compare bits as signed integers.
BitVector & fromDecimal(const std::string &input)
Obtain bits from a decimal representation.
BitVector & shiftRightArithmetic(size_t nShift)
Shift bits right.
void bitwiseAnd(const Word *vec1, const BitRange &range1, Word *vec2, const BitRange &range2)
Bit-wise AND.
bool equalTo(const Word *vec1, const BitRange &range1, const Word *vec2, const BitRange &range2)
Compare bits for equality.
bool isAllClear(const BitRange &range) const
True if all bits are clear.
bool isAllSet() const
True if all bits are set.
BitVector & fromBinary(const std::string &input)
Obtain bits from a binary representation.
size_t size() const
Size of vector in bits.
std::string toHex(const Word *vec, const BitRange &range)
Hexadecimal representation.
Optional< size_t > leastSignificantClearBit() const
Find the least significant clear bit.
BitVector & swap(const BitRange &range1, BitVector &other, const BitRange &range2)
Swap some bits.
size_t nSet(const BitRange &range) const
Number of set bits.
BitVector & signExtend(const BitVector &other)
Copy bits and sign extend.
BitVector & copy(const BitRange &to, const BitVector &other, const BitRange &from)
Copy some bits.
size_t nClear(const BitRange &range) const
Number of clear bits.
unsigned Word
Base storage type.
int compare(const BitVector &other) const
Compare bits as integers.
const Word * data() const
Raw data for vector.
Optional< size_t > leastSignificantSetBit(const BitRange &range) const
Find the least significant set bit.
BitVector & rotateLeft(const BitRange &range, size_t nShift)
Rotate bits left.
Optional< size_t > mostSignificantDifference(const BitRange &range1, const BitVector &other, const BitRange &range2) const
Find most significant difference.
boost::int64_t toSignedInteger() const
Interpret bits as a signed integer.
BitVector & set(const BitRange &range)
Assign true to some bits.
bool isAllClear(const Word *words, const BitRange &range)
True if all bits are clear.
BitVector & bitwiseXor(const BitRange &range1, const BitRange &range2)
Bit-wise XOR.
BitVector multiply(const BitVector &other) const
Multiply two bit vectors.
static BitVector parse(std::string str)
Create a bit vector by reading a string.
BitVector & setValue(bool value)
Assign true/false to all bits.
BitVector & bitwiseXor(const BitRange &range1, const BitVector &other, const BitRange &range2)
Bit-wise XOR.
BitVector & bitwiseAnd(const BitRange &range1, const BitVector &other, const BitRange &range2)
Bit-wise AND.
int compareSigned(const BitRange &range1, const BitVector &other, const BitRange &range2) const
Compare bits as signed integers.
void fromBinary(Word *vec, const BitRange &range, const std::string &input)
Obtain bits from a binary representation.
void fromInteger(Word *words, const BitRange &range, boost::uint64_t value)
Assign an unsigned value to a bit range.
void checkRange(const BitRange &range) const
Assert valid range.
BitVector & bitwiseOr(const BitRange &range1, const BitRange &range2)
Bit-wise OR.
bool add(const BitRange &range1, const BitRange &range2)
Add bits as integers.
void swap(Word *vec1, const BitRange &range1, Word *vec2, const BitRange &range2)
Swap some bits.
bool isAllSet(const Word *words, const BitRange &range)
True if all bits are set.
Optional< size_t > leastSignificantSetBit() const
Find the least significant set bit.
bool isEqualToZero(const Word *vec1, const BitRange &range1)
Compares with zero.
bool decrement(const BitRange &range1)
Decrement bits as integer.
Optional< size_t > leastSignificantDifference(const Word *vec1, const BitRange &range1, const Word *vec2, const BitRange &range2)
Find least significant different bits.
bool isEmpty() const
Determines if the vector is empty.
std::string toBinary() const
Convert to an binary string.
bool isAllSet(const BitRange &range) const
True if all bits are set.
BitVector & shiftRight(size_t nShift, bool newBits=0)
Shift bits right.
BitVector & multiply10(const BitRange &range)
Multiply by 10.
BitVector & fromInteger(boost::uint64_t value)
Obtain bits from an integer.
BitVector()
Default construct an empty vector.
Optional< size_t > leastSignificantDifference(const BitRange &range1, const BitRange &range2) const
Find least significant difference.
BitVector & multiply10()
Multiply by 10.
bool equalTo(const BitVector &other) const
Checks whether the bits of one vector are equal to the bits of the other.
bool isAllClear() const
True if all bits are clear.
BitVector & signExtend(const BitRange &range1, const BitVector &other, const BitRange &range2)
Copy bits and sign extend.
boost::uint64_t toInteger(const Word *words, const BitRange &range)
Convert a bit vector to an integer.
bool equalTo(const BitRange &range1, const BitRange &range2) const
Checks whether the bits of two ranges are equal.
void setValue(Word *words, const BitRange &where, bool value)
Set or clear some bits.
static Interval baseSize(size_t lo, size_t size)
Construct an interval from one endpoint and a size.
BitVector & fromDecimal(const BitRange &range, const std::string &input)
Obtains bits from a decimal representation.
boost::uint64_t toInteger() const
Interpret bits as an unsigned integer.
Optional< size_t > mostSignificantSetBit(const BitRange &range) const
Find the most significant set bit.
BitVector & copy(const BitRange &to, const BitRange &from)
Copy some bits.
int compare(const Word *vec1, const BitRange &range1, const Word *vec2, const BitRange &range2)
Unsigned comparison.
Optional< size_t > leastSignificantClearBit(const BitRange &range) const
Find the least significant clear bit.
BitVector(size_t nbits, bool newBits=false)
Create a vector of specified size.
BitVector & operator=(const BitVector &other)
Assignment.
Optional< size_t > mostSignificantDifference(const BitRange &range1, const BitRange &range2) const
Find most significant difference.
std::string toOctal(const BitRange &range) const
Convert to an octal string.
static BitRange baseSize(size_t base, size_t size)
Create a bit range from a starting offset and size.
BitVector & fromHex(const std::string &input)
Obtain bits from a hexadecimal representation.
BitVector & signExtend(const BitRange &range1, const BitRange &range2)
Copy bits and sign extend.
BitVector & shiftLeft(size_t nShift, bool newBits=0)
Shift bits left.
size_t dataSize() const
Raw data size.
BitRange hull() const
Interval representing the entire vector.
Optional< size_t > mostSignificantClearBit(const BitRange &range) const
Find the most significant clear bit.
void copy(const Word *src, const BitRange &srcRange, Word *dst, const BitRange &dstRange)
Copy some bits.
void rotateRight(Word *words, const BitRange &range, size_t nShift)
Rotate bits to the right.
void shiftLeft(Word *words, const BitRange &range, size_t nShift, bool newBits=0)
Shift bits left.
Optional< size_t > leastSignificantDifference(const BitRange &range1, const BitVector &other, const BitRange &range2) const
Find least significant difference.
void negate(Word *vec1, const BitRange &range)
Negate bits as an integer.
bool isEqualToZero() const
Compare to zero.
bool decrement(Word *vec1, const BitRange &range1)
Decrement.
bool increment()
Increment bits as integer.
BitVector & rotateRight(size_t nShift)
Rotate bits right.
boost::int64_t toSignedInteger(const BitRange &range) const
Interpret bits as a signed integer.
Optional< size_t > mostSignificantSetBit() const
Find the most significant set bit.
BitVector & setValue(const BitRange &range, bool value)
Assign true/false to some bits.
bool subtract(const BitRange &range1, const BitVector &other, const BitRange &range2)
Subtract bits as integers.
void fromDecimal(Word *vec, const BitRange &range, const std::string &input)
Obtain bits from a decimal representation.
Optional< size_t > mostSignificantClearBit(const Word *words, const BitRange &range)
Index of most significant clear bit.
bool add(const Word *vec1, const BitRange &range1, Word *vec2, const BitRange &range2, bool carryIn=false)
Add bits.
BitVector & shiftLeft(const BitRange &range, size_t nShift, bool newBits=0)
Shift bits left.
BitVector & bitwiseXor(const BitVector &other)
Bit-wise XOR.
BitVector & negate(const BitRange &range1)
Negates bits as integer.
BitVector & fromHex(const BitRange &range, const std::string &input)
Obtain bits from a hexadecimal representation.
void bitwiseXor(const Word *vec1, const BitRange &range1, Word *vec2, const BitRange &range2)
Bit-wise XOR.
std::string toHex(const BitRange &range) const
Convert to a hexadecimal string.
int compare(const BitRange &range1, const BitVector &other, const BitRange &range2) const
Compare bits as integers.
void invert(Word *words, const BitRange &range)
Invert bits.
bool add(const BitVector &other)
Add bits as integers.
std::string toBinary(const Word *vec, const BitRange &range)
Binary representation.
static BitRange hull(size_t minOffset, size_t maxOffset)
Create a bit range from min and max positions.
BitVector & clear(const BitRange &range)
Assign zero to some bits.
BitVector(const BitVector &other)
Copy constructor.
bool get(size_t idx) const
Retrieve one bit.
void set(Word *words, const BitRange &where)
Set some bits.
BitVector & rotateLeft(size_t nShift)
Rotate bits left.
Word * data()
Raw data for vector.
std::string toOctal(const Word *vec, const BitRange &range)
Octal representation.
BitVector & negate()
Negates bits as integer.
BitVector & invert(const BitRange &range)
Invert bits.
Name space for the entire library.
int compareSigned(const BitRange &range1, const BitRange &range2) const
Compare bits as signed integers.
static Interval hull(size_t v1, size_t v2)
Construct an interval from two endpoints.
bool increment(Word *vec1, const BitRange &range1)
Increment.
boost::int64_t toSignedInteger(const Word *words, const BitRange &range)
Convert a bit vector to a signed integer.
BitVector & bitwiseAnd(const BitVector &other)
Bit-wise AND.
bool subtract(const Word *vec1, const BitRange &range1, Word *vec2, const BitRange &range2)
Subtract bits.
BitVector & rotateRight(const BitRange &range, size_t nShift)
Rotate bits right.
Optional< size_t > mostSignificantClearBit() const
Find the most significant clear bit.
void fromHex(Word *vec, const BitRange &range, const std::string &input)
Obtain bits from a hexadecimal representation.
BitVector & bitwiseOr(const BitVector &other)
Bit-wise OR.
size_t nClear() const
Number of clear bits.
BitVector & fromBinary(const BitRange &range, const std::string &input)
Obtain bits from a binary representation.
BitVectorSupport::BitRange BitRange
Describes an inclusive interval of bit indices.
bool isEqualToZero(const BitRange &range) const
Compare to zero.
BitVector & swap(const BitRange &range1, const BitRange &range2)
Swap some bits.
BitVector & fromInteger(const BitRange &range, boost::uint64_t value)
Obtain bits from an integer.
BitVector & fromOctal(const BitRange &range, const std::string &input)
Obtain bits from an octal representation.
BitVector & set()
Assign true to all bits.
BitVector & fromOctal(const std::string &input)
Obtain bits from an octal representation.
BitVector & bitwiseAnd(const BitRange &range1, const BitRange &range2)
Bit-wise AND.
Optional< size_t > leastSignificantDifference(const BitVector &other) const
Find least significant difference.
Optional< size_t > mostSignificantDifference(const BitVector &other) const
Find most significant difference.
size_t nSet() const
Number of set bits.
size_t nClear(const Word *words, const BitRange &range)
Number of clear bits.
Optional< size_t > mostSignificantSetBit(const Word *words, const BitRange &range)
Index of most significant set bit.
BitVector & bitwiseOr(const BitRange &range1, const BitVector &other, const BitRange &range2)
Bit-wise OR.
bool subtract(const BitVector &other)
Subtract bits as integers.
bool increment(const BitRange &range1)
Increment bits as integer.
bool signExtend(const Word *vec1, const BitRange &range1, Word *vec2, const BitRange &range2)
Sign extend.
void clear(Word *words, const BitRange &where)
Clear some bits.
BitVector & resize(size_t newSize, bool newBits=false)
Change vector size.
bool add(const BitRange &range1, const BitVector &other, const BitRange &range2)
Add bits as integers.
bool equalTo(const BitRange &range1, BitVector &other, const BitRange &range2) const
Checks whether two ranges are equal.
bool subtract(const BitRange &range1, const BitRange &range2)
Subtract bits as integers.
void multiply10(Word *vec, const BitRange &range)
Multiply by 10.
void fromOctal(Word *vec, const BitRange &range, const std::string &input)
Obtain bits from an octal representation.
Optional< size_t > mostSignificantDifference(const Word *vec1, const BitRange &range1, const Word *vec2, const BitRange &range2)
Find most significant different bits.
size_t nSet(const Word *words, const BitRange &range)
Number of set bits.
BitVector multiplySigned(const BitVector &other) const
Multiply two signed integers.
void shiftRight(Word *words, const BitRange &range, size_t nShift, bool newBits=0)
Shift bits right.
std::string toHex() const
Convert to a hexadecimal string.
bool decrement()
Decrement bits as integer.
void shiftRightArithmetic(Word *words, const BitRange &range, size_t nShift)
Shift bits right arithmetically.
void bitwiseOr(const Word *vec1, const BitRange &range1, Word *vec2, const BitRange &range2)
Bit-wise OR.
boost::uint64_t toInteger(const BitRange &range) const
Interpret bits as an unsigned integer.
Optional< size_t > leastSignificantSetBit(const Word *words, const BitRange &range)
Index of least significant set bit.
Optional< size_t > leastSignificantClearBit(const Word *words, const BitRange &range)
Index of least significant zero bit.
BitVector & invert()
Invert bits.
std::string toBinary(const BitRange &range) const
Convert to a binary string.
BitVector & clear()
Assign zero to all bits.
size_t capacity() const
Maximum size before reallocation.
std::string toOctal() const
Convert to an octal string.
BitVector & shiftRight(const BitRange &range, size_t nShift, bool newBits=0)
Shift bits right.
int compare(const BitRange &range1, const BitRange &range2) const
Compare bits as integers.
int compareSigned(const Word *vec1, const BitRange &range1, const Word *vec2, const BitRange &range2)
Signed comparison.