126 uintptr_t word(
size_t i)
const {
return i < size ? size > 1 ? ptr[i] : data : 0; }
129 static constexpr size_t bits_per_unit = CHAR_BIT *
sizeof(uintptr_t);
137 bitref(T s,
int i) : self(s), idx(i) {}
140 bitref(
const bitref &a) =
default;
141 bitref(bitref &&a) =
default;
142 operator bool()
const {
return self.getbit(idx); }
143 bool operator==(
const bitref &a)
const {
return &self == &a.self && idx == a.idx; }
144 bool operator!=(
const bitref &a)
const {
return &self != &a.self || idx != a.idx; }
145 int index()
const {
return idx; }
146 int operator*()
const {
return idx; }
147 bitref &operator++() {
148 while ((
size_t)++idx < self.size * bitvec::bits_per_unit) {
150 self.word(idx / bitvec::bits_per_unit) >> (idx % bitvec::bits_per_unit)) {
151 idx += bv::count_trailing_zeroes(w);
154 idx = (idx / bitvec::bits_per_unit) * bitvec::bits_per_unit +
155 bitvec::bits_per_unit - 1;
160 bitref &operator--() {
161 if (idx < 0) idx = self.size * bitvec::bits_per_unit;
163 if (
auto w = self.word(idx / bitvec::bits_per_unit)
164 << (bitvec::bits_per_unit - 1 - idx % bitvec::bits_per_unit)) {
165 idx -= bv::count_leading_zeroes(w);
168 idx = (idx / bitvec::bits_per_unit) * bitvec::bits_per_unit;
183 bool operator=(
bool b)
const {
185 return b ? self.setbit(idx) : self.clrbit(idx);
187 bool set(
bool b =
true) {
189 bool rv = self.getbit(idx);
190 b ? self.setbit(idx) : self.clrbit(idx);
193 using difference_type = std::ptrdiff_t;
196 using reference =
const bool &;
197 using iterator_category = std::bidirectional_iterator_tag;
206 const_bitref(
const bitref<const bitvec &> &a) : bitref(a) {}
209 using difference_type = std::ptrdiff_t;
212 using reference =
const bool &;
213 using iterator_category = std::bidirectional_iterator_tag;
222 bitvec() : size(1), data(0) {}
223 explicit bitvec(uintptr_t v) : size(1), data(v) {}
224 template <typename T, typename = typename std::enable_if<std::is_integral<T>::value &&
225 (
sizeof(T) >
sizeof(uintptr_t))>::type>
226 explicit bitvec(T v) : size(1), data(v) {
228 size =
sizeof(v) /
sizeof(data);
229 ptr =
new IF_HAVE_LIBGC((PointerFreeGC)) uintptr_t[size];
230 for (
unsigned i = 0; i < size; ++i) {
236 bitvec(
size_t lo,
size_t cnt) : size(1), data(0) { setrange(lo, cnt); }
237 bitvec(
const bitvec &a) : size(a.size) {
239 ptr =
new IF_HAVE_LIBGC((PointerFreeGC)) uintptr_t[size];
240 memcpy(ptr, a.ptr, size *
sizeof(*ptr));
245 bitvec(bitvec &&a) : size(a.size), data(a.data) { a.size = 1; }
246 bitvec &operator=(
const bitvec &a) {
247 if (
this == &a)
return *
this;
248 if (size > 1)
delete[] ptr;
249 if ((size = a.size) > 1) {
250 ptr =
new IF_HAVE_LIBGC((PointerFreeGC)) uintptr_t[size];
251 memcpy(ptr, a.ptr, size *
sizeof(*ptr));
257 bitvec &operator=(bitvec &&a) {
258 std::swap(size, a.size);
259 std::swap(data, a.data);
263 if (size > 1)
delete[] ptr;
268 memset(ptr, 0, size *
sizeof(*ptr));
272 bool setbit(
size_t idx) {
273 if (idx >= size * bits_per_unit) expand(1 + idx / bits_per_unit);
275 ptr[idx / bits_per_unit] |= (uintptr_t)1 << (idx % bits_per_unit);
277 data |= (uintptr_t)1 << idx;
280 void setrange(
size_t idx,
size_t sz) {
282 if (idx + sz > size * bits_per_unit) expand(1 + (idx + sz - 1) / bits_per_unit);
284 data |= ~(~(uintptr_t)1 << (sz - 1)) << idx;
285 }
else if (idx / bits_per_unit == (idx + sz - 1) / bits_per_unit) {
286 ptr[idx / bits_per_unit] |= ~(~(uintptr_t)1 << (sz - 1)) << (idx % bits_per_unit);
288 size_t i = idx / bits_per_unit;
289 ptr[i] |= ~(uintptr_t)0 << (idx % bits_per_unit);
291 while (++i < idx / bits_per_unit) {
292 ptr[i] = ~(uintptr_t)0;
294 if (i < size) ptr[i] |= (((uintptr_t)1 << (idx % bits_per_unit)) - 1);
297 void setraw(uintptr_t raw) {
302 for (
size_t i = 1; i < size; i++) ptr[i] = 0;
305 template <typename T, typename = typename std::enable_if<std::is_integral<T>::value &&
306 (
sizeof(T) >
sizeof(uintptr_t))>::type>
308 if (
sizeof(T) /
sizeof(uintptr_t) > size) expand(
sizeof(T) /
sizeof(uintptr_t));
309 for (
size_t i = 0; i < size; i++) {
311 raw >>= bits_per_unit;
314 void setraw(uintptr_t *raw,
size_t sz) {
315 if (sz > size) expand(sz);
319 for (
size_t i = 0; i < sz; i++) ptr[i] = raw[i];
320 for (
size_t i = sz; i < size; i++) ptr[i] = 0;
323 template <typename T, typename = typename std::enable_if<std::is_integral<T>::value &&
324 (
sizeof(T) >
sizeof(uintptr_t))>::type>
325 void setraw(T *raw,
size_t sz) {
326 constexpr size_t m =
sizeof(T) /
sizeof(uintptr_t);
327 if (m * sz > size) expand(m * sz);
329 for (; i < sz * m; ++i) ptr[i] = raw[i / m] >> ((i % m) * bits_per_unit);
330 for (; i < size; ++i) ptr[i] = 0;
332 bool clrbit(
size_t idx) {
333 if (idx >= size * bits_per_unit)
return false;
335 ptr[idx / bits_per_unit] &= ~((uintptr_t)1 << (idx % bits_per_unit));
337 data &= ~((uintptr_t)1 << idx);
340 void clrrange(
size_t idx,
size_t sz) {
342 if (size < sz / bits_per_unit)
343 sz = size * bits_per_unit;
344 if (idx >= size * bits_per_unit)
return;
346 if (idx + sz < bits_per_unit)
347 data &= ~(~(~(uintptr_t)1 << (sz - 1)) << idx);
349 data &= ~(~(uintptr_t)0 << idx);
350 }
else if (idx / bits_per_unit == (idx + sz - 1) / bits_per_unit) {
351 ptr[idx / bits_per_unit] &= ~(~(~(uintptr_t)1 << (sz - 1)) << (idx % bits_per_unit));
353 size_t i = idx / bits_per_unit;
354 ptr[i] &= ~(~(uintptr_t)0 << (idx % bits_per_unit));
356 while (++i < idx / bits_per_unit && i < size) {
359 if (i < size) ptr[i] &= ~(((uintptr_t)1 << (idx % bits_per_unit)) - 1);
362 bool getbit(
size_t idx)
const {
363 return (word(idx / bits_per_unit) >> (idx % bits_per_unit)) & 1;
365 uintmax_t getrange(
size_t idx,
size_t sz)
const {
366 assert(sz > 0 && sz <= CHAR_BIT *
sizeof(uintmax_t));
367 if (idx >= size * bits_per_unit)
return 0;
369 unsigned shift = idx % bits_per_unit;
370 idx /= bits_per_unit;
371 uintmax_t rv = ptr[idx] >> shift;
372 shift = bits_per_unit - shift;
374 if (++idx >= size)
break;
375 rv |= (uintmax_t)ptr[idx] << shift;
376 shift += bits_per_unit;
378 return rv & ~(~(uintmax_t)1 << (sz - 1));
380 return (data >> idx) & ~(~(uintmax_t)1 << (sz - 1));
383 void putrange(
size_t idx,
size_t sz, uintmax_t v) {
384 assert(sz > 0 && sz <= CHAR_BIT *
sizeof(uintmax_t));
385 uintptr_t mask = ~(uintmax_t)0 >> (CHAR_BIT *
sizeof(uintmax_t) - sz);
387 if (idx + sz > size * bits_per_unit) expand(1 + (idx + sz - 1) / bits_per_unit);
389 data &= ~(mask << idx);
392 unsigned shift = idx % bits_per_unit;
393 idx /= bits_per_unit;
394 ptr[idx] &= ~(mask << shift);
395 ptr[idx] |= v << shift;
396 shift = bits_per_unit - shift;
398 assert(idx + 1 < size);
399 ptr[++idx] &= ~(mask >> shift);
400 ptr[idx] |= v >> shift;
401 shift += bits_per_unit;
405 bitvec getslice(
size_t idx,
size_t sz)
const;
406 nonconst_bitref operator[](
int idx) {
return nonconst_bitref(*
this, idx); }
407 bool operator[](
int idx)
const {
return getbit(idx); }
408 int ffs(
unsigned start = 0)
const;
409 unsigned ffz(
unsigned start = 0)
const;
410 const_bitref min() const & {
return const_bitref(*
this, ffs()); }
411 const_bitref max() const & {
return --const_bitref(*
this, size * bits_per_unit); }
412 const_bitref begin() const & {
return min(); }
413 const_bitref end() const & {
return const_bitref(*
this, -1); }
415 copy_bitref min() &&;
416 copy_bitref max() &&;
417 copy_bitref begin() &&;
418 copy_bitref end() &&;
419 nonconst_bitref min() & {
return nonconst_bitref(*
this, ffs()); }
420 nonconst_bitref max() & {
return --nonconst_bitref(*
this, size * bits_per_unit); }
421 nonconst_bitref begin() & {
return min(); }
422 nonconst_bitref end() & {
return nonconst_bitref(*
this, -1); }
424 for (
size_t i = 0; i < size; i++)
425 if (word(i) != 0)
return false;
428 explicit operator bool()
const {
return !empty(); }
429 bool operator&=(
const bitvec &a) {
433 for (
size_t i = 0; i < size && i < a.size; i++) {
434 rv |= ((ptr[i] & a.ptr[i]) != ptr[i]);
438 rv |= ((*ptr & a.data) != *ptr);
443 for (
size_t i = a.size; i < size; i++)
449 memset(ptr + a.size, 0, (size - a.size) *
sizeof(*ptr));
451 }
else if (a.size > 1) {
452 rv |= ((data & a.ptr[0]) != data);
455 rv |= ((data & a.data) != data);
460 bitvec operator&(
const bitvec &a)
const {
461 if (size <= a.size) {
471 bool operator|=(
const bitvec &a) {
473 if (size < a.size) expand(a.size);
476 for (
size_t i = 0; i < a.size; i++) {
477 rv |= ((ptr[i] | a.ptr[i]) != ptr[i]);
481 rv |= ((*ptr | a.data) != *ptr);
485 rv |= ((data | a.data) != data);
490 bool operator|=(uintptr_t a) {
492 auto t = size > 1 ? ptr : &data;
493 rv |= ((*t | a) != *t);
497 template <typename T, typename = typename std::enable_if<std::is_integral<T>::value &&
498 (
sizeof(T) >
sizeof(uintptr_t))>::type>
499 bool operator|=(T a) {
500 return (*
this) |= bitvec(a);
502 bitvec operator|(
const bitvec &a)
const {
507 bitvec operator|(uintptr_t a)
const {
512 template <typename T, typename = typename std::enable_if<std::is_integral<T>::value &&
513 (
sizeof(T) >
sizeof(uintptr_t))>::type>
514 bitvec
operator|(T a) {
519 bitvec &operator^=(
const bitvec &a) {
520 if (size < a.size) expand(a.size);
523 for (
size_t i = 0; i < a.size; i++) ptr[i] ^= a.ptr[i];
532 bitvec operator^(
const bitvec &a)
const {
537 bool operator-=(
const bitvec &a) {
541 for (
size_t i = 0; i < size && i < a.size; i++) {
542 rv |= ((ptr[i] & ~a.ptr[i]) != ptr[i]);
546 rv |= ((*ptr & ~a.data) != *ptr);
549 }
else if (a.size > 1) {
550 rv |= ((data & ~a.ptr[0]) != data);
553 rv |= ((data & ~a.data) != data);
558 bitvec operator-(
const bitvec &a)
const {
563 bool operator==(
const bitvec &a)
const {
564 for (
size_t i = 0; i < size || i < a.size; i++)
565 if (word(i) != a.word(i))
return false;
568 bool operator!=(
const bitvec &a)
const {
return !(*
this == a); }
569 bool operator<(
const bitvec &a)
const {
570 size_t i = std::max(size, a.size);
572 if (word(i) < a.word(i))
return true;
573 if (word(i) > a.word(i))
return false;
577 bool operator>(
const bitvec &a)
const {
return a < *
this; }
578 bool operator>=(
const bitvec &a)
const {
return !(*
this < a); }
579 bool operator<=(
const bitvec &a)
const {
return !(a < *
this); }
580 bool intersects(
const bitvec &a)
const {
581 for (
size_t i = 0; i < size && i < a.size; i++)
582 if (word(i) & a.word(i))
return true;
585 bool contains(
const bitvec &a)
const {
586 for (
size_t i = 0; i < size && i < a.size; i++)
587 if ((word(i) & a.word(i)) != a.word(i))
return false;
588 for (
size_t i = size; i < a.size; i++)
589 if (a.word(i))
return false;
592 bitvec &operator>>=(
size_t count);
593 bitvec &operator<<=(
size_t count);
594 bitvec operator>>(
size_t count)
const {
599 bitvec operator<<(
size_t count)
const {
604 void rotate_right(
size_t start_bit,
size_t rotation_idx,
size_t end_bit);
605 bitvec rotate_right_copy(
size_t start_bit,
size_t rotation_idx,
size_t end_bit)
const;
606 int popcount()
const {
608 for (
size_t i = 0; i < size; i++) rv += bv::popcount(word(i));
611 bool is_contiguous()
const;
614 void expand(
size_t newsize) {
615 assert(newsize > size);
616 if (
size_t m = newsize >> 3) {
623 newsize = (newsize + m) & ~m;
626 uintptr_t *old = ptr;
627 ptr =
new IF_HAVE_LIBGC((PointerFreeGC)) uintptr_t[newsize];
628 memcpy(ptr, old, size *
sizeof(*ptr));
629 memset(ptr + size, 0, (newsize - size) *
sizeof(*ptr));
633 ptr =
new IF_HAVE_LIBGC((PointerFreeGC)) uintptr_t[newsize];
635 memset(ptr + size, 0, (newsize - size) *
sizeof(*ptr));
640 bitvec rotate_right_helper(
size_t start_bit,
size_t rotation_idx,
size_t end_bit)
const;
643 friend std::ostream &operator<<(std::ostream &,
const bitvec &);
644 friend std::istream &operator>>(std::istream &, bitvec &);
645 friend bool operator>>(
const char *, bitvec &);