117 uintptr_t word(
size_t i)
const {
return i < size ? size > 1 ? ptr[i] : data : 0; }
120 static constexpr size_t bits_per_unit = CHAR_BIT *
sizeof(uintptr_t);
128 bitref(T s,
int i) : self(s), idx(i) {}
131 bitref(
const bitref &a) =
default;
132 bitref(bitref &&a) =
default;
133 operator bool()
const {
return self.getbit(idx); }
134 bool operator==(
const bitref &a)
const {
return &self == &a.self && idx == a.idx; }
135 bool operator!=(
const bitref &a)
const {
return &self != &a.self || idx != a.idx; }
136 int index()
const {
return idx; }
137 int operator*()
const {
return idx; }
138 bitref &operator++() {
139 while ((
size_t)++idx < self.size * bitvec::bits_per_unit) {
141 self.word(idx / bitvec::bits_per_unit) >> (idx % bitvec::bits_per_unit)) {
142 idx += bv::count_trailing_zeroes(w);
145 idx = (idx / bitvec::bits_per_unit) * bitvec::bits_per_unit +
146 bitvec::bits_per_unit - 1;
151 bitref &operator--() {
152 if (idx < 0) idx = self.size * bitvec::bits_per_unit;
154 if (
auto w = self.word(idx / bitvec::bits_per_unit)
155 << (bitvec::bits_per_unit - 1 - idx % bitvec::bits_per_unit)) {
156 idx -= bv::count_leading_zeroes(w);
159 idx = (idx / bitvec::bits_per_unit) * bitvec::bits_per_unit;
166 class nonconst_bitref :
public bitref<bitvec &> {
168 nonconst_bitref(bitvec &s,
int i) : bitref(s, i) {}
171 nonconst_bitref(
const bitref<bitvec &> &a) : bitref(a) {}
172 nonconst_bitref(
const nonconst_bitref &a) =
default;
173 nonconst_bitref(nonconst_bitref &&a) =
default;
174 bool operator=(
bool b)
const {
176 return b ? self.setbit(idx) : self.clrbit(idx);
178 bool set(
bool b =
true) {
180 bool rv = self.getbit(idx);
181 b ? self.setbit(idx) : self.clrbit(idx);
184 using difference_type = std::ptrdiff_t;
185 using value_type =
const bitvec;
186 using pointer =
const bitvec *;
187 using reference =
const bool &;
188 using iterator_category = std::bidirectional_iterator_tag;
192 class const_bitref :
public bitref<const bitvec &> {
194 const_bitref(
const bitvec &s,
int i) : bitref(s, i) {}
197 const_bitref(
const bitref<const bitvec &> &a) : bitref(a) {}
198 const_bitref(
const const_bitref &a) =
default;
199 const_bitref(const_bitref &&a) =
default;
200 using difference_type = std::ptrdiff_t;
201 using value_type =
const bitvec;
202 using pointer =
const bitvec *;
203 using reference =
const bool &;
204 using iterator_category = std::bidirectional_iterator_tag;
213 bitvec() : size(1), data(0) {}
214 explicit bitvec(uintptr_t v) : size(1), data(v) {}
215 template <typename T, typename = typename std::enable_if<std::is_integral<T>::value &&
216 (
sizeof(T) >
sizeof(uintptr_t))>::type>
217 explicit bitvec(T v) : size(1), data(v) {
219 size =
sizeof(v) /
sizeof(data);
220 ptr =
new IF_HAVE_LIBGC((PointerFreeGC)) uintptr_t[size];
221 for (
unsigned i = 0; i < size; ++i) {
227 bitvec(
size_t lo,
size_t cnt) : size(1), data(0) { setrange(lo, cnt); }
228 bitvec(
const bitvec &a) : size(a.size) {
230 ptr =
new IF_HAVE_LIBGC((PointerFreeGC)) uintptr_t[size];
231 memcpy(ptr, a.ptr, size *
sizeof(*ptr));
236 bitvec(bitvec &&a) : size(a.size), data(a.data) { a.size = 1; }
237 bitvec &operator=(
const bitvec &a) {
238 if (
this == &a)
return *
this;
239 if (size > 1)
delete[] ptr;
240 if ((size = a.size) > 1) {
241 ptr =
new IF_HAVE_LIBGC((PointerFreeGC)) uintptr_t[size];
242 memcpy(ptr, a.ptr, size *
sizeof(*ptr));
248 bitvec &operator=(bitvec &&a) {
249 std::swap(size, a.size);
250 std::swap(data, a.data);
254 if (size > 1)
delete[] ptr;
259 memset(ptr, 0, size *
sizeof(*ptr));
263 bool setbit(
size_t idx) {
264 if (idx >= size * bits_per_unit) expand(1 + idx / bits_per_unit);
266 ptr[idx / bits_per_unit] |= (uintptr_t)1 << (idx % bits_per_unit);
268 data |= (uintptr_t)1 << idx;
271 void setrange(
size_t idx,
size_t sz) {
273 if (idx + sz > size * bits_per_unit) expand(1 + (idx + sz - 1) / bits_per_unit);
275 data |= ~(~(uintptr_t)1 << (sz - 1)) << idx;
276 }
else if (idx / bits_per_unit == (idx + sz - 1) / bits_per_unit) {
277 ptr[idx / bits_per_unit] |= ~(~(uintptr_t)1 << (sz - 1)) << (idx % bits_per_unit);
279 size_t i = idx / bits_per_unit;
280 ptr[i] |= ~(uintptr_t)0 << (idx % bits_per_unit);
282 while (++i < idx / bits_per_unit) {
283 ptr[i] = ~(uintptr_t)0;
285 if (i < size) ptr[i] |= (((uintptr_t)1 << (idx % bits_per_unit)) - 1);
288 void setraw(uintptr_t raw) {
293 for (
size_t i = 1; i < size; i++) ptr[i] = 0;
296 template <typename T, typename = typename std::enable_if<std::is_integral<T>::value &&
297 (
sizeof(T) >
sizeof(uintptr_t))>::type>
299 if (
sizeof(T) /
sizeof(uintptr_t) > size) expand(
sizeof(T) /
sizeof(uintptr_t));
300 for (
size_t i = 0; i < size; i++) {
302 raw >>= bits_per_unit;
305 void setraw(uintptr_t *raw,
size_t sz) {
306 if (sz > size) expand(sz);
310 for (
size_t i = 0; i < sz; i++) ptr[i] = raw[i];
311 for (
size_t i = sz; i < size; i++) ptr[i] = 0;
314 template <typename T, typename = typename std::enable_if<std::is_integral<T>::value &&
315 (
sizeof(T) >
sizeof(uintptr_t))>::type>
316 void setraw(T *raw,
size_t sz) {
317 constexpr size_t m =
sizeof(T) /
sizeof(uintptr_t);
318 if (m * sz > size) expand(m * sz);
320 for (; i < sz * m; ++i) ptr[i] = raw[i / m] >> ((i % m) * bits_per_unit);
321 for (; i < size; ++i) ptr[i] = 0;
323 bool clrbit(
size_t idx) {
324 if (idx >= size * bits_per_unit)
return false;
326 ptr[idx / bits_per_unit] &= ~((uintptr_t)1 << (idx % bits_per_unit));
328 data &= ~((uintptr_t)1 << idx);
331 void clrrange(
size_t idx,
size_t sz) {
333 if (size < sz / bits_per_unit)
334 sz = size * bits_per_unit;
335 if (idx >= size * bits_per_unit)
return;
337 if (idx + sz < bits_per_unit)
338 data &= ~(~(~(uintptr_t)1 << (sz - 1)) << idx);
340 data &= ~(~(uintptr_t)0 << idx);
341 }
else if (idx / bits_per_unit == (idx + sz - 1) / bits_per_unit) {
342 ptr[idx / bits_per_unit] &= ~(~(~(uintptr_t)1 << (sz - 1)) << (idx % bits_per_unit));
344 size_t i = idx / bits_per_unit;
345 ptr[i] &= ~(~(uintptr_t)0 << (idx % bits_per_unit));
347 while (++i < idx / bits_per_unit && i < size) {
350 if (i < size) ptr[i] &= ~(((uintptr_t)1 << (idx % bits_per_unit)) - 1);
353 bool getbit(
size_t idx)
const {
354 return (word(idx / bits_per_unit) >> (idx % bits_per_unit)) & 1;
356 uintmax_t getrange(
size_t idx,
size_t sz)
const {
357 assert(sz > 0 && sz <= CHAR_BIT *
sizeof(uintmax_t));
358 if (idx >= size * bits_per_unit)
return 0;
360 unsigned shift = idx % bits_per_unit;
361 idx /= bits_per_unit;
362 uintmax_t rv = ptr[idx] >> shift;
363 shift = bits_per_unit - shift;
365 if (++idx >= size)
break;
366 rv |= (uintmax_t)ptr[idx] << shift;
367 shift += bits_per_unit;
369 return rv & ~(~(uintmax_t)1 << (sz - 1));
371 return (data >> idx) & ~(~(uintmax_t)1 << (sz - 1));
374 void putrange(
size_t idx,
size_t sz, uintmax_t v) {
375 assert(sz > 0 && sz <= CHAR_BIT *
sizeof(uintmax_t));
376 uintptr_t mask = ~(uintmax_t)0 >> (CHAR_BIT *
sizeof(uintmax_t) - sz);
378 if (idx + sz > size * bits_per_unit) expand(1 + (idx + sz - 1) / bits_per_unit);
380 data &= ~(mask << idx);
383 unsigned shift = idx % bits_per_unit;
384 idx /= bits_per_unit;
385 ptr[idx] &= ~(mask << shift);
386 ptr[idx] |= v << shift;
387 shift = bits_per_unit - shift;
389 assert(idx + 1 < size);
390 ptr[++idx] &= ~(mask >> shift);
391 ptr[idx] |= v >> shift;
392 shift += bits_per_unit;
396 bitvec getslice(
size_t idx,
size_t sz)
const;
398 bool operator[](
int idx)
const {
return getbit(idx); }
399 int ffs(
unsigned start = 0)
const;
400 unsigned ffz(
unsigned start = 0)
const;
415 for (
size_t i = 0; i < size; i++)
416 if (word(i) != 0)
return false;
419 explicit operator bool()
const {
return !empty(); }
420 bool operator&=(
const bitvec &a) {
424 for (
size_t i = 0; i < size && i < a.size; i++) {
425 rv |= ((ptr[i] & a.ptr[i]) != ptr[i]);
429 rv |= ((*ptr & a.data) != *ptr);
434 for (
size_t i = a.size; i < size; i++)
440 memset(ptr + a.size, 0, (size - a.size) *
sizeof(*ptr));
442 }
else if (a.size > 1) {
443 rv |= ((data & a.ptr[0]) != data);
446 rv |= ((data & a.data) != data);
451 bitvec operator&(
const bitvec &a)
const {
452 if (size <= a.size) {
462 bool operator|=(
const bitvec &a) {
464 if (size < a.size) expand(a.size);
467 for (
size_t i = 0; i < a.size; i++) {
468 rv |= ((ptr[i] | a.ptr[i]) != ptr[i]);
472 rv |= ((*ptr | a.data) != *ptr);
476 rv |= ((data | a.data) != data);
481 bool operator|=(uintptr_t a) {
483 auto t = size > 1 ? ptr : &data;
484 rv |= ((*t | a) != *t);
488 template <typename T, typename = typename std::enable_if<std::is_integral<T>::value &&
489 (
sizeof(T) >
sizeof(uintptr_t))>::type>
490 bool operator|=(T a) {
491 return (*
this) |= bitvec(a);
493 bitvec operator|(
const bitvec &a)
const {
498 bitvec operator|(uintptr_t a)
const {
503 template <typename T, typename = typename std::enable_if<std::is_integral<T>::value &&
504 (
sizeof(T) >
sizeof(uintptr_t))>::type>
505 bitvec
operator|(T a) {
510 bitvec &operator^=(
const bitvec &a) {
511 if (size < a.size) expand(a.size);
514 for (
size_t i = 0; i < a.size; i++) ptr[i] ^= a.ptr[i];
523 bitvec operator^(
const bitvec &a)
const {
528 bool operator-=(
const bitvec &a) {
532 for (
size_t i = 0; i < size && i < a.size; i++) {
533 rv |= ((ptr[i] & ~a.ptr[i]) != ptr[i]);
537 rv |= ((*ptr & ~a.data) != *ptr);
540 }
else if (a.size > 1) {
541 rv |= ((data & ~a.ptr[0]) != data);
544 rv |= ((data & ~a.data) != data);
549 bitvec operator-(
const bitvec &a)
const {
554 bool operator==(
const bitvec &a)
const {
555 for (
size_t i = 0; i < size || i < a.size; i++)
556 if (word(i) != a.word(i))
return false;
559 bool operator!=(
const bitvec &a)
const {
return !(*
this == a); }
560 bool operator<(
const bitvec &a)
const {
561 size_t i = std::max(size, a.size);
563 if (word(i) < a.word(i))
return true;
564 if (word(i) > a.word(i))
return false;
568 bool operator>(
const bitvec &a)
const {
return a < *
this; }
569 bool operator>=(
const bitvec &a)
const {
return !(*
this < a); }
570 bool operator<=(
const bitvec &a)
const {
return !(a < *
this); }
571 bool intersects(
const bitvec &a)
const {
572 for (
size_t i = 0; i < size && i < a.size; i++)
573 if (word(i) & a.word(i))
return true;
576 bool contains(
const bitvec &a)
const {
577 for (
size_t i = 0; i < size && i < a.size; i++)
578 if ((word(i) & a.word(i)) != a.word(i))
return false;
579 for (
size_t i = size; i < a.size; i++)
580 if (a.word(i))
return false;
583 bitvec &operator>>=(
size_t count);
584 bitvec &operator<<=(
size_t count);
585 bitvec operator>>(
size_t count)
const {
590 bitvec operator<<(
size_t count)
const {
595 void rotate_right(
size_t start_bit,
size_t rotation_idx,
size_t end_bit);
596 bitvec rotate_right_copy(
size_t start_bit,
size_t rotation_idx,
size_t end_bit)
const;
597 int popcount()
const {
599 for (
size_t i = 0; i < size; i++) rv += bv::popcount(word(i));
602 bool is_contiguous()
const;
605 void expand(
size_t newsize) {
606 assert(newsize > size);
607 if (
size_t m = newsize >> 3) {
614 newsize = (newsize + m) & ~m;
617 uintptr_t *old = ptr;
618 ptr =
new IF_HAVE_LIBGC((PointerFreeGC)) uintptr_t[newsize];
619 memcpy(ptr, old, size *
sizeof(*ptr));
620 memset(ptr + size, 0, (newsize - size) *
sizeof(*ptr));
624 ptr =
new IF_HAVE_LIBGC((PointerFreeGC)) uintptr_t[newsize];
626 memset(ptr + size, 0, (newsize - size) *
sizeof(*ptr));
631 bitvec rotate_right_helper(
size_t start_bit,
size_t rotation_idx,
size_t end_bit)
const;
634 friend std::ostream &operator<<(std::ostream &,
const bitvec &);
635 friend std::istream &operator>>(std::istream &, bitvec &);
636 friend bool operator>>(
const char *, bitvec &);