23 static constexpr
size_t data_w = 8 *
sizeof(data_t);
25 static_assert(data_w <= 64,
26 "bit vectors backing must have width of at most 64 bits");
29 static constexpr uint8_t basic_rank(data_t v);
30 static constexpr uint8_t basic_rank(data_t v, uint8_t l, uint8_t m);
31 static constexpr uint8_t basic_select(data_t, uint8_t k);
32 static constexpr uint8_t basic_select(data_t, uint8_t l, uint8_t k);
38 size_t m_supblock_size;
56 m_block_size(other.m_block_size),
57 m_supblock_size(other.m_supblock_size),
58 m_blocks(other.m_blocks),
59 m_supblocks(other.m_supblocks) {
66 m_block_size(other.m_block_size),
67 m_supblock_size(other.m_supblock_size),
68 m_blocks(
std::move(other.m_blocks)),
69 m_supblocks(
std::move(other.m_supblocks)) {
76 m_block_size = other.m_block_size;
77 m_supblock_size = other.m_supblock_size;
78 m_blocks = other.m_blocks;
79 m_supblocks = other.m_supblocks;
87 m_block_size = other.m_block_size;
88 m_supblock_size = other.m_supblock_size;
89 m_blocks = std::move(other.m_blocks);
90 m_supblocks = std::move(other.m_supblocks);
102 const size_t n = bv.
size();
107 m_supblock_size = log_n * log_n;
108 m_block_size = log_n;
118 size_t cur_sb_offset = 0;
119 size_t longest_sb = 0;
123 auto data = bv.
data();
124 for(
size_t i = 0; i <
idiv_ceil(n, data_w); i++) {
125 const auto v = data[i];
126 const uint8_t r = basic_rank(v);
129 if(r_b + r >= m_block_size) {
133 size_t distance_b = m_block_size - r_b;
140 size_t distance_sum = 0;
141 while(r_b >= m_block_size) {
143 offs = basic_select(v, offs, distance_b);
146 const size_t pos = i * data_w + offs;
148 distance_sum += distance_b;
150 if(r_sb >= m_supblock_size) {
152 longest_sb = std::max(longest_sb, pos - cur_sb_offset);
155 m_supblocks[cur_sb++] =
pos;
157 r_sb -= m_supblock_size;
160 m_blocks[cur_b++] = pos - cur_sb_offset;
162 distance_b = m_block_size;
167 DCHECK_GE(
size_t(r), distance_sum);
168 r_sb += r - distance_sum;
175 longest_sb = std::max(longest_sb, n - cur_sb_offset);
176 const size_t w_block =
bits_for(longest_sb);
179 m_blocks.
width(w_block);
182 m_supblocks.
resize(cur_sb);
192 DCHECK_GT(x, 0) <<
"order must be at least one";
193 if(x > m_max)
return m_bv->
size();
199 const size_t i = x / m_supblock_size;
200 const size_t j = x / m_block_size;
203 pos += m_supblocks[i-1];
204 x -= i * m_supblock_size;
206 if(x == 0)
return pos;
209 size_t k = j - i * (m_supblock_size / m_block_size);
211 pos += m_blocks[j-1];
212 x -= k * m_block_size;
214 if(x == 0)
return pos;
216 if(i > 0 || k > 0) ++
pos;
220 auto data = m_bv->
data();
222 size_t i = pos / data_w;
223 size_t offs = pos % data_w;
225 uint8_t s = basic_select(data[i], offs, x);
228 return pos + s - offs;
233 x -= basic_rank(data[i], offs, data_w-1);
236 pos = (++i) * data_w;
237 s = basic_select(data[i], x);
255 inline constexpr uint8_t Select1::basic_rank(data_t v) {
260 inline constexpr uint8_t Select1::basic_rank(data_t v, uint8_t l, uint8_t m) {
265 inline constexpr uint8_t Select1::basic_select(data_t v, uint8_t k) {
270 inline constexpr uint8_t Select1::basic_select(data_t v, uint8_t l, uint8_t k) {
279 inline constexpr uint8_t Select0::basic_rank(data_t v) {
284 inline constexpr uint8_t Select0::basic_rank(data_t v, uint8_t l, uint8_t m) {
289 inline constexpr uint8_t Select0::basic_select(data_t v, uint8_t k) {
294 inline constexpr uint8_t Select0::basic_select(data_t v, uint8_t l, uint8_t k) {
Contains the text compression and encoding framework.
constexpr uint_fast8_t bits_for(size_t n)
Computes the number of bits required to store the given integer value.
constexpr size_t idiv_ceil(size_t a, size_t b)
Performs an integer division with the result rounded up to the next integer.
A vector over arbitrary unsigned integer types.
Select & operator=(const Select &other)
Copy assignment.
Select(BitVector &bv)
Constructs the select data structure for the given bit vector.
constexpr uint8_t select1(uint_t v, uint8_t k)
Finds the position of the k-th 1-bit in the binary representation of the given value.
constexpr uint8_t rank0(uint_t v)
constexpr uint8_t SELECT_FAIL
Returned by select0 and select1 in case the searched bit does not exist in the given input value...
Implements a select data structure for a BitVector.
constexpr uint8_t select0(uint_t v, uint8_t k)
Finds the position of the k-th 0-bit in the binary representation of the given value.
constexpr uint8_t rank1(uint8_t v)
Computes the amount of 1-bits in the binary representation of the given 8-bit value.
Select(Select &&other)
Move constructor.
size_t select(size_t x) const
Finds the position of the x-th flagged bit in the bit vector.
Select()
Default constructor.
IntVectorTrait< T >::internal_data_type internal_data_type
The element type of the internal data buffer accessed with data()
internal_data_type * data() noexcept
size_t operator()(size_t k) const
Select & operator=(Select &&other)
Move assignment.
Select(const Select &other)
Copy constructor.
IntVector< dynamic_t > DynamicIntVector
Represents an integer vector with unspecified (dynamic) bit width.