#ifndef MARISA_BITVECTOR_H_ #define MARISA_BITVECTOR_H_ #include "rank.h" #include "vector.h" namespace marisa { class BitVector { public: BitVector(); void build(); void clear_select0s() { select0s_.clear(); } void clear_select1s() { select1s_.clear(); } void mmap(Mapper *mapper, const char *filename, long offset = 0, int whence = SEEK_SET); void map(const void *ptr, std::size_t size); void map(Mapper &mapper); void load(const char *filename, long offset = 0, int whence = SEEK_SET); void fread(std::FILE *file); void read(int fd); void read(std::istream &stream); void read(Reader &reader); void save(const char *filename, bool trunc_flag = true, long offset = 0, int whence = SEEK_SET) const; void fwrite(std::FILE *file) const; void write(int fd) const; void write(std::ostream &stream) const; void write(Writer &writer) const; void push_back(bool bit) { MARISA_THROW_IF(size_ == max_size(), MARISA_SIZE_ERROR); if ((size_ % 32) == 0) { blocks_.push_back(0); } if (bit) { blocks_.back() |= 1U << (size_ % 32); } ++size_; } bool operator[](std::size_t i) const { MARISA_DEBUG_IF(i >= size_, MARISA_PARAM_ERROR); return (blocks_[i / 32] & (1U << (i % 32))) != 0; } UInt32 rank0(UInt32 i) const { MARISA_DEBUG_IF(i > size_, MARISA_PARAM_ERROR); return i - rank1(i); } UInt32 rank1(UInt32 i) const; UInt32 select0(UInt32 i) const; UInt32 select1(UInt32 i) const; std::size_t size() const { return size_; } bool empty() const { return blocks_.empty(); } std::size_t max_size() const { return MARISA_UINT32_MAX; } std::size_t total_size() const { return blocks_.total_size() + sizeof(size_) + ranks_.total_size() + select0s_.total_size() + select1s_.total_size(); } void clear(); void swap(BitVector *rhs); private: Vector<UInt32> blocks_; UInt32 size_; Vector<Rank> ranks_; Vector<UInt32> select0s_; Vector<UInt32> select1s_; // Disallows copy and assignment. BitVector(const BitVector &); BitVector &operator=(const BitVector &); }; } // namespace marisa #endif // MARISA_BITVECTOR_H_