14 #include <type_traits> 24 #include <sdsl/bits.hpp> 25 #include <glog/logging.h> 30 namespace int_vector {
32 struct BitPackingVector: IntRepr<T>::BitPackingVectorRepr {
33 typedef typename IntRepr<T>::value_type value_type;
35 typedef IntRef<T> reference;
36 typedef ConstIntRef<T> const_reference;
38 typedef IntPtr<T> pointer;
39 typedef ConstIntPtr<T> const_pointer;
41 typedef pointer iterator;
42 typedef const_pointer const_iterator;
44 typedef typename std::reverse_iterator<iterator> reverse_iterator;
45 typedef typename std::reverse_iterator<const_iterator> const_reverse_iterator;
47 typedef ptrdiff_t difference_type;
48 typedef size_t size_type;
50 typedef typename IntRepr<T>::BitPackingVectorRepr::internal_data_type internal_data_type;
53 friend bool operator==(
const BitPackingVector<M>& lhs,
const BitPackingVector<M>& rhs);
55 inline static uint64_t backing2bits_w(
size_t n) {
56 return uint64_t(
sizeof(internal_data_type) * CHAR_BIT) * uint64_t(n);
58 inline uint64_t backing2bits(
size_t n)
const {
59 return backing2bits_w(n);
62 inline static uint64_t elem2bits_w(
size_t n, uint8_t w) {
63 return uint64_t(w) * uint64_t(n);
65 inline uint64_t elem2bits(
size_t n)
const {
66 return elem2bits_w(n, this->width());
69 inline static uint64_t bits2backing_w(uint64_t bits) {
73 return ((bits - 1) / backing2bits_w(1)) + 1;
75 inline uint64_t bits2backing(uint64_t bits)
const {
76 return bits2backing_w(bits);
79 inline static uint64_t bits2elem_w(uint64_t bits, uint8_t w) {
83 return ((bits - 1) / elem2bits_w(1, w)) + 1;
85 inline uint64_t bits2elem(uint64_t bits)
const {
86 return bits2elem_w(bits, this->width());
89 struct PosAndOffset {
size_t pos; uint8_t offset; };
90 inline static PosAndOffset bitpos2backingpos_w(uint64_t bits) {
92 bits / backing2bits_w(1),
93 uint8_t(bits % backing2bits_w(1))
96 inline PosAndOffset bitpos2backingpos(uint64_t bits)
const {
97 return bitpos2backingpos_w(bits);
100 inline explicit BitPackingVector(): IntRepr<T>::BitPackingVectorRepr() {}
101 inline explicit BitPackingVector(size_type n): BitPackingVector() {
102 this->m_real_size = n;
103 size_t converted_size = bits2backing(elem2bits(this->m_real_size));
104 this->m_vec = std::vector<internal_data_type>(converted_size);
105 DCHECK_EQ(converted_size, this->m_vec.capacity());
107 inline BitPackingVector(size_type n,
const value_type& val): BitPackingVector(n) {
108 auto ptr = this->m_vec.data();
111 for (
size_t i = 0; i < n; i++) {
112 bits::write_int_and_move(ptr, val, offset, this->width());
116 inline BitPackingVector(size_type n,
const value_type& val, uint8_t width):
119 this->set_width_raw(width);
121 this->resize(n, val);
122 DCHECK_EQ(this->m_vec.size(), bits2backing(elem2bits(n)));
123 DCHECK_EQ(this->m_vec.size(), this->m_vec.capacity());
126 template <
class InputIterator>
127 inline BitPackingVector(InputIterator first, InputIterator last) {
129 for(; first != last; first++) {
133 inline BitPackingVector (
const BitPackingVector& other):
134 IntRepr<T>::BitPackingVectorRepr(other) {}
135 inline BitPackingVector (BitPackingVector&& other):
136 IntRepr<T>::BitPackingVectorRepr(
std::move(other)) {}
137 inline BitPackingVector(std::initializer_list<value_type> il):
138 BitPackingVector(il.begin(), il.end()) {}
140 inline BitPackingVector&
operator=(
const BitPackingVector& other) {
141 this->m_vec = other.m_vec;
142 this->m_real_size = other.m_real_size;
143 this->set_width_raw(other.width());
147 inline BitPackingVector&
operator=(BitPackingVector&& other) {
148 this->m_vec = std::move(other.m_vec);
149 this->m_real_size = other.m_real_size;
150 this->set_width_raw(other.width());
154 inline BitPackingVector&
operator=(std::initializer_list<value_type> il) {
155 *
this = BitPackingVector(il);
159 inline iterator begin() {
160 using Base =
typename int_vector::IntPtrBase<pointer>;
161 auto x = bitpos2backingpos(0);
162 return pointer(Base(&this->m_vec[x.pos], x.offset, this->width()));
165 inline iterator end() {
166 using Base =
typename int_vector::IntPtrBase<pointer>;
167 auto x = bitpos2backingpos(elem2bits(this->m_real_size));
168 return pointer(Base(&this->m_vec[x.pos], x.offset, this->width()));
171 inline reverse_iterator rbegin() {
172 return std::reverse_iterator<iterator>(end());
175 inline reverse_iterator rend() {
176 return std::reverse_iterator<iterator>(begin());
179 inline const_iterator begin()
const {
180 using Base =
typename int_vector::IntPtrBase<const_pointer>;
181 auto x = bitpos2backingpos(0);
182 return const_pointer(Base(&this->m_vec[x.pos], x.offset, this->width()));
185 inline const_iterator end()
const {
186 using Base =
typename int_vector::IntPtrBase<const_pointer>;
187 auto x = bitpos2backingpos(elem2bits(this->m_real_size));
188 return const_pointer(Base(&this->m_vec[x.pos], x.offset, this->width()));
191 inline const_reverse_iterator rbegin()
const {
192 return std::reverse_iterator<const_iterator>(end());
195 inline const_reverse_iterator rend()
const {
196 return std::reverse_iterator<const_iterator>(begin());
199 inline const_iterator cbegin()
const {
203 inline const_iterator cend()
const {
207 inline const_reverse_iterator crbegin()
const {
211 inline const_reverse_iterator crend()
const {
215 inline size_type size()
const {
216 return this->m_real_size;
219 inline uint64_t bit_size()
const {
220 return elem2bits(this->m_real_size);
223 inline size_type max_size()
const {
225 return std::vector<value_type>().max_size();
228 inline void resize(size_type n) {
229 this->m_real_size = n;
230 this->m_vec.resize(bits2backing(elem2bits(n)), 0);
233 inline void resize(size_type n,
const value_type& val) {
234 auto old_size = size();
237 for (
auto a = begin() + old_size, b = end(); a != b; ++a) {
243 inline size_type capacity()
const {
244 return bits2elem(backing2bits(this->m_vec.capacity()));
247 inline bool empty()
const {
251 inline void reserve(size_type n) {
252 this->m_vec.reserve(bits2backing(elem2bits(n)));
255 inline void shrink_to_fit() {
256 this->m_vec.shrink_to_fit();
259 inline reference operator[](size_type n) {
260 using Base =
typename int_vector::IntPtrBase<pointer>;
261 DCHECK_LT(n, size());
262 auto x = bitpos2backingpos(elem2bits(n));
263 return reference(pointer(Base(this->m_vec.data() + x.pos, x.offset, this->width())));
266 inline const_reference operator[](size_type n)
const {
267 using Base =
typename int_vector::IntPtrBase<const_pointer>;
269 auto x = bitpos2backingpos(elem2bits(n));
270 return const_reference(const_pointer(Base(this->m_vec.data() + x.pos, x.offset, this->width())));
273 inline void range_check(size_type n)
const {
275 std::stringstream ss;
276 ss <<
"Out-of-range access of IntVector: index is ";
278 ss <<
", size() is ";
280 throw std::out_of_range(ss.str());
284 inline reference at(size_type n) {
286 return operator[](n);
289 inline const_reference at(size_type n)
const {
291 return operator[](n);
294 inline reference front() {
295 return operator[](0);
298 inline const_reference front()
const {
299 return operator[](0);
302 inline reference back() {
303 return operator[](size() - 1);
306 inline const_reference back()
const {
307 return operator[](size() - 1);
310 inline internal_data_type* data() noexcept {
311 return this->m_vec.data();
314 inline const internal_data_type* data() const noexcept {
315 return this->m_vec.data();
318 template <
class InputIterator>
319 inline void assign(InputIterator first, InputIterator last) {
320 *
this = BitPackingVector(first, last);
323 inline void assign(size_type n,
const value_type& val) {
324 *
this = BitPackingVector(n, val);
327 inline void assign(std::initializer_list<value_type> il) {
328 *
this = BitPackingVector(il);
331 inline void push_back(
const value_type& val) {
332 this->m_real_size += 1;
334 while (elem2bits(this->m_real_size) > backing2bits(this->m_vec.size())) {
335 this->m_vec.push_back(0);
341 inline void push_back(value_type&& val) {
346 inline void pop_back() {
348 this->m_real_size -= 1;
349 while (bits2backing(elem2bits(this->m_real_size)) < this->m_vec.size()) {
350 this->m_vec.pop_back();
354 inline iterator insert(const_iterator position,
const value_type& val) {
355 return insert(position, size_type(1), val);
358 inline iterator insert(const_iterator position, size_type n,
const value_type& val) {
360 auto p = (position - cbegin());
364 auto new_bits_needed = elem2bits(n);
365 auto existing_extra_bits = backing2bits(this->m_vec.size()) - elem2bits(this->m_real_size);
367 if (new_bits_needed > existing_extra_bits) {
368 new_bits_needed -= existing_extra_bits;
373 auto new_backing_needed = bits2backing(new_bits_needed);
374 this->m_vec.insert(this->m_vec.cend(), new_backing_needed, 0);
375 this->m_real_size += n;
380 auto start = begin() + p;
381 auto old_end = end() - n;
382 auto new_end = end();
386 while(start != old_end) {
395 for(
auto a = begin() + p, b = begin() + p + n; a != b; ++a) {
403 template <
class InputIterator>
404 inline iterator insert(const_iterator position, InputIterator first, InputIterator last) {
408 const auto p = (position - cbegin());
411 for(; first != last; ++first) {
412 insert(cbegin() + pi, value_type(*first));
419 inline iterator insert(const_iterator position, value_type&& val) {
421 return insert(position, v);
424 inline iterator insert(const_iterator position, std::initializer_list<value_type> il) {
425 return insert(position, il.begin(), il.end());
428 inline iterator erase(const_iterator position) {
429 return erase(position, position + 1);
432 inline iterator erase(const_iterator first, const_iterator last) {
433 auto from = (first - cbegin());
434 auto to = (last - cbegin());
436 std::copy(begin() + to, end(), begin() + from);
438 this->m_real_size -= n;
440 auto obsolete_backing = this->m_vec.size() - bits2backing(elem2bits(this->m_real_size));
441 this->m_vec.erase(this->m_vec.cend() - obsolete_backing, this->m_vec.cend());
442 return begin() + from;
445 inline void swap(BitPackingVector& other) {
446 this->m_vec.swap(other.m_vec);
447 std::swap(this->m_real_size, other.m_real_size);
448 auto a = this->width();
449 auto b = other.width();
450 this->set_width_raw(b);
451 other.set_width_raw(a);
454 inline void clear() {
456 this->m_real_size = 0;
459 template <
class... Args>
460 inline iterator emplace(const_iterator position, Args&&... args) {
461 return insert(position, value_type(std::forward<Args...>(args)...));
464 template <
class... Args>
465 inline void emplace_back(Args&&... args) {
466 push_back(value_type(std::forward<Args...>(args)...));
469 inline uint8_t width()
const {
470 return this->raw_width();
473 inline void width(uint8_t w) {
474 this->bit_reserve(this->size() * w);
475 this->resize(this->size(), 0, w);
478 inline void resize(size_type n,
const value_type& val, uint8_t w) {
479 auto old_width = this->width();
481 auto old_size = this->size();
484 auto new_bit_size = elem2bits_w(new_size, new_width);
485 auto common_size = std::min(old_size, new_size);
487 if (old_width < new_width) {
492 auto old_p = bitpos2backingpos_w(elem2bits_w(common_size, old_width));
493 auto new_p = bitpos2backingpos_w(elem2bits_w(common_size, new_width));
496 this->m_vec.resize(bits2backing_w(new_bit_size));
497 this->set_width_raw(w);
498 this->m_real_size = new_size;
500 uint64_t* old_ptr = this->m_vec.data() + old_p.pos;
501 uint64_t* new_ptr = this->m_vec.data() + new_p.pos;
504 for (uint64_t i = 0; i < common_size; i++) {
505 sdsl::bits::move_left((
const uint64_t*&) old_ptr, old_p.offset, old_width);
506 auto v = sdsl::bits::read_int( old_ptr, old_p.offset, old_width);
508 sdsl::bits::move_left((
const uint64_t*&) new_ptr, new_p.offset, new_width);
509 sdsl::bits::write_int( new_ptr, v, new_p.offset, new_width);
511 }
else if (old_width > new_width) {
514 uint64_t* old_ptr = this->m_vec.data();
515 uint64_t* new_ptr = this->m_vec.data();
517 uint8_t old_offset = 0;
518 uint8_t new_offset = 0;
521 for (uint64_t i = 0; i < common_size; i++) {
522 auto v = sdsl::bits::read_int_and_move((
const uint64_t*&) old_ptr, old_offset, old_width);
523 sdsl::bits::write_int_and_move(new_ptr, v, new_offset, new_width);
527 this->m_vec.resize(bits2backing_w(new_bit_size));
528 this->set_width_raw(w);
529 this->m_real_size = new_size;
533 if (old_size < new_size) {
534 auto a = this->begin() + old_size;
535 auto b = this->end();
542 inline void bit_reserve(uint64_t n) {
543 this->m_vec.reserve(bits2backing(n));
546 inline void reserve(uint64_t n, uint8_t w) {
547 this->bit_reserve(n * w);
552 bool operator==(
const BitPackingVector<N>& lhs,
const BitPackingVector<N>& rhs) {
553 DCHECK(lhs.width() == rhs.width());
554 if (lhs.size() == rhs.size()) {
555 auto extra_bits = lhs.backing2bits(lhs.m_vec.size())
556 - lhs.elem2bits(lhs.m_real_size);
558 if (extra_bits == 0) {
559 return lhs.m_vec == rhs.m_vec;
561 if (!std::equal(lhs.m_vec.cbegin(), lhs.m_vec.cend() - 1, rhs.m_vec.cbegin())) {
564 auto occupied_bits = lhs.backing2bits(1) - extra_bits;
567 auto elements = (occupied_bits - 1) / lhs.elem2bits(1) + 1;
569 return std::equal(lhs.cend() - elements, lhs.cend(), rhs.cend() - elements);
576 bool operator!=(
const BitPackingVector<N>& lhs,
const BitPackingVector<N>& rhs) {
577 return !(lhs == rhs);
581 bool operator<(const BitPackingVector<N>& lhs,
const BitPackingVector<N>& rhs) {
582 return std::lexicographical_compare(lhs.cbegin(), lhs.cend(), rhs.cbegin(), rhs.cend());
586 bool operator<=(const BitPackingVector<N>& lhs,
const BitPackingVector<N>& rhs) {
591 bool operator>(
const BitPackingVector<N>& lhs,
const BitPackingVector<N>& rhs) {
592 return std::lexicographical_compare(rhs.cbegin(), rhs.cend(), lhs.cbegin(), lhs.cend());
596 bool operator>=(
const BitPackingVector<N>& lhs,
const BitPackingVector<N>& rhs) {
601 void swap(BitPackingVector<N>& x, BitPackingVector<N>& y) {
607 using BitPackingVector = int_vector::BitPackingVector<T>;
Contains the text compression and encoding framework.
uint_impl_t & operator=(const uint_impl_t &b)
bool operator>(const IntVector< T > &lhs, const IntVector< T > &rhs)
bool operator==(const IntVector< T > &lhs, const IntVector< T > &rhs)
void swap(IntVector< T > &lhs, IntVector< T > &rhs)
bool operator>=(const IntVector< T > &lhs, const IntVector< T > &rhs)
bool operator!=(const IntVector< T > &lhs, const IntVector< T > &rhs)