14 #include <type_traits> 25 #include <glog/logging.h> 28 namespace int_vector {
32 struct IntVectorStdVectorRepr {
33 typedef typename std::vector<T>::value_type value_type;
35 typedef typename std::vector<T>::reference reference;
36 typedef typename std::vector<T>::const_reference const_reference;
38 typedef typename std::vector<T>::pointer pointer;
39 typedef typename std::vector<T>::const_pointer const_pointer;
41 typedef typename std::vector<T>::iterator iterator;
42 typedef typename std::vector<T>::const_iterator const_iterator;
44 typedef typename std::vector<T>::reverse_iterator reverse_iterator;
45 typedef typename std::vector<T>::const_reverse_iterator const_reverse_iterator;
47 typedef typename std::vector<T>::difference_type difference_type;
48 typedef typename std::vector<T>::size_type size_type;
50 typedef std::vector<T> backing_data;
51 typedef T internal_data_type;
53 inline static uint64_t bit_size(
const backing_data&
self) {
54 return sizeof(T) * CHAR_BIT *
self.size();
57 inline static uint64_t bit_capacity(
const backing_data&
self) {
58 return sizeof(T) * CHAR_BIT *
self.capacity();
65 inline static uint8_t width(
const backing_data&
self) {
66 return sizeof(T) * CHAR_BIT;
69 inline static backing_data with_width(size_type n,
const value_type& val, uint8_t width) {
70 return backing_data(n, val, width);
73 inline static void width(backing_data&
self, uint8_t w) {
76 inline static void resize(backing_data&
self, size_type n,
const value_type& val, uint8_t w) {
80 inline static void bit_reserve(backing_data&
self, uint64_t n) {
86 struct IntVectorBitPackingVectorRepr {
87 typedef typename BitPackingVector<T>::value_type value_type;
89 typedef typename BitPackingVector<T>::reference reference;
90 typedef typename BitPackingVector<T>::const_reference const_reference;
92 typedef typename BitPackingVector<T>::pointer pointer;
93 typedef typename BitPackingVector<T>::const_pointer const_pointer;
95 typedef typename BitPackingVector<T>::iterator iterator;
96 typedef typename BitPackingVector<T>::const_iterator const_iterator;
98 typedef typename BitPackingVector<T>::reverse_iterator reverse_iterator;
99 typedef typename BitPackingVector<T>::const_reverse_iterator const_reverse_iterator;
101 typedef typename BitPackingVector<T>::difference_type difference_type;
102 typedef typename BitPackingVector<T>::size_type size_type;
104 typedef BitPackingVector<T> backing_data;
105 typedef typename BitPackingVector<T>::internal_data_type internal_data_type;
107 inline static uint64_t bit_size(
const backing_data&
self) {
108 return self.size() *
self.width();
111 inline static uint64_t bit_capacity(
const backing_data&
self) {
112 return self.capacity() *
self.width();
119 inline static uint8_t width(
const backing_data&
self) {
123 inline static backing_data with_width(size_type n,
const value_type& val, uint8_t width) {
124 return backing_data(n, val, width);
127 inline static void width(backing_data&
self, uint8_t w) {
131 inline static void resize(backing_data&
self, size_type n,
const value_type& val, uint8_t w) {
132 self.resize(n, val, w);
135 inline static void bit_reserve(backing_data&
self, uint64_t n) {
140 template<
class T,
class X =
void>
141 struct IntVectorTrait:
142 public IntVectorStdVectorRepr<T> {};
145 struct IntVectorTrait<
uint_impl_t<N>, typename
std::enable_if_t<(N % 8 != 0) && (N > 1)>>:
146 public IntVectorBitPackingVectorRepr<uint_t<N>> {};
149 struct IntVectorTrait<dynamic_t>:
150 public IntVectorBitPackingVectorRepr<dynamic_t> {};
153 struct IntVectorTrait<bool>:
154 public IntVectorBitPackingVectorRepr<uint_t<1>> {};
179 typedef typename IntVectorTrait<T>::reference
reference;
181 typedef typename IntVectorTrait<T>::pointer
pointer;
183 typedef typename IntVectorTrait<T>::iterator
iterator;
188 typedef typename IntVectorTrait<T>::size_type
size_type;
194 return IntVectorTrait<T>::element_storage_mode();
197 typename IntVectorTrait<T>::backing_data
m_data;
204 inline IntVector(size_type n,
const value_type& val): m_data(n, val) {}
205 inline IntVector(size_type n,
const value_type& val, uint8_t width):
206 m_data(IntVectorTrait<T>::with_width(n, val, width)) {}
209 template <
class InputIterator>
210 inline IntVector(InputIterator first, InputIterator last): m_data(first, last) {}
219 inline IntVector(std::initializer_list<value_type> il): m_data(il) {}
222 m_data = other.m_data;
227 m_data = std::move(other.m_data);
237 return m_data.begin();
245 return m_data.rbegin();
248 inline reverse_iterator
rend() {
249 return m_data.rend();
252 inline const_iterator
begin()
const {
253 return m_data.begin();
256 inline const_iterator
end()
const {
260 inline const_reverse_iterator
rbegin()
const {
261 return m_data.rbegin();
264 inline const_reverse_iterator
rend()
const {
265 return m_data.rend();
269 return m_data.cbegin();
272 inline const_iterator
cend()
const {
273 return m_data.cend();
276 inline const_reverse_iterator
crbegin()
const {
277 return m_data.crbegin();
280 inline const_reverse_iterator
crend()
const {
281 return m_data.crend();
284 inline size_type
size()
const {
285 return m_data.size();
289 return IntVectorTrait<T>::bit_size(m_data);
293 return m_data.max_size();
297 return IntVectorTrait<T>::width(m_data);
301 IntVectorTrait<T>::width(m_data, w);
305 static const bool do_resize_check =
false;
312 void check_for_growth(F f) {
313 auto old_cap = this->capacity();
315 auto new_cap = this->capacity();
317 if (do_resize_check) {
318 DCHECK_EQ(old_cap, new_cap)
319 <<
"\nresize() call grew the capacity!" 320 <<
"\nThis does not cause a single reallocation, but dynamical growth" 321 " with overallocation!" 322 <<
"\nConsider calling reserve() beforehand.";
328 check_for_growth([&]() {
333 inline void resize(size_type n,
const value_type& val) {
334 check_for_growth([&]() {
335 m_data.resize(n, val);
339 inline void resize(size_type n,
const value_type& val, uint8_t w) {
340 check_for_growth([&]() {
341 IntVectorTrait<T>::resize(m_data, n, val, w);
346 return m_data.capacity();
350 return IntVectorTrait<T>::bit_capacity(m_data);
354 return m_data.empty();
362 IntVectorTrait<T>::bit_reserve(m_data, n * w);
366 IntVectorTrait<T>::bit_reserve(m_data, n);
370 m_data.shrink_to_fit();
381 inline reference
at(size_type n) {
385 inline const_reference
at(size_type n)
const {
390 return m_data.front();
393 inline const_reference
front()
const {
394 return m_data.front();
398 return m_data.back();
401 inline const_reference
back()
const {
402 return m_data.back();
405 inline internal_data_type*
data() noexcept {
406 return m_data.data();
409 inline const internal_data_type*
data() const noexcept {
410 return m_data.data();
413 template <
class InputIterator>
414 inline void assign(InputIterator first, InputIterator last) {
415 m_data.assign(first, last);
418 inline void assign(size_type n,
const value_type& val) {
419 m_data.assign(n, val);
422 inline void assign(std::initializer_list<value_type> il) {
427 m_data.push_back(val);
431 m_data.push_back(std::move(val));
438 inline iterator
insert(const_iterator position,
const value_type& val) {
439 return m_data.insert(position, val);
442 inline iterator
insert(const_iterator position, size_type n,
const value_type& val) {
443 return m_data.insert(position, n, val);
446 template <
class InputIterator>
447 inline iterator
insert(const_iterator position, InputIterator first, InputIterator last) {
448 return m_data.insert(position, first, last);
451 inline iterator
insert(const_iterator position, value_type&& val) {
452 return m_data.insert(position, std::move(val));
455 inline iterator
insert(const_iterator position, std::initializer_list<value_type> il) {
456 return m_data.insert(position, il);
459 inline iterator
erase(const_iterator position) {
460 return m_data.erase(position);
463 inline iterator
erase(const_iterator first, const_iterator last) {
464 return m_data.erase(first, last);
468 m_data.swap(other.m_data);
475 template <
class... Args>
476 inline iterator
emplace(const_iterator position, Args&&... args) {
477 return m_data.emplace(position, std::forward<Args...>(args)...);
480 template <
class... Args>
482 m_data.emplace_back(std::forward<Args...>(args)...);
490 friend bool operator<(const IntVector<U>& lhs,
const IntVector<U>& rhs);
492 friend bool operator<=(const IntVector<U>& lhs,
const IntVector<U>& rhs);
503 return lhs.m_data == rhs.m_data;
508 return lhs.m_data != rhs.m_data;
513 return lhs.m_data < rhs.m_data;
518 return lhs.m_data <= rhs.m_data;
523 return lhs.m_data > rhs.m_data;
528 return lhs.m_data >= rhs.m_data;
534 swap(lhs.m_data, rhs.m_data);
void assign(size_type n, const value_type &val)
void assign(std::initializer_list< value_type > il)
void reserve(size_type n, uint8_t w)
reference operator[](size_type n)
Contains the text compression and encoding framework.
const_iterator cbegin() const
const_iterator end() const
bool operator>(const IntVector< T > &lhs, const IntVector< T > &rhs)
iterator erase(const_iterator first, const_iterator last)
IntVector(IntVector &&other)
IntVectorTrait< T >::reverse_iterator reverse_iterator
bool operator==(const IntVector< T > &lhs, const IntVector< T > &rhs)
void resize(size_type n, const value_type &val, uint8_t w)
IntVector(const IntVector &other)
A vector over arbitrary unsigned integer types.
const_iterator cend() const
const_reference back() const
uint64_t bit_capacity() const
reverse_iterator rbegin()
void push_back(const value_type &val)
size_type max_size() const
IntVector & operator=(std::initializer_list< value_type > il)
IntVectorTrait< T >::size_type size_type
IntVector(size_type n, const value_type &val)
IntVectorTrait< T >::const_reverse_iterator const_reverse_iterator
void emplace_back(Args &&... args)
const_reference at(size_type n) const
static constexpr ElementStorageMode element_storage_mode()
IntVectorTrait< T >::difference_type difference_type
const_reference front() const
iterator insert(const_iterator position, std::initializer_list< value_type > il)
void push_back(value_type &&val)
IntVector(std::initializer_list< value_type > il)
IntVector & operator=(IntVector &&other)
iterator emplace(const_iterator position, Args &&... args)
IntVectorTrait< T >::pointer pointer
IntVector & operator=(const IntVector &other)
void swap(IntVector &other)
IntVectorTrait< T >::iterator iterator
void swap(IntVector< T > &lhs, IntVector< T > &rhs)
IntVectorTrait< T >::reference reference
IntVectorTrait< T >::value_type value_type
const_reverse_iterator crbegin() const
const_reverse_iterator rend() const
IntVectorTrait< T >::internal_data_type internal_data_type
The element type of the internal data buffer accessed with data()
internal_data_type * data() noexcept
IntVectorTrait< T >::const_reference const_reference
iterator insert(const_iterator position, const value_type &val)
const_iterator begin() const
bool operator>=(const IntVector< T > &lhs, const IntVector< T > &rhs)
void bit_reserve(uint64_t n)
const_reverse_iterator rbegin() const
size_type capacity() const
iterator insert(const_iterator position, InputIterator first, InputIterator last)
uint64_t bit_size() const
IntVector(InputIterator first, InputIterator last)
void reserve(size_type n)
bool operator!=(const IntVector< T > &lhs, const IntVector< T > &rhs)
IntVectorTrait< T >::const_iterator const_iterator
const_reference operator[](size_type n) const
reference at(size_type n)
const_reverse_iterator crend() const
IntVectorTrait< T >::const_pointer const_pointer
IntVector(size_type n, const value_type &val, uint8_t width)
iterator insert(const_iterator position, size_type n, const value_type &val)
const internal_data_type * data() const noexcept
iterator insert(const_iterator position, value_type &&val)
void resize(size_type n, const value_type &val)
void assign(InputIterator first, InputIterator last)
iterator erase(const_iterator position)