#ifndef __CXXMPH_MPH_BITS_H__ #define __CXXMPH_MPH_BITS_H__ #include // for uint32_t and friends #include #include #include #include #include #include #include #include #include namespace cxxmph { class dynamic_2bitset { public: dynamic_2bitset() : size_(0), fill_(false) {} dynamic_2bitset(uint32_t size, bool fill = false) : size_(size), fill_(fill), data_(ceil(size / 4.0), ones()*fill) { if (data_.size()) fprintf(stderr, "creating %p size %d\n", &data_[0], data_.size()); } ~dynamic_2bitset() { if (data_.size()) fprintf(stderr, "Deleting %p size %d\n", &data_[0], data_.size()); } const uint8_t operator[](uint32_t i) const { return get(i); } const uint8_t get(uint32_t i) const { assert(i < size()); assert((i >> 2) < data_.size()); return (data_[(i >> 2)] >> (((i & 3) << 1)) & 3); } uint8_t set(uint32_t i, uint8_t v) { assert((i >> 2) < data_.size()); data_[(i >> 2)] |= ones() ^ dynamic_2bitset::vmask[i & 3]; data_[(i >> 2)] &= ((v << ((i & 3) << 1)) | dynamic_2bitset::vmask[i & 3]); assert(v <= 3); assert(get(i) == v); } void resize(uint32_t size) { size_ = size; data_.resize(size >> 2, fill_*ones()); } void swap(dynamic_2bitset& other) { std::swap(other.size_, size_); std::swap(other.fill_, fill_); other.data_.swap(data_); } void clear() { data_.clear(); size_ = 0; } uint32_t size() const { return size_; } static const uint8_t vmask[]; const std::vector& data() const { return data_; } // private: uint32_t size_; bool fill_; std::vector data_; const uint8_t ones() { return std::numeric_limits::max(); } }; static void set_2bit_value(uint8_t *d, uint32_t i, uint8_t v) { d[(i >> 2)] &= ((v << ((i & 3) << 1)) | dynamic_2bitset::vmask[i & 3]); } static uint32_t get_2bit_value(const uint8_t* d, uint32_t i) { return (d[(i >> 2)] >> (((i & 3) << 1)) & 3); } static uint32_t nextpoweroftwo(uint32_t k) { if (k == 0) return 1; k--; for (int i=1; i> i; return k+1; } // 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 } // namespace cxxmph #endif