10#ifndef ROUTING_KIT_NO_ALIGNED_ALLOC
15#define aligned_alloc(alignment, size) _aligned_malloc(size, alignment)
16#define aligned_free(ptr) _aligned_free(ptr)
18#define aligned_free(ptr) free(ptr)
26#ifdef ROUTING_KIT_NO_ALIGNED_ALLOC
27void*aligned_alloc(uint8_t alignment, uint64_t size){
28 uint64_t potentially_unaligned_buffer = (uint64_t)malloc(size+alignment);
29 uint64_t aligned_buffer = ((potentially_unaligned_buffer + alignment)/alignment) * alignment;
30 uint8_t*buffer = (uint8_t*)aligned_buffer;
31 *(buffer-1) = aligned_buffer - potentially_unaligned_buffer;
37 uint8_t*buffer = (uint8_t*)ptr;
38 uint8_t shift = *(buffer-1);
47 #ifndef ROUTING_KIT_NO_GCC_EXTENSIONS
48 typedef uint64_t v8_uint64_t __attribute__((vector_size(64)));
53 v8_uint64_t(
unsigned x){
54 for(
unsigned i=0; i<8; ++i)
59 void operator^=(v8_uint64_t o){
60 for(
unsigned i=0; i<8; ++i)
64 void operator&=(v8_uint64_t o){
65 for(
unsigned i=0; i<8; ++i)
69 void operator|=(v8_uint64_t o){
70 for(
unsigned i=0; i<8; ++i)
74 v8_uint64_t operator~()
const{
76 for(
unsigned i=0; i<8; ++i)
81 uint64_t&operator[](uint64_t i){
return v[i];};
82 const uint64_t&operator[](uint64_t i)
const{
return v[i];};
86 v8_uint64_t
operator^(v8_uint64_t l, v8_uint64_t r){
91 v8_uint64_t
operator&(v8_uint64_t l, v8_uint64_t r){
96 v8_uint64_t
operator|(v8_uint64_t l, v8_uint64_t r){
103 uint64_t get_v8_uint64_count(uint64_t bit_count){
104 return (bit_count+511)/512;
107 uint64_t get_uint64_count(uint64_t bit_count){
108 return get_v8_uint64_count(bit_count)*8;
111 uint64_t get_uint8_count(uint64_t bit_count){
112 return get_v8_uint64_count(bit_count)*64;
115 v8_uint64_t get_padding_mask(uint64_t size){
118 uint64_t x = size % 512;
130 bool is_any_bit_set(
const v8_uint64_t*x){
146 bool are_all_bits_set(
const v8_uint64_t*x){
159 return u[0] == ~0ull;
163 bool are_all_padding_bits_zero(
const BitVector&v){
164 if(v.size() % 512 == 0){
167 auto x = get_padding_mask(v.size());
168 x = ((
const v8_uint64_t*)v.data())[v.size()/512] & ~x;
169 return !is_any_bit_set(&x);
176 data_(nullptr), size_(0){}
180 if(__builtin_expect(
size != 0,
true)){
181 data_ = (uint64_t*)(aligned_alloc(64, get_uint8_count(
size)));
183 throw std::bad_alloc();
191 assert(are_all_padding_bits_zero(*
this));
196 if(__builtin_expect(
size != 0,
true)){
197 data_ = (uint64_t*)(aligned_alloc(64, get_uint8_count(
size)));
199 throw std::bad_alloc();
202 v8_uint64_t init_vec = {0};
203 assert(init_vec[0] == 0ull);
205 init_vec = ~init_vec;
206 assert(!init_value || init_vec[0] == ~0ull);
207 assert(init_value || init_vec[0] == 0ull);
210 v8_uint64_t*i = (v8_uint64_t*)
data_;
211 i<((v8_uint64_t*)
data_)+get_v8_uint64_count(
size);
223 assert(are_all_padding_bits_zero(*
this));
231 data_(static_cast<uint64_t*>(aligned_alloc(64, get_uint8_count(o.size_)))), size_(o.size_){
233 throw std::bad_alloc();
235 assert(are_all_padding_bits_zero(o));
238 v8_uint64_t*i = (v8_uint64_t*)
data_, *j=(v8_uint64_t*)o.
data_;
239 i<((v8_uint64_t*)
data_)+get_v8_uint64_count(
size_);
244 assert(are_all_padding_bits_zero(*
this));
248 data_(o.data_), size_(o.size_){
250 assert(are_all_padding_bits_zero(o));
257 assert(are_all_padding_bits_zero(o));
264 assert(are_all_padding_bits_zero(o));
265 assert(are_all_padding_bits_zero(*
this));
267 uint64_t*x = o.
data_;
271 uint64_t y = o.
size_;
277 if(
size_ % 512 != 0){
278 v8_uint64_t* v = (v8_uint64_t*)
data_ +
size_/512;
279 *v &= get_padding_mask(
size_);
282 assert(are_all_padding_bits_zero(*
this));
286 if(
data_ ==
nullptr){
290 assert(are_all_padding_bits_zero(*
this));
291 if(get_uint8_count(new_size) == get_uint8_count(
size_)){
298 v8_uint64_t*i = (v8_uint64_t*)
data_, *j=(v8_uint64_t*)o.
data_;
299 i<((v8_uint64_t*)
data_)+std::min(get_v8_uint64_count(
size_), get_v8_uint64_count(new_size));
305 assert(are_all_padding_bits_zero(o));
308 assert(are_all_padding_bits_zero(*
this));
313 if(
data_ ==
nullptr){
316 assert(are_all_padding_bits_zero(*
this));
317 if(new_size <
size_) {
319 }
else if(get_uint8_count(new_size) == get_uint8_count(
size_)){
323 ((v8_uint64_t*)
data_)[
size_/512] |= get_padding_mask(new_size) & ~get_padding_mask(
size_);
330 *i = (v8_uint64_t*)
data_,
331 *j = (v8_uint64_t*)o.
data_;
333 while(i < (v8_uint64_t*)
data_ + get_v8_uint64_count(
size_)){
340 *(j-1) |= ~get_padding_mask(
size_);
342 v8_uint64_t all_one = {0};
345 while(j < (v8_uint64_t*)o.
data_ + get_v8_uint64_count(o.
size_)){
350 *(j-1) &= get_padding_mask(o.
size_);
351 assert(are_all_padding_bits_zero(o));
353 v8_uint64_t all_zero = {0};
355 while(j < (v8_uint64_t*)o.
data_ + get_v8_uint64_count(o.
size_)){
359 assert(are_all_padding_bits_zero(o));
362 assert(are_all_padding_bits_zero(*
this));
365 assert(are_all_padding_bits_zero(*
this));
370 assert(are_all_padding_bits_zero(*
this));
378 assert(are_all_padding_bits_zero(*
this));
383 assert(are_all_padding_bits_zero(*
this));
392 assert(are_all_padding_bits_zero(*
this));
398 assert(are_all_padding_bits_zero(*
this));
401 n += __builtin_popcountll(*i);
408 for(v8_uint64_t*i = (v8_uint64_t*)
data_; i<((v8_uint64_t*)
data_)+get_v8_uint64_count(
size_); ++i)
415 for(v8_uint64_t*i = (v8_uint64_t*)
data_; i<((v8_uint64_t*)
data_)+get_v8_uint64_count(
size_); ++i)
417 assert(are_all_padding_bits_zero(*
this));
425 for(v8_uint64_t*i = (v8_uint64_t*)
data_; i<((v8_uint64_t*)
data_)+get_v8_uint64_count(
size_); ++i)
430 assert(are_all_padding_bits_zero(*
this));
434 assert(are_all_padding_bits_zero(*
this));
435 if(__builtin_expect(
size_ == 0,
false))
441 uint64_t n = get_v8_uint64_count(
size_);
445 for(i = (v8_uint64_t*)
data_; i<((v8_uint64_t*)
data_)+n; ++i)
447 x &= *i | ~get_padding_mask(
size_);
448 return are_all_bits_set(&x);
452 assert(are_all_padding_bits_zero(*
this));
453 if(__builtin_expect(
size_ == 0,
false))
458 for(v8_uint64_t*i = (v8_uint64_t*)
data_; i<((v8_uint64_t*)
data_)+get_v8_uint64_count(
size_); ++i)
461 return is_any_bit_set(&x);
465 assert(are_all_padding_bits_zero(*
this));
466 assert(are_all_padding_bits_zero(o));
467 assert(
size_ == o.
size_ &&
"can only combine bit vectors of same size");
468 for(v8_uint64_t*i = (v8_uint64_t*)
data_, *j=(v8_uint64_t*)o.
data_; i<((v8_uint64_t*)
data_)+get_v8_uint64_count(
size_); ++i, ++j)
470 assert(are_all_padding_bits_zero(*
this));
475 assert(are_all_padding_bits_zero(*
this));
476 assert(are_all_padding_bits_zero(o));
477 assert(
size_ == o.
size_ &&
"can only combine bit vectors of same size");
478 for(v8_uint64_t*i = (v8_uint64_t*)
data_, *j=(v8_uint64_t*)o.
data_; i<((v8_uint64_t*)
data_)+get_v8_uint64_count(
size_); ++i, ++j)
480 assert(are_all_padding_bits_zero(*
this));
485 assert(are_all_padding_bits_zero(*
this));
486 assert(are_all_padding_bits_zero(o));
487 assert(
size_ == o.
size_ &&
"can only combine bit vectors of same size");
488 for(v8_uint64_t*i = (v8_uint64_t*)
data_, *j=(v8_uint64_t*)o.
data_; i<((v8_uint64_t*)
data_)+get_v8_uint64_count(
size_); ++i, ++j)
490 assert(are_all_padding_bits_zero(*
this));
495 assert(are_all_padding_bits_zero(*
this));
496 for(v8_uint64_t*i = (v8_uint64_t*)
data_; i<((v8_uint64_t*)
data_)+get_v8_uint64_count(
size_); ++i)
499 assert(are_all_padding_bits_zero(*
this));
503 assert(are_all_padding_bits_zero(l));
504 assert(are_all_padding_bits_zero(r));
505 if(__builtin_expect(l.
size_ != r.
size_,
false))
510 for(v8_uint64_t*i = (v8_uint64_t*)l.
data_, *j=(v8_uint64_t*)r.
data_; i<((v8_uint64_t*)l.
data_)+get_v8_uint64_count(l.
size_); ++i, ++j){
514 return !is_any_bit_set(&x);
518 assert(are_all_padding_bits_zero(l));
519 assert(are_all_padding_bits_zero(r));
520 if(__builtin_expect(l.
size_ != r.
size_,
false))
#define aligned_free(ptr)
static constexpr Uninitialized uninitialized
BitVector & operator&=(const BitVector &)
BitVector & operator=(BitVector)
BitVector & operator|=(const BitVector &)
void resize(uint64_t size, Uninitialized)
BitVector & operator^=(const BitVector &)
void reset_all_padding_bits()
uint64_t population_count() const
void make_large_enough_for(uint64_t x, Uninitialized)
BitVector operator^(BitVector &&l, BitVector &&r)
bool operator==(const BitVector &l, const BitVector &r)
BitVector operator|(BitVector &&l, BitVector &&r)
bool operator<(const BitVector &l, const BitVector &r)
BitVector operator&(BitVector &&l, BitVector &&r)