Added rank function implementation.
This commit is contained in:
parent
86dccdb466
commit
9375a15dd4
@ -4,4 +4,25 @@ namespace cxxmph {
|
|||||||
|
|
||||||
const uint8_t dynamic_2bitset::vmask[] = { 0xfc, 0xf3, 0xcf, 0x3f};
|
const uint8_t dynamic_2bitset::vmask[] = { 0xfc, 0xf3, 0xcf, 0x3f};
|
||||||
|
|
||||||
|
template <int n, int mask = (1 << 7)> struct bitcount {
|
||||||
|
enum { value = (n & mask ? 1:0) + bitcount<n, (mask >> 1)>::value };
|
||||||
|
};
|
||||||
|
template <int n> struct bitcount<n, 0> { enum { value = 0 }; };
|
||||||
|
|
||||||
|
template <int size, int index = size>
|
||||||
|
class CompileTimeRankTable {
|
||||||
|
public:
|
||||||
|
CompileTimeRankTable() : current(bitcount<index - 1>::value) { }
|
||||||
|
uint8_t operator[] (uint8_t i) { return *(¤t + size - i - 1); }
|
||||||
|
private:
|
||||||
|
unsigned char current;
|
||||||
|
CompileTimeRankTable<index -1> next;
|
||||||
|
};
|
||||||
|
template <int size> class CompileTimeRankTable<size, 0> { };
|
||||||
|
static CompileTimeRankTable<256> kRanktable;
|
||||||
|
|
||||||
|
uint8_t Ranktable::get(uint8_t i) { return kRanktable[i]; }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -62,30 +62,19 @@ static uint32_t nextpoweroftwo(uint32_t k) {
|
|||||||
for (int i=1; i<sizeof(uint32_t)*CHAR_BIT; i<<=1) k = k | k >> i;
|
for (int i=1; i<sizeof(uint32_t)*CHAR_BIT; i<<=1) k = k | k >> i;
|
||||||
return k+1;
|
return k+1;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <int n, int mask = (1 << 7)> struct bitcount {
|
|
||||||
enum { value = (n & mask ? 1:0) + bitcount<n, (mask >> 1)>::value };
|
|
||||||
};
|
|
||||||
template <int n> struct bitcount<n, 0> { enum { value = 0 }; };
|
|
||||||
|
|
||||||
template <int size, int index = size>
|
|
||||||
class CompileTimeRankTable {
|
|
||||||
public:
|
|
||||||
CompileTimeRankTable() : current(bitcount<index - 1>::value) { }
|
|
||||||
int operator[] (int i) { return *(¤t + size - i - 1); }
|
|
||||||
private:
|
|
||||||
unsigned char current;
|
|
||||||
CompileTimeRankTable<index -1> next;
|
|
||||||
};
|
|
||||||
template <int size> class CompileTimeRankTable<size, 0> { };
|
|
||||||
typedef CompileTimeRankTable<256> Ranktable;
|
|
||||||
|
|
||||||
// Interesting bit tricks that might end up here:
|
// Interesting bit tricks that might end up here:
|
||||||
// http://graphics.stanford.edu/~seander/bithacks.html#ZeroInWord
|
// http://graphics.stanford.edu/~seander/bithacks.html#ZeroInWord
|
||||||
// Fast a % (k*2^t)
|
// Fast a % (k*2^t)
|
||||||
// http://www.azillionmonkeys.com/qed/adiv.html
|
// http://www.azillionmonkeys.com/qed/adiv.html
|
||||||
// rank and select:
|
// rank and select:
|
||||||
// http://vigna.dsi.unimi.it/ftp/papers/Broadword.pdf
|
// 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<const uint8_t*>(&bits);
|
||||||
|
return Ranktable::get(bytes[0]) + Ranktable::get(bytes[1]) +
|
||||||
|
Ranktable::get(bytes[2]) + Ranktable::get(bytes[3]);
|
||||||
|
};
|
||||||
|
|
||||||
} // namespace cxxmph
|
} // namespace cxxmph
|
||||||
|
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
#include "mph_bits.h"
|
#include "mph_bits.h"
|
||||||
|
|
||||||
using cxxmph::dynamic_2bitset;
|
using cxxmph::dynamic_2bitset;
|
||||||
using cxxmph::Ranktable;
|
using cxxmph::rank64;
|
||||||
|
|
||||||
int main(int argc, char** argv) {
|
int main(int argc, char** argv) {
|
||||||
dynamic_2bitset small(256, true);
|
dynamic_2bitset small(256, true);
|
||||||
@ -55,11 +55,10 @@ int main(int argc, char** argv) {
|
|||||||
dynamic_2bitset large(1000, true);
|
dynamic_2bitset large(1000, true);
|
||||||
empty.swap(large);
|
empty.swap(large);
|
||||||
|
|
||||||
Ranktable ranktable;
|
if (rank64(0) != 0) exit(-1);
|
||||||
if (ranktable[0] != 0) exit(-1);
|
if (rank64(1) != 1) exit(-1);
|
||||||
if (ranktable[1] != 1) exit(-1);
|
if (rank64(2) != 1) exit(-1);
|
||||||
if (ranktable[2] != 1) exit(-1);
|
if (rank64(255) != 8) exit(-1);
|
||||||
if (ranktable[255] != 8) exit(-1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user