25 using iterator_category = std::random_access_iterator_tag;
26 using value_type = bool;
27 using difference_type = std::ptrdiff_t;
32 bool operator*()
const
34 return stool::LSBByte::get_bit(this->bits, index);
36 uint64_t get_size()
const
38 return stool::LSBByte::get_code_length(this->bits) - 1;
42 return this->index == UINT16_MAX;
47 uint64_t size = this->get_size();
48 if ((uint64_t)(this->index + 1) < size)
52 else if ((uint64_t)(this->index + 1) == size)
54 this->index = UINT16_MAX;
58 throw std::invalid_argument(
"Error: BitDequeIterator::operator++()");
80 throw std::invalid_argument(
"Error: BitDequeIterator::operator--()");
95 if ((uint64_t)(this->index + n) < this->get_size())
107 if ((uint64_t)(this->index + n) < this->get_size())
113 this->index = UINT16_MAX;
120 if (this->index - n >= 0)
126 throw std::invalid_argument(
"Error: BitContainerIterator::operator-()");
134 throw std::invalid_argument(
"Error: BitDequeIterator::operator-()");
140 uint64_t read_64bit_MSB_string()
const
142 uint64_t size = this->get_size();
143 if (this->index == size)
145 throw std::invalid_argument(
"Error: BitContainerIterator::read_64_bit_string()");
153 uint64_t p = size - this->index;
154 uint64_t return_bits = 0;
157 for(uint64_t x = 0; x < p; x++){
158 uint64_t y = x + this->index;
159 if(stool::LSBByte::get_bit(this->bits, y)){
160 return_bits = return_bits | (1ULL << (63-x));
171 return (int16_t)this->index - (int16_t)other.index;
208 BitContainer(std::vector<uint64_t> &_items)
210 for (uint64_t x : _items)
215 BitContainer(std::vector<bool> &_items)
217 for (uint64_t i = 0; i < _items.size(); i++)
219 this->push_back(_items[i]);
223 void swap(BitContainer &item)
225 std::swap(this->bits, item.bits);
227 uint64_t size()
const
229 return stool::LSBByte::get_code_length(this->bits) - 1;
231 uint64_t size_in_bytes(
bool only_extra_bytes)
const
233 if (only_extra_bytes)
239 return sizeof(uint64_t);
242 uint64_t unused_size_in_bytes()
const
247 uint64_t at(uint64_t pos)
const
249 return stool::LSBByte::get_bit(this->bits, pos);
253 throw std::runtime_error(
"Error: BitContainer");
260 static std::string name()
264 uint64_t psum(uint64_t i)
const noexcept
266 uint64_t x = (this->bits << (63 - i));
267 return __builtin_popcountll(x);
269 uint64_t psum() const noexcept
271 return __builtin_popcountll(this->bits) - 1;
273 int64_t search(uint64_t x)
const noexcept
281 uint64_t count = this->psum();
284 return stool::LSBByte::select1(this->bits, x - 1);
293 std::string to_string()
const
296 for (uint64_t i = 0; i < this->size(); i++)
298 if (this->at(i) >= 1)
310 std::vector<uint64_t> to_packed_vector()
const
312 std::vector<uint64_t> r;
313 for (uint64_t i = 0; i < this->size(); i++)
315 r.push_back(this->at(i));
319 uint64_t to_uint64()
const
321 return stool::LSBByte::write_bit(this->bits, this->size(),
false);
324 template <
typename VEC>
325 void to_values(VEC &output_vec)
const
328 output_vec.resize(this->size());
329 for (uint64_t i = 0; i < this->size(); i++)
331 output_vec[i] = this->at(i);
335 void insert(uint64_t pos, uint64_t value)
337 assert(this->size() + 1 < 64);
338 this->bits = stool::LSBByte::insert_bit(this->bits, pos, value >= 1);
340 void remove(uint64_t pos)
342 assert(this->size() > 0);
343 this->bits = stool::LSBByte::remove_bit(this->bits, pos);
345 void push_front(std::vector<uint64_t> &new_items)
347 assert(this->size() + new_items.size() < 64);
349 for (int64_t i = new_items.size() - 1; i >= 0; i--)
351 this->push_front(new_items[i]);
354 void push_front(uint64_t new_item)
356 assert(this->size() + 1 < 64);
357 this->bits = (this->bits << 1) | (new_item >= 1 ? 1 : 0);
360 void push_back(std::vector<uint64_t> &new_items)
362 assert(this->size() + 1 < 64);
363 assert(this->size() + new_items.size() < 64);
365 for (uint64_t v : new_items)
373 void push_back(uint64_t value)
375 assert(this->size() + 1 < 64);
376 this->bits = stool::LSBByte::insert_bit(this->bits, this->size(), value >= 1);
380 assert(this->size() > 0);
381 this->bits = this->bits >> 1;
383 std::vector<uint64_t> pop_front(uint64_t len)
385 assert(len <= this->size());
386 std::vector<uint64_t> r;
387 for (uint64_t i = 0; i < len; i++)
389 r.push_back(this->at(0));
396 assert(this->size() > 0);
397 this->remove(this->size() - 1);
400 std::vector<uint64_t> pop_back(uint64_t len)
402 assert(len <= this->size());
403 std::vector<uint64_t> r;
406 for (uint64_t i = 0; i < len; i++)
408 r[len - i - 1] = this->at(this->size() - 1);
414 uint64_t reverse_psum(uint64_t i)
const
416 if (i == this->size() - 1)
422 uint64_t len1 = i + 1;
423 uint64_t idx = this->size() - len1;
424 return this->psum() - this->psum(idx - 1);
428 uint64_t psum(uint64_t i, uint64_t j)
const
436 throw std::runtime_error(
"No implementation");
440 void increment(uint64_t i, int64_t delta)
444 this->bits = stool::LSBByte::write_bit(this->bits, i,
true);
446 else if (delta <= -1)
448 this->bits = stool::LSBByte::write_bit(this->bits, i,
false);
452 BitContainerIterator begin()
const
454 if (this->size() == 0)
456 return BitContainerIterator(this->bits, UINT16_MAX);
460 return BitContainerIterator(this->bits, 0);
464 BitContainerIterator end()
const
466 return BitContainerIterator(this->bits, UINT16_MAX);
469 int64_t one_based_rank1(uint64_t i)
const
477 return this->psum(i - 1);
481 int64_t one_based_rank0(uint64_t i)
const
483 return i - this->one_based_rank1(i);
485 int64_t one_based_rank(uint64_t i,
bool b)
const
487 return b ? this->one_based_rank1(i) : this->one_based_rank0(i);
490 int64_t select(uint64_t i,
bool b)
const
492 return b ? this->select1(i) : this->select0(i);
495 int64_t select1(uint64_t i)
const
497 return this->search(i + 1);
499 int64_t select0(uint64_t i)
const
501 return stool::LSBByte::select0(this->bits, i);
504 void to_data(std::vector<uint8_t> &output)
const
506 output.push_back(this->bits);
514 static uint64_t get_byte_size(
const std::vector<BitContainer> &items)
516 return sizeof(uint64_t) + (items.size() *
sizeof(BitContainer));
518 static void store_to_bytes(
const std::vector<BitContainer> &items, std::vector<uint8_t> &output, uint64_t &pos)
520 uint64_t size = get_byte_size(items);
521 if (pos + size > output.size())
523 output.resize(pos + size);
526 uint64_t items_size = items.size();
527 std::memcpy(output.data() + pos, &items_size,
sizeof(uint64_t));
528 pos +=
sizeof(uint64_t);
530 std::memcpy(output.data() + pos, items.data(), items_size *
sizeof(BitContainer));
531 pos += size *
sizeof(BitContainer);
533 static void store_to_file(
const std::vector<BitContainer> &items, std::ofstream &os)
535 uint64_t items_size = items.size();
536 os.write(
reinterpret_cast<const char *
>(&items_size),
sizeof(uint64_t));
537 os.write(
reinterpret_cast<const char *
>(items.data()), items.size() *
sizeof(BitContainer));
540 static std::vector<BitContainer> load_vector_from_bytes(
const std::vector<uint8_t> &data, uint64_t &pos)
543 std::memcpy(&size, data.data() + pos,
sizeof(uint64_t));
544 pos +=
sizeof(uint64_t);
546 std::vector<BitContainer> output;
548 std::memcpy(output.data(), data.data() + pos, size *
sizeof(BitContainer));
549 pos += size *
sizeof(BitContainer);
552 static std::vector<BitContainer> load_vector_from_file(std::ifstream &ifs)
555 ifs.read(
reinterpret_cast<char *
>(&size),
sizeof(uint64_t));
557 std::vector<BitContainer> output;
560 ifs.read(
reinterpret_cast<char *
>(output.data()), size *
sizeof(BitContainer));
564 void sort_leaf_containers()