diff --git a/cxxmph/mph_bits.cc b/cxxmph/mph_bits.cc index 510572c..8c4185e 100644 --- a/cxxmph/mph_bits.cc +++ b/cxxmph/mph_bits.cc @@ -4,4 +4,25 @@ namespace cxxmph { const uint8_t dynamic_2bitset::vmask[] = { 0xfc, 0xf3, 0xcf, 0x3f}; +template struct bitcount { +enum { value = (n & mask ? 1:0) + bitcount> 1)>::value }; +}; +template struct bitcount { enum { value = 0 }; }; + +template +class CompileTimeRankTable { +public: +CompileTimeRankTable() : current(bitcount::value) { } +uint8_t operator[] (uint8_t i) { return *(¤t + size - i - 1); } +private: +unsigned char current; +CompileTimeRankTable next; +}; +template class CompileTimeRankTable { }; +static CompileTimeRankTable<256> kRanktable; + +uint8_t Ranktable::get(uint8_t i) { return kRanktable[i]; } + + + } diff --git a/cxxmph/mph_bits.h b/cxxmph/mph_bits.h index a32f31f..57debec 100644 --- a/cxxmph/mph_bits.h +++ b/cxxmph/mph_bits.h @@ -62,30 +62,19 @@ static uint32_t nextpoweroftwo(uint32_t k) { for (int i=1; i> i; return k+1; } - -template struct bitcount { -enum { value = (n & mask ? 1:0) + bitcount> 1)>::value }; -}; -template struct bitcount { enum { value = 0 }; }; - -template -class CompileTimeRankTable { -public: -CompileTimeRankTable() : current(bitcount::value) { } -int operator[] (int i) { return *(¤t + size - i - 1); } -private: -unsigned char current; -CompileTimeRankTable next; -}; -template class CompileTimeRankTable { }; -typedef CompileTimeRankTable<256> Ranktable; - // Interesting bit tricks that might end up here: // http://graphics.stanford.edu/~seander/bithacks.html#ZeroInWord // Fast a % (k*2^t) // http://www.azillionmonkeys.com/qed/adiv.html // rank and select: // http://vigna.dsi.unimi.it/ftp/papers/Broadword.pdf + +struct Ranktable { static uint8_t get(uint8_t); }; +static uint8_t rank64(uint64_t bits) { + auto bytes = reinterpret_cast(&bits); + return Ranktable::get(bytes[0]) + Ranktable::get(bytes[1]) + + Ranktable::get(bytes[2]) + Ranktable::get(bytes[3]); +}; } // namespace cxxmph diff --git a/cxxmph/mph_bits_test.cc b/cxxmph/mph_bits_test.cc index 0105265..7af4b66 100644 --- a/cxxmph/mph_bits_test.cc +++ b/cxxmph/mph_bits_test.cc @@ -4,7 +4,7 @@ #include "mph_bits.h" using cxxmph::dynamic_2bitset; -using cxxmph::Ranktable; +using cxxmph::rank64; int main(int argc, char** argv) { dynamic_2bitset small(256, true); @@ -55,11 +55,10 @@ int main(int argc, char** argv) { dynamic_2bitset large(1000, true); empty.swap(large); - Ranktable ranktable; - if (ranktable[0] != 0) exit(-1); - if (ranktable[1] != 1) exit(-1); - if (ranktable[2] != 1) exit(-1); - if (ranktable[255] != 8) exit(-1); + if (rank64(0) != 0) exit(-1); + if (rank64(1) != 1) exit(-1); + if (rank64(2) != 1) exit(-1); + if (rank64(255) != 8) exit(-1); }