8#ifndef Sawyer_BitVectorSupport_H 
    9#define Sawyer_BitVectorSupport_H 
   12#include <boost/cstdint.hpp> 
   13#include <boost/foreach.hpp> 
   14#include <boost/lexical_cast.hpp> 
   16#include <Sawyer/Assert.h> 
   17#include <Sawyer/Interval.h> 
   18#include <Sawyer/Optional.h> 
   19#include <Sawyer/Sawyer.h> 
   27namespace BitVectorSupport {
 
   31template<
class T> 
struct RemoveConst<const T> { 
typedef T Base; };
 
   42    enum { value = 8 * 
sizeof(Word) };
 
 
   72Word 
bitMask(
size_t offset, 
size_t nbits) {
 
   75    return mask << offset;
 
 
   83template<
class Processor, 
class Word>
 
   84bool processWord(Processor &processor, 
const Word &word, 
size_t shift, 
size_t nbits) {
 
   87    const Word tmp = word >> shift;
 
   88    return processor(tmp, nbits);
 
 
   91template<
class Processor, 
class Word>
 
   92bool processWord(Processor &processor, Word &word, 
size_t shift, 
size_t nbits) {
 
   94    Word tmp = word >> shift;
 
   95    bool retval = processor(tmp, nbits);
 
   96    word &= ~bitMask<Word>(shift, nbits);
 
   97    word |= (tmp & bitMask<Word>(0, nbits)) << shift;
 
 
  101template<
class Processor, 
class Word>
 
  102bool processWord(Processor &processor, 
const Word &src, Word &dst, 
size_t shift, 
size_t nbits) {
 
  105    const Word tmpSrc = src >> shift;
 
  106    Word tmpDst = dst >> shift;
 
  107    bool retval = processor(tmpSrc, tmpDst, nbits);
 
  108    dst &= ~bitMask<Word>(shift, nbits);
 
  109    dst |= (tmpDst & bitMask<Word>(0, nbits)) << shift;
 
 
  112template<
class Processor, 
class Word>
 
  113bool processWord(Processor &processor, Word &w1, Word &w2, 
size_t shift, 
size_t nbits) {
 
  116    Word tmp1 = w1 >> shift;
 
  117    Word tmp2 = w2 >> shift;
 
  118    bool retval = processor(tmp1, tmp2, nbits);
 
  119    Word mask = bitMask<Word>(shift, nbits);
 
  121    w1 |= (tmp1 << shift) & mask;
 
  123    w2 |= (tmp2 << shift) & mask;
 
 
  126template<
class Processor, 
class Word>
 
  127bool processWord(Processor &processor, 
const Word &w1, 
const Word &w2, 
size_t shift, 
size_t nbits) {
 
  130    Word tmp1 = w1 >> shift;
 
  131    Word tmp2 = w2 >> shift;
 
  132    return processor(tmp1, tmp2, nbits);
 
 
  138void nonoverlappingCopy(
const Word *src, 
const BitRange &srcRange, Word *dst, 
const BitRange &dstRange) {
 
  139    ASSERT_require(srcRange.size()==dstRange.size());
 
  140    ASSERT_require(src != dst);
 
  142    size_t dstFirstIdx = wordIndex<Word>(dstRange.least());
 
  143    size_t dstLastIdx  = wordIndex<Word>(dstRange.greatest());
 
  144    size_t srcFirstIdx = wordIndex<Word>(srcRange.least());
 
  145    size_t srcLastIdx  = wordIndex<Word>(srcRange.greatest());
 
  147    size_t srcOffset = srcFirstIdx - dstFirstIdx; 
 
  149    size_t srcBitIdx = bitIndex<Word>(srcRange.least());
 
  150    size_t dstBitIdx = bitIndex<Word>(dstRange.least());
 
  152    if (srcBitIdx < dstBitIdx) {
 
  154        const size_t leftShiftAmount = dstBitIdx - srcBitIdx;
 
  155        const size_t rightShiftAmount = bitsPerWord<Word>::value - leftShiftAmount;
 
  157        for (
size_t i=dstFirstIdx; i<=dstLastIdx; ++i) {
 
  158            const Word tmp = (i+srcOffset > srcFirstIdx ? (src[i+srcOffset-1] >> rightShiftAmount) : Word(0)) |
 
  159                             (i+srcOffset > srcLastIdx ? Word(0) : (src[i+srcOffset] << leftShiftAmount));
 
  160            Word mask = bitMask<Word>(0, bitsPerWord<Word>::value);
 
  162                mask &= ~bitMask<Word>(0, bitIndex<Word>(dstRange.least()));
 
  164                mask &= bitMask<Word>(0, bitIndex<Word>(dstRange.greatest())+1);
 
  166            dst[i] |= tmp & mask;
 
  168    } 
else if (srcBitIdx > dstBitIdx) {
 
  170        const size_t rightShiftAmount = srcBitIdx - dstBitIdx;
 
  171        const size_t leftShiftAmount = bitsPerWord<Word>::value - rightShiftAmount;
 
  173        for (
size_t i=dstFirstIdx; i<=dstLastIdx; ++i) {
 
  174            const Word tmp = (src[i+srcOffset] >> rightShiftAmount) |
 
  175                             (i+srcOffset+1 <= srcLastIdx ? (src[i+srcOffset+1] << leftShiftAmount) : Word(0));
 
  176            Word mask = bitMask<Word>(0, bitsPerWord<Word>::value);
 
  178                mask &= ~bitMask<Word>(0, bitIndex<Word>(dstRange.least()));
 
  180                mask &= bitMask<Word>(0, bitIndex<Word>(dstRange.greatest())+1);
 
  182            dst[i] |= tmp & mask;
 
  186        for (
size_t i=dstFirstIdx; i<=dstLastIdx; ++i) {
 
  187            const Word tmp = src[i+srcOffset];
 
  188            Word 
mask = bitMask<Word>(0, bitsPerWord<Word>::value);
 
  190                mask &= ~bitMask<Word>(0, bitIndex<Word>(dstRange.least()));
 
  192                mask &= bitMask<Word>(0, bitIndex<Word>(dstRange.greatest())+1);
 
  194            dst[i] |= tmp & 
mask;
 
  199template<
class Src, 
class Dst>
 
  200void conditionalCopy(
const Src *src, 
const BitRange &srcRange, Dst *dst, 
const BitRange &dstRange) {
 
  201    nonoverlappingCopy(src, srcRange, dst, dstRange);
 
  203template<
class Src, 
class Dst>
 
  204void conditionalCopy(
const Src *, 
const BitRange &, 
const Dst *, 
const BitRange &) {
 
  213template<
class Processor, 
class Word>
 
  217    size_t nRemaining = range.size();
 
  218    size_t offsetInWord = bitIndex<Word>(range.least());
 
  220    for (
size_t wordIdx = wordIndex<Word>(range.least()); !done && nRemaining > 0; ++wordIdx) {
 
  222        ASSERT_require(nbits > 0);
 
  223        done = 
processWord(processor, words[wordIdx], offsetInWord, nbits);
 
 
  230template<
class Processor, 
class Word>
 
  234    size_t nRemaining = range.size();
 
  235    size_t offsetInWord = bitIndex<Word>(range.least());
 
  237    size_t firstWordIdx = wordIndex<Word>(range.least());
 
  238    size_t lastWordIdx = wordIndex<Word>(range.greatest());
 
  239    for (
size_t wordIdx=lastWordIdx; !done && nRemaining > 0; --wordIdx) {
 
  241        if (wordIdx == firstWordIdx) {
 
  244        } 
else if (wordIdx < lastWordIdx) {
 
  248            ASSERT_require(wordIdx==lastWordIdx);
 
  249            ASSERT_require(wordIdx>firstWordIdx);
 
  252            ASSERT_require(nRemaining > nBitsToLeft);
 
  253            nbits = nRemaining - nBitsToLeft;
 
  256        done = 
processWord(processor, words[wordIdx], wordIdx==firstWordIdx ? offsetInWord : 0, nbits);
 
 
  262template<
class Processor, 
class Word1, 
class Word2>
 
  264    ASSERT_require(
sizeof(Word1)==
sizeof(Word2));       
 
  268    ASSERT_require(range1.
size() == range2.
size());
 
  273    size_t offsetInWord = bitIndex<Word2>(range2.
least());
 
  274    const size_t nWordsTmp = numberOfWords<Word2>(offsetInWord + range2.
size());
 
  275    SAWYER_VARIABLE_LENGTH_ARRAY(
typename RemoveConst<Word1>::Base, tmp, nWordsTmp);
 
  277    nonoverlappingCopy(vec1, range1, tmp, tmpRange);
 
  281    const size_t vec2WordOffset = wordIndex<Word2>(range2.
least());
 
  282    size_t nRemaining = range2.
size();
 
  284    for (
size_t wordIdx=0; !done && nRemaining > 0; ++wordIdx) {
 
  285        ASSERT_require(wordIdx < nWordsTmp);
 
  287        ASSERT_require(nbits > 0);
 
  288        done = 
processWord(processor, *
const_cast<Word1*
>(tmp+wordIdx), vec2[wordIdx+vec2WordOffset], offsetInWord, nbits);
 
  294    conditionalCopy(tmp, tmpRange, vec1, range1);
 
 
  298template<
class Processor, 
class Word1, 
class Word2>
 
  300    ASSERT_require(
sizeof(Word1)==
sizeof(Word2));       
 
  304    ASSERT_require(range1.
size() == range2.
size());
 
  309    const size_t offsetInWord = bitIndex<Word2>(range2.
least());
 
  310    const size_t nWordsTmp = numberOfWords<Word2>(offsetInWord + range2.
size());
 
  311    SAWYER_VARIABLE_LENGTH_ARRAY(
typename RemoveConst<Word1>::Base, tmp, nWordsTmp);
 
  313    nonoverlappingCopy(vec1, range1, tmp, tmpRange);
 
  316    size_t nRemaining = range2.
size();
 
  318    const size_t vec2WordOffset = wordIndex<Word2>(range2.
least());
 
  319    for (
size_t wordIdx=nWordsTmp-1; !done && nRemaining>0; --wordIdx) {
 
  324        } 
else if (wordIdx < nWordsTmp-1) {
 
  328            ASSERT_require(wordIdx==nWordsTmp-1);
 
  329            ASSERT_require(wordIdx>0);
 
  331            ASSERT_require(nRemaining > nBitsToLeft);
 
  332            nbits = nRemaining - nBitsToLeft;
 
  335        done = 
processWord(processor, *
const_cast<Word1*
>(tmp+wordIdx), vec2[wordIdx+vec2WordOffset],
 
  336                           wordIdx==0 ? offsetInWord : 0, nbits);
 
  341    conditionalCopy(tmp, tmpRange, vec1, range1);
 
 
  344template<
class Processor, 
class Word>
 
  346              const Word *vec1, 
const BitRange &range1,
 
  347              const Word *vec2, 
const BitRange &range2,
 
  349    traverse2(processor, vec1, range1, vec2, range2, dir);
 
  352template<
class Processor, 
class Word>
 
  354              const Word *vec1, 
const BitRange &range1,
 
  355              const Word *vec2, 
const BitRange &range2,
 
  357    traverse2(processor, vec1, range1, vec2, range2, dir);
 
  359template<
class Processor, 
class Word>
 
  361              const Word *vec1, 
const BitRange &range1,
 
  362                    Word *vec2, 
const BitRange &range2,
 
  364    traverse2(processor, vec1, range1, vec2, range2, dir);
 
  366template<
class Processor, 
class Word>
 
  368              Word *vec1, 
const BitRange &range1,
 
  369              Word *vec2, 
const BitRange &range2,
 
  371    traverse2(processor, vec1, range1, vec2, range2, dir);
 
  384bool get(
const Word *words, 
size_t idx) {
 
  385    return 0 != (words[wordIndex<Word>(idx)] & bitMask<Word>(bitIndex<Word>(idx), 1));
 
 
  390    bool operator()(Word &word, 
size_t nbits) {
 
  391        word &= ~bitMask<Word>(0, nbits);
 
 
  407    bool operator()(Word &word, 
size_t nbits) {
 
  408        word |= bitMask<Word>(0, nbits);
 
 
  436    bool operator()(
const Word &src, Word &dst, 
size_t nbits) {
 
  437        dst &= ~bitMask<Word>(0, nbits);
 
  438        dst |= src & bitMask<Word>(0, nbits);
 
 
  455    bool operator()(Word &w1, Word &w2, 
size_t nbits) {
 
  456        Word tmp = w1, mask = bitMask<Word>(0, nbits);
 
 
  472    ASSERT_require(vec1!=vec2 || !range1.
overlaps(range2));
 
 
  483    bool operator()(
const Word &w1, Word &w2, 
size_t nbits) {
 
  485            Word a = w1 & bitMask<Word>(0, nbits);
 
  486            Word b = w2 & bitMask<Word>(0, nbits);
 
 
  502    return visitor.wasEqv;
 
 
  515    bool operator()(
const Word &word, 
size_t nbits) {
 
  516        if (0 != (word & bitMask<Word>(0, nbits))) {
 
  517            for (
size_t i=0; i<nbits; ++i) {
 
  518                if (0 != (word & bitMask<Word>(i, 1))) {
 
 
  538        return range.least() + *visitor.result;
 
 
  547    bool operator()(
const Word &word, 
size_t nbits) {
 
  548        if (bitMask<Word>(0, nbits) != (word & bitMask<Word>(0, nbits))) {
 
  549            for (
size_t i=0; i<nbits; ++i) {
 
  550                if (0 == (word & bitMask<Word>(i, 1))) {
 
 
  570        return range.least() + *visitor.result;
 
 
  579    bool operator()(
const Word &word, 
size_t nbits) {
 
  580        ASSERT_require(nbits <= offset);
 
  582        if (0 != (word & bitMask<Word>(0, nbits))) {
 
  583            for (
size_t i=nbits; i>0; --i) {
 
  584                if (0 != (word & bitMask<Word>(i-1, 1))) {
 
  585                    result = offset + i-1;
 
 
  603        return range.least() + *visitor.result;
 
 
  612    bool operator()(
const Word &word, 
size_t nbits) {
 
  613        ASSERT_require(nbits <= offset);
 
  615        if (bitMask<Word>(0, nbits) != (word & bitMask<Word>(0, nbits))) {
 
  616            for (
size_t i=nbits; i>0; --i) {
 
  617                if (0 == (word & bitMask<Word>(i-1, 1))) {
 
  618                    result = offset + i-1;
 
 
  636        return range.least() + *visitor.result;
 
 
  660    bool operator()(
const Word &word, 
size_t nbits) {
 
  661        if (0 != (word & bitMask<Word>(0, nbits))) {
 
  662            for (
size_t i=0; i<nbits; ++i) {
 
  663                if (0 != (word & bitMask<Word>(i, 1)))
 
 
  678    return visitor.result;
 
 
  685    bool operator()(
const Word &word, 
size_t nbits) {
 
  686        if (bitMask<Word>(0, nbits) != (word & bitMask<Word>(0, nbits))) {
 
  687            for (
size_t i=0; i<nbits; ++i) {
 
  688                if (0 == (word & bitMask<Word>(i, 1)))
 
 
  703    return visitor.result;
 
 
  711    bool operator()(
const Word &w1, 
const Word &w2, 
size_t nbits) {
 
  712        Word mask = bitMask<Word>(0, nbits);
 
  713        if ((w1 & mask) != (w2 & mask)) {
 
  714            for (
size_t i=0; i<nbits; ++i) {
 
  715                if ((w1 ^ w2) & bitMask<Word>(i, 1)) {
 
 
  733                                            const Word *vec2, 
const BitRange &range2) {
 
  736    return visitor.result;
 
 
  744    bool operator()(
const Word &w1, 
const Word &w2, 
size_t nbits) {
 
  745        ASSERT_require(nbits <= offset);
 
  747        Word mask = bitMask<Word>(0, nbits);
 
  748        if ((w1 & mask) != (w2 & mask)) {
 
  749            for (
size_t i=nbits; i>0; --i) {
 
  750                if ((w1 ^ w2) & bitMask<Word>(i-1, 1)) {
 
  751                    result = offset + i-1;
 
 
  767                                           const Word *vec2, 
const BitRange &range2) {
 
  770    return visitor.result;
 
 
  794    if (nShift < range.size()) {
 
  795        size_t nbits = range.size() - nShift;           
 
  799        copy(words, shiftedFrom, words, shiftedTo);
 
  800        setValue(words, introduced, newBits);
 
 
  812    if (nShift < range.size()) {
 
  813        size_t nbits = range.size() - nShift;           
 
  817        copy(words, shiftedFrom, words, shiftedTo);
 
  818        setValue(words, introduced, newBits);
 
 
  830    if (!range.isEmpty()) {
 
  831        bool newBits = 
get(words, range.greatest());
 
 
  844    nShift %= range.size();
 
  849    size_t nSavedWords = numberOfWords<Word>(nShift);
 
  850    SAWYER_VARIABLE_LENGTH_ARRAY(Word, saved, nSavedWords);
 
  857    copy(saved, savedRange, words, introduced);
 
 
  868    nShift %= range.size();
 
 
  879    bool operator()(Word &word, 
size_t nbits) {
 
  880        word ^= bitMask<Word>(0, nbits);
 
 
  896    bool operator()(
const Word &w1, Word &w2, 
size_t nbits) {
 
  897        w2 &= w1 | ~bitMask<Word>(0, nbits);
 
 
  914    bool operator()(
const Word &w1, Word &w2, 
size_t nbits) {
 
  915        w2 |= w1 & bitMask<Word>(0, nbits);
 
 
  932    bool operator()(
const Word &w1, Word &w2, 
size_t nbits) {
 
  933        w2 ^= w1 & bitMask<Word>(0, nbits);
 
 
  958    ASSERT_require(8==
sizeof value);
 
  963    size_t nbits = std::min(range.size(), (
size_t)64);  
 
  965    size_t nTmpWords = numberOfWords<Word>(nbits);
 
  966    SAWYER_VARIABLE_LENGTH_ARRAY(Word, tmp, nTmpWords);
 
  967    for (
size_t i=0; i<nTmpWords; ++i)
 
  972    if (range.size() >= 64) {
 
 
  984    boost::uint64_t result = 0;
 
  985    ASSERT_require(8==
sizeof result);
 
  988    size_t nbits = std::min(range.size(), (
size_t)64);
 
  989    size_t nTmpWords = numberOfWords<Word>(nbits);
 
  990    SAWYER_VARIABLE_LENGTH_ARRAY(
typename RemoveConst<Word>::Base, tmp, nTmpWords);
 
  995    for (
size_t i=0; i<nTmpWords; ++i)
 
 
 1005    boost::uint64_t result = 0;
 
 1006    ASSERT_require(nbits <= 64);
 
 1007    size_t nTmpWords = numberOfWords<Word>(nbits);
 
 1008    for (
size_t i=0; i<nTmpWords; ++i)
 
 1011        result &= ~((~(boost::uint64_t)0) << nbits);
 
 
 1022    boost::uint64_t u = toInteger<Word>(words, range);
 
 1023    const size_t nBits = range.size();
 
 1024    if (nBits > 1 && nBits < 64) {
 
 1025        bool isNegative = (u & (boost::uint64_t(1) << (nBits-1))) != 0;
 
 1027            u |= boost::uint64_t(-1) << nBits;
 
 1029    return boost::int64_t(u);
 
 
 1038    boost::uint64_t u = toInteger<Word>(words, nBits);
 
 1039    if (nBits > 1 && nBits < 64) {
 
 1040        bool isNegative = (u & (boost::uint64_t(1) << (nBits-1))) != 0;
 
 1042            u |= boost::uint64_t(-1) << nBits;
 
 1044    return boost::int64_t(u);
 
 
 1051    bool operator()(Word &word, 
size_t nbits) {
 
 1052        ASSERT_require(carry);
 
 1053        Word mask = bitMask<Word>(0, nbits);
 
 1054        Word arg1 = word & mask;
 
 1055        Word sum = arg1 + 1;
 
 1058        carry = (sum & mask) < arg1;
 
 
 1070    return visitor.carry;
 
 
 1077    bool operator()(Word &word, 
size_t nbits) {
 
 1078        ASSERT_require(borrowed);
 
 1079        Word mask = bitMask<Word>(0, nbits);
 
 1080        Word arg1 = word & mask;
 
 1082        Word difference = (arg1 - 1) & mask;
 
 
 1097    return visitor.borrowed;
 
 
 1112    AddBits(
bool carry): carry(carry) {}
 
 1113    bool operator()(
const Word &w1, Word &w2, 
size_t nbits) {
 
 1114        Word mask = bitMask<Word>(0, nbits);
 
 1115        Word addend1(carry ? 1 : 0);
 
 1116        Word addend2(w1 & mask);
 
 1117        Word addend3(w2 & mask);
 
 1118        Word sum = addend1 + addend2 + addend3;
 
 1122            carry = sum < addend2 || (sum==addend2 && carry);
 
 1124            carry = 0 != (sum & bitMask<Word>(nbits, 1));
 
 
 1138    return visitor.carry;
 
 
 1149    size_t nTempWords = numberOfWords<Word>(range1.
size());
 
 1150    SAWYER_VARIABLE_LENGTH_ARRAY(Word, temp, nTempWords);
 
 1152    copy(vec1, range1, temp, tempRange);
 
 1154    return add(temp, tempRange, vec2, range2, 
true);
 
 
 1167    } 
else if (range1.
isEmpty()) {
 
 1168        clear(vec2, range2);
 
 1170    } 
else if (range1.
size() < range2.
size()) {         
 
 1176        ASSERT_require(range1.
size() >= range2.
size());
 
 1178        copy(vec1, copyFrom, vec2, range2);
 
 
 1189    const size_t nWords = numberOfWords<Word>(range.size());
 
 1191    SAWYER_VARIABLE_LENGTH_ARRAY(Word, part, nWords);
 
 1192    copy(vec, range, part, partRange);
 
 1195    add(part, partRange, vec, range);
 
 
 1214    bool operator()(
const Word &w1, 
const Word &w2, 
size_t nbits) {
 
 1215        Word mask = bitMask<Word>(0, nbits);
 
 1216        Word tmp1 = w1 & mask;
 
 1217        Word tmp2 = w2 & mask;
 
 1221        } 
else if (tmp1 > tmp2) {
 
 
 1240    } 
else if (range1.
isEmpty()) {
 
 1242    } 
else if (range2.
isEmpty()) {
 
 1244    } 
else if (range1.
size() < range2.
size()) {
 
 1249        return compare(vec1, range1, vec2, lo);
 
 1250    } 
else if (range1.
size() > range2.
size()) {
 
 1255        return compare(vec1, lo, vec2, range2);
 
 1258        ASSERT_require(range1.
size() == range2.
size());
 
 1261        return visitor.result;
 
 
 1275    } 
else if (range1.
isEmpty()) {
 
 1277            return *mssb == range2.
greatest() ? 1 : -1;
 
 1281    } 
else if (range2.
isEmpty()) {
 
 1283            return *mssb == range1.
greatest() ? -1 : 1;
 
 1287    } 
else if (range1.
size() < range2.
size()) {
 
 1291        if (!neg1 && !neg2) {                           
 
 1292            return compare(vec1, range1, vec2, range2);
 
 1293        } 
else if (neg1 && neg2) {                      
 
 1304    } 
else if (range1.
size() > range2.
size()) {         
 
 1307        ASSERT_require(range1.
size()==range2.
size());
 
 1310        if (!neg1 && !neg2) {
 
 1311            return compare(vec1, range1, vec2, range2);
 
 1312        } 
else if (neg1 && neg2) {
 
 1314                return get(vec1, range1.
least() + *diff) ? 1 : -1;
 
 
 1332    size_t nremaining = 0;                              
 
 1333    std::vector<uint8_t> bytes;                         
 
 1336        const size_t nBytes = (nBitsTotal + 7) / 8;
 
 1337        bytes.reserve(nBytes);
 
 1340    bool operator()(
const Word &word, 
size_t nbits) {
 
 1342        ASSERT_require(nremaining < 
size_t(8));
 
 1343        while (nremaining + nbits >= 
size_t(8)) {
 
 1344            const size_t nrem = nremaining;             
 
 1345            const size_t nnew = size_t(8) - nrem;       
 
 1346            const Word 
byte = (remaining & bitMask<Word>(0, nrem)) | ((tmp & bitMask<Word>(0, nnew)) << nrem);
 
 1347            bytes.push_back(
byte);
 
 1357    std::vector<uint8_t> result() {
 
 1358        if (nremaining > 0) {
 
 1359            ASSERT_require(nremaining <= 7);
 
 1360            const uint8_t 
byte = remaining & bitMask<Word>(0, nremaining);
 
 1361            bytes.push_back(
byte);
 
 1363        return std::move(bytes);
 
 
 1369toBytes(
const Word *vec, 
const BitRange &range) {
 
 1372    return visitor.result();
 
 1376void fromBytes(Word *vec, 
const BitRange &range, 
const std::vector<uint8_t> &input) {
 
 1379    for (
size_t idx = 0; idx < input.size() && offset < range.size(); ++idx) {
 
 1380        const Word 
byte = input[idx];
 
 1381        const size_t nbits = std::min(
size_t(8), range.size() - offset); 
 
 1387    if (offset < range.size())
 
 1396template<
class Word, 
size_t bitsPerDigit>
 
 1400    std::string reversed;                               
 
 1402    ToString(): remaining(0), nremaining(0) {
 
 1403        ASSERT_require(bitsPerDigit >= 1 && bitsPerDigit <= 4);
 
 1407    bool operator()(
const Word &word, 
size_t nbits) {
 
 1408        static const char digits[] = {
'0', 
'1', 
'2', 
'3', 
'4', 
'5', 
'6', 
'7', 
'8', 
'9', 
'a', 
'b', 
'c', 
'd', 
'e', 
'f'};
 
 1409        Word tmp = word & bitMask<Word>(0, nbits);
 
 1410        ASSERT_require(nremaining < bitsPerDigit);
 
 1411        while (nremaining+nbits >= bitsPerDigit) {
 
 1412            size_t nrem = std::min(nremaining, bitsPerDigit); 
 
 1413            size_t nnew = bitsPerDigit - nrem;                
 
 1414            Word digit = (remaining & bitMask<Word>(0, nrem)) | ((tmp & bitMask<Word>(0, nnew)) << nrem);
 
 1415            reversed += digits[digit];
 
 1425    std::string result() {
 
 1426        if (nremaining > 0) {
 
 1427            ASSERT_require(nremaining <= 3);            
 
 1428            reversed += 
'0' + (remaining & bitMask<Word>(0, nremaining));
 
 1432        std::swap(s, reversed);
 
 1433        std::reverse(s.begin(), s.end());
 
 
 1448    return visitor.result();
 
 
 1460    return visitor.result();
 
 
 1472    return visitor.result();
 
 
 1480Word charToDigit(
char ch) {
 
 1482    if (ch >= 
'0' && ch <= 
'9') {
 
 1484    } 
else if (ch >= 
'a' && ch <= 
'f') {
 
 1485        digit = ch - 
'a' + 10;
 
 1486    } 
else if (ch >= 
'A' && ch <= 
'F') {
 
 1487        digit = ch - 
'A' + 10;
 
 1494template<
class Word, 
size_t bitsPerDigit>
 
 1495void fromString(Word *vec, 
const BitRange &range, 
const std::string &input) {
 
 1496    ASSERT_require(bitsPerDigit >= 1 && bitsPerDigit <= 4);
 
 1497    ASSERT_require(bitsPerDigit <= bitsPerWord<Word>::value);
 
 1500    for (
size_t idx=0; idx<input.size(); ++idx) {
 
 1501        if (
'_'!=input[idx] && charToDigit<Word>(input[idx]) >= Word(1) << bitsPerDigit) {
 
 1502            throw std::runtime_error(std::string(
"invalid character '") + input[idx] + 
"' at index " +
 
 1503                                     boost::lexical_cast<std::string>(idx) + 
" in base-" +
 
 1504                                     boost::lexical_cast<std::string>(1 << bitsPerDigit) + 
" input string");
 
 1510    for (
size_t idx=input.size(); idx>0 && offset<
range.size(); --idx) {
 
 1511        if (
'_'!=input[idx-1]) {
 
 1512            Word digit = charToDigit<Word>(input[idx-1]);
 
 1513            size_t nbits = std::min(bitsPerDigit, 
range.size()-offset);
 
 1516            offset += bitsPerDigit;
 
 1521    if (offset < 
range.size())
 
 1535    boost::uint64_t v = 0;
 
 1536    bool hadOverflow = 
false;
 
 1537    BOOST_FOREACH (
char ch, input) {
 
 1539            boost::uint64_t tmp = v * 10 + (ch - 
'0');
 
 1545        } 
else if (ch != 
'_') {
 
 1546            throw std::runtime_error(
"invalid decimal digit \"" + std::string(1, ch) + 
"\"");
 
 1555    const size_t nWords = numberOfWords<Word>(range.size());
 
 1556    SAWYER_VARIABLE_LENGTH_ARRAY(Word, accumulator, nWords);
 
 1557    SAWYER_VARIABLE_LENGTH_ARRAY(Word, digit, nWords);
 
 1559    BOOST_FOREACH (
char ch, input) {
 
 1562        add(digit, accumulatorRange, accumulator, accumulatorRange);
 
 1564    copy(accumulator, accumulatorRange, vec, range);
 
 
 1576    fromString<Word, 4>(vec, range, input);
 
 
 1587    fromString<Word, 3>(vec, range, input);
 
 
 1598    fromString<Word, 1>(vec, range, input);
 
 
 
Range of values delimited by endpoints.
 
T greatest() const
Returns upper limit.
 
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.
 
Value size() const
Size of interval.
 
bool isEmpty() const
True if interval is empty.
 
T least() const
Returns lower limit.
 
bool overlaps(const Interval &other) const
True if two intervals overlap.
 
Holds a value or nothing.
 
void fromString(source_position &, const std::string &input)
Parse a string (such as 12.10, 13, 0 etc )into source position data structure.
 
Unsigned mask(size_t least, size_t greatest)
Generate a mask.
 
SgRangeExp * range(const SgAdaAttributeExp *rangeAttribute)
returns a range for the range attribute rangeAttribute.
 
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.
 
size_t numberOfWords(size_t nbits)
Number of words to hold indicated number of bits.
 
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.
 
void traverse2(Processor &processor, Word1 *vec1, const BitRange &range1, Word2 *vec2, const BitRange &range2, LowToHigh)
Traverse two ranges of bits from low to high.
 
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.
 
Word bitMask(size_t offset, size_t nbits)
Creates a mask.
 
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.
 
void traverse(Processor &processor, Word *words, const BitRange &range, LowToHigh)
Traverses a range of bits.
 
bool areEqual(const Word *vec1, const BitRange &range1, const Word *vec2, const BitRange &range2)
Equality predicate.
 
bool processWord(Processor &processor, const Word &word, size_t shift, size_t nbits)
Invoke the a processor for a vector traversal.
 
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.
 
size_t bitIndex(size_t idx)
Index to bit within word.
 
size_t wordIndex(size_t idx)
Index to bit vector word.
 
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.
 
Tags for traversal directions.
 
For removing const qualifiers.