23 using iterator_category = std::random_access_iterator_tag;
25 using difference_type = std::ptrdiff_t;
30 bool operator*()
const
32 return stool::LSBByte::get_bit(this->bits, index);
36 return stool::LSBByte::get_code_length(this->bits) - 1;
46 if ((
uint64_t)(this->index + 1) < size)
50 else if ((
uint64_t)(this->index + 1) == size)
56 throw std::invalid_argument(
"Error: BitDequeIterator::operator++()");
78 throw std::invalid_argument(
"Error: BitDequeIterator::operator--()");
93 if ((
uint64_t)(this->index +
n) < this->get_size())
105 if ((
uint64_t)(this->index +
n) < this->get_size())
118 if (this->index -
n >= 0)
124 throw std::invalid_argument(
"Error: BitContainerIterator::operator-()");
132 throw std::invalid_argument(
"Error: BitDequeIterator::operator-()");
138 uint64_t read_64bit_MSB_string()
const
141 if (this->index == size)
143 throw std::invalid_argument(
"Error: BitContainerIterator::read_64_bit_string()");
157 if(stool::LSBByte::get_bit(this->bits,
y)){
206 BitContainer(std::vector<uint64_t> &_items)
208 for (uint64_t x : _items)
213 BitContainer(std::vector<bool> &_items)
215 for (uint64_t i = 0; i < _items.size(); i++)
217 this->push_back(_items[i]);
221 void swap(BitContainer &item)
223 std::swap(this->bits, item.bits);
225 uint64_t size()
const
227 return stool::LSBByte::get_code_length(this->bits) - 1;
229 uint64_t size_in_bytes(
bool only_extra_bytes)
const
231 if (only_extra_bytes)
237 return sizeof(uint64_t);
240 uint64_t unused_size_in_bytes()
const
245 uint64_t at(uint64_t pos)
const
247 return stool::LSBByte::get_bit(this->bits, pos);
251 throw std::runtime_error(
"Error: BitContainer");
258 static std::string name()
262 uint64_t psum(uint64_t i)
const noexcept
264 uint64_t x = (this->bits << (63 - i));
265 return __builtin_popcountll(x);
267 uint64_t psum() const noexcept
269 return __builtin_popcountll(this->bits) - 1;
271 int64_t search(uint64_t x)
const noexcept
279 uint64_t count = this->psum();
282 return stool::LSBByte::select1(this->bits, x - 1);
291 std::string to_string()
const
294 for (uint64_t i = 0; i < this->size(); i++)
296 if (this->at(i) >= 1)
308 std::vector<uint64_t> to_value_vector()
const
310 std::vector<uint64_t> r;
311 for (uint64_t i = 0; i < this->size(); i++)
313 r.push_back(this->at(i));
317 uint64_t to_uint64()
const
319 return stool::LSBByte::write_bit(this->bits, this->size(),
false);
322 template <
typename VEC>
323 void to_values(VEC &output_vec)
const
326 output_vec.resize(this->size());
327 for (uint64_t i = 0; i < this->size(); i++)
329 output_vec[i] = this->at(i);
333 void insert(uint64_t pos, uint64_t value)
335 assert(this->size() + 1 < 64);
336 this->bits = stool::LSBByte::insert_bit(this->bits, pos, value >= 1);
338 void remove(uint64_t pos)
340 assert(this->size() > 0);
341 this->bits = stool::LSBByte::remove_bit(this->bits, pos);
343 void push_front(std::vector<uint64_t> &new_items)
345 assert(this->size() + new_items.
size() < 64);
347 for (int64_t i = new_items.size() - 1; i >= 0; i--)
349 this->push_front(new_items[i]);
352 void push_front(uint64_t new_item)
354 assert(this->size() + 1 < 64);
355 this->bits = (this->bits << 1) | (new_item >= 1 ? 1 : 0);
358 void push_back(std::vector<uint64_t> &new_items)
360 assert(this->size() + 1 < 64);
361 assert(this->size() + new_items.
size() < 64);
363 for (uint64_t v : new_items)
371 void push_back(uint64_t value)
373 assert(this->size() + 1 < 64);
374 this->bits = stool::LSBByte::insert_bit(this->bits, this->size(), value >= 1);
378 assert(this->size() > 0);
379 this->bits = this->bits >> 1;
381 std::vector<uint64_t> pop_front(uint64_t len)
383 assert(len <= this->size());
384 std::vector<uint64_t> r;
385 for (uint64_t i = 0; i < len; i++)
387 r.push_back(this->at(0));
394 assert(this->size() > 0);
395 this->remove(this->size() - 1);
398 std::vector<uint64_t> pop_back(uint64_t len)
400 assert(len <= this->size());
401 std::vector<uint64_t> r;
404 for (uint64_t i = 0; i < len; i++)
406 r[len - i - 1] = this->at(this->size() - 1);
412 uint64_t reverse_psum(uint64_t i)
const
414 if (i == this->size() - 1)
420 uint64_t len1 = i + 1;
421 uint64_t idx = this->size() - len1;
422 return this->psum() - this->psum(idx - 1);
426 uint64_t psum(uint64_t i, uint64_t j)
const
434 throw std::runtime_error(
"No implementation");
438 void increment(uint64_t i, int64_t delta)
442 this->bits = stool::LSBByte::write_bit(this->bits, i,
true);
444 else if (delta <= -1)
446 this->bits = stool::LSBByte::write_bit(this->bits, i,
false);
450 BitContainerIterator begin()
const
452 if (this->size() == 0)
454 return BitContainerIterator(this->bits, UINT16_MAX);
458 return BitContainerIterator(this->bits, 0);
462 BitContainerIterator end()
const
464 return BitContainerIterator(this->bits, UINT16_MAX);
467 int64_t rank1(uint64_t i)
const
475 return this->psum(i - 1);
479 int64_t rank0(uint64_t i)
const
481 return i - this->rank1(i);
483 int64_t rank(uint64_t i,
bool b)
const
485 return b ? this->rank1(i) : this->rank0(i);
488 int64_t select(uint64_t i,
bool b)
const
490 return b ? this->select1(i) : this->select0(i);
493 int64_t select1(uint64_t i)
const
495 return this->search(i + 1);
497 int64_t select0(uint64_t i)
const
499 return stool::LSBByte::select0(this->bits, i);
502 void to_data(std::vector<uint8_t> &output)
const
504 output.push_back(this->bits);
512 static uint64_t get_byte_size(
const std::vector<BitContainer> &items)
514 return sizeof(uint64_t) + (items.size() *
sizeof(BitContainer));
516 static void save(
const std::vector<BitContainer> &items, std::vector<uint8_t> &output, uint64_t &pos)
518 uint64_t size = get_byte_size(items);
519 if (pos + size > output.size())
521 output.resize(pos + size);
524 uint64_t items_size = items.size();
525 std::memcpy(output.data() + pos, &items_size,
sizeof(uint64_t));
526 pos +=
sizeof(uint64_t);
528 std::memcpy(output.data() + pos, items.data(), items_size *
sizeof(BitContainer));
529 pos += size *
sizeof(BitContainer);
531 static void save(
const std::vector<BitContainer> &items, std::ofstream &os)
533 uint64_t items_size = items.size();
534 os.write(
reinterpret_cast<const char *
>(&items_size),
sizeof(uint64_t));
535 os.write(
reinterpret_cast<const char *
>(items.data()), items.size() *
sizeof(BitContainer));
538 static std::vector<BitContainer> load_vector(
const std::vector<uint8_t> &data, uint64_t &pos)
541 std::memcpy(&size, data.data() + pos,
sizeof(uint64_t));
542 pos +=
sizeof(uint64_t);
544 std::vector<BitContainer> output;
546 std::memcpy(output.data(), data.data() + pos, size *
sizeof(BitContainer));
547 pos += size *
sizeof(BitContainer);
550 static std::vector<BitContainer> load_vector(std::ifstream &ifs)
553 ifs.read(
reinterpret_cast<char *
>(&size),
sizeof(uint64_t));
555 std::vector<BitContainer> output;
558 ifs.read(
reinterpret_cast<char *
>(output.data()), size *
sizeof(BitContainer));
562 void sort_leaf_containers()