GF2++
Loading...
Searching...
No Matches
BitVector.h
Go to the documentation of this file.
1#pragma once
2// SPDX-FileCopyrightText: 2025 Nessan Fitzmaurice <nzznfitz+gh@icloud.com>
3// SPDX-License-Identifier: MIT
4
8
9#include <gf2/BitStore.h>
10#include <gf2/Iterators.h>
11#include <gf2/BitRef.h>
12#include <gf2/BitSpan.h>
13
14#include <charconv>
15
16namespace gf2 {
17
22template<Unsigned Word = usize>
23class BitVector {
24private:
25 // The number of bit elements in the bit-vector.
26 usize m_size;
27
28 // The bit elements are packed compactly into this standard vector of unsigned words
29 std::vector<Word> m_store;
30
31public:
33 using word_type = Word;
34
36 static constexpr u8 bits_per_word = BITS<Word>;
37
40
50 constexpr usize size() const { return m_size; }
51
63 constexpr usize words() const { return m_store.size(); }
64
80 constexpr Word word(usize i) const {
81 gf2_debug_assert(i < words(), "Index {} is too large for a bit-vector with {} words.", i, words());
82 return m_store[i];
83 }
84
100 constexpr void set_word(usize i, Word word) {
101 gf2_debug_assert(i < words(), "Index {} is too large for a bit-vector with {} words.", i, words());
102
103 // Set the value and if it's the last word, make sure it is kept clean
104 m_store[i] = word;
105 if (i == words() - 1) clean();
106 }
107
116 constexpr const Word* store() const { return m_store.data(); }
117
128 constexpr Word* store() { return m_store.data(); }
129
133 constexpr u8 offset() const { return 0; }
134
138
150 explicit constexpr BitVector(usize size = 0) : m_size(size), m_store(gf2::words_needed<Word>(size)) {
151 // Empty body -- we now have an underlying vector of words all initialized to 0.
152 // Note: We avoided using uniform initialization on the `std::vector` data member.
153 }
154
166 explicit constexpr BitVector(usize size, Word word) : m_size(size), m_store(gf2::words_needed<Word>(size), word) {
167 // Make sure any excess bits are set to 0.
168 clean();
169 }
170
174
184 auto result = BitVector<Word>{};
185 result.m_store.reserve(gf2::words_needed<Word>(capacity));
186 return result;
187 }
188
196 static constexpr BitVector zeros(usize n) { return BitVector{n}; }
197
204 static constexpr BitVector ones(usize n) { return BitVector{n, MAX<Word>}; }
205
215 static constexpr BitVector constant(usize n, bool value) { return BitVector{n, value ? MAX<Word> : Word{0}}; }
216
226 static constexpr BitVector unit(usize n, usize i) {
227 gf2_assert(i < n, "Unit axis i = {} should be less than the bit-vector size n = {}", i, n);
228 BitVector result{n};
229 result.set(i);
230 return result;
231 }
232
239 static constexpr BitVector alternating(usize n) { return BitVector{n, gf2::ALTERNATING<Word>}; }
240
258 template<Unsigned Src>
259 static constexpr BitVector from(Src src) {
261 result.copy(src);
262 return result;
263 }
264
278 template<typename Iter>
279 requires std::is_unsigned_v<typename std::iterator_traits<Iter>::value_type>
280 static constexpr BitVector from(Iter src_begin, Iter src_end) {
281 // How many bits are we copying?
282 using src_type = typename std::iterator_traits<Iter>::value_type;
283 auto src_words = static_cast<std::size_t>(std::distance(src_begin, src_end));
284 auto src_bits = src_words * BITS<src_type>;
285 BitVector result{src_bits};
286 result.copy(src_begin, src_end);
287 return result;
288 }
289
309 template<BitStore Src>
310 static constexpr BitVector from(Src const& src) {
311 BitVector result{src.size()};
312 result.copy(src);
313 return result;
314 }
315
327 template<usize N>
328 static constexpr BitVector from(std::bitset<N> const& src) {
329 BitVector result{N};
330 result.copy(src);
331 return result;
332 }
333
345 static constexpr BitVector from(usize size, std::invocable<usize> auto f) {
346 BitVector result{size};
347 result.copy(f);
348 return result;
349 }
350
354
373 static BitVector random(usize size, double p = 0.5, u64 seed = 0) {
374 BitVector result{size};
375 result.fill_random(p, seed);
376 return result;
377 }
378
396 static BitVector seeded_random(usize size, u64 seed) { return random(size, 0.5, seed); }
397
410 static BitVector biased_random(usize size, double p) { return random(size, p, 0); }
411
415
436 static std::optional<BitVector> from_string(std::string_view sv) {
437 // Edge case ...
438 if (sv.empty()) return BitVector<Word>{};
439
440 // Remove any whitespace, commas, single quotes, or underscores characters.
441 std::string s{sv};
442 std::erase_if(s, [](char c) { return c == ' ' || c == ',' || c == '\'' || c == '_'; });
443 bool no_punctuation = true;
444
445 // Check for a binary prefix.
446 if (s.starts_with("0b")) return from_binary_string(s, no_punctuation);
447
448 // Check for a hex prefix.
449 if (s.starts_with("0x") || s.starts_with("0X")) return from_hex_string(s, no_punctuation);
450
451 // No prefix, but perhaps the string only contains '0' and '1' characters.
452 if (std::ranges::all_of(s, [](char c) { return c == '0' || c == '1'; })) {
453 return BitVector::from_binary_string(s, no_punctuation);
454 }
455
456 // Last gasp -- try hex ...
457 return BitVector::from_hex_string(s, no_punctuation);
458 }
459
473 static std::optional<BitVector> from_binary_string(std::string_view sv, bool no_punctuation = false) {
474 // Edge case ...
475 if (sv.empty()) return BitVector<Word>{};
476
477 // Convert to a string & remove the "0b" prefix if it exists.
478 std::string s{sv};
479 if (s.starts_with("0b")) s = s.substr(2);
480
481 // If necessary, also remove any whitespace, commas, single quotes, or underscores.
482 if (!no_punctuation) std::erase_if(s, [](char c) { return c == ' ' || c == ',' || c == '\'' || c == '_'; });
483
484 // The string should now be a sequence of 0's and 1's.
485 if (std::ranges::any_of(s, [](char c) { return c != '0' && c != '1'; })) return std::nullopt;
486
487 // Construct the bit-vector.
488 auto result = BitVector::zeros(s.size());
489 for (auto i = 0uz; i < s.size(); ++i)
490 if (s[i] == '1') result.set(i);
491 return result;
492 }
493
514 static std::optional<BitVector> from_hex_string(std::string_view sv, bool no_punctuation = false) {
515 // Edge case ...
516 if (sv.empty()) return BitVector<Word>{};
517
518 // Convert to a string and remove the optional "0x" prefix if it exists.
519 std::string s{sv};
520 if (s.starts_with("0x") || s.starts_with("0X")) s = s.substr(2);
521
522 // By default, the base of the last digit is 16 just like all the others.
523 // However, there may be a suffix of the form ".base" where `base` is one of 2, 4 or 8.
524 int last_digit_base = 16;
525 if (s.ends_with(".2"))
526 last_digit_base = 2;
527 else if (s.ends_with(".4"))
528 last_digit_base = 4;
529 else if (s.ends_with(".8"))
530 last_digit_base = 8;
531
532 // Remove the suffix if it exists.
533 if (last_digit_base != 16) s = s.substr(0, s.size() - 2);
534
535 // If necessary, also remove any whitespace, commas, single quotes, or underscores.
536 if (!no_punctuation) std::erase_if(s, [](char c) { return c == ' ' || c == ',' || c == '_'; });
537
538 // The string should now be a sequence of 0-9, A-F, a-f.
539 if (std::ranges::any_of(s, [](char c) { return !std::isxdigit(c); })) return std::nullopt;
540
541 // Construct the bit-vector where we allow all the characters to be hex digits.
542 auto result = BitVector::with_capacity(s.size() * 4);
543
544 // Push all but the last character -- those are hex digits for sure.
545 for (auto i = 0uz; i < s.size() - 1; ++i) result.append_hex_digit(s[i]);
546
547 // Push the last character -- it may be a hex digit or a base indicator.
548 result.append_digit(s[s.size() - 1], last_digit_base);
549
550 return result;
551 }
552
556
569 constexpr usize capacity() const { return bits_per_word * m_store.capacity(); }
570
578 constexpr usize remaining_capacity() const { return capacity() - size(); }
579
593 m_store.shrink_to_fit();
594 return *this;
595 }
596
600 constexpr BitVector& clear() {
601 m_store.clear();
602 m_size = 0;
603 return *this;
604 }
605
619 constexpr BitVector& resize(usize n) {
620 if (n != size()) {
621 m_store.resize(gf2::words_needed<Word>(n), 0);
622 auto old_size = size();
623 m_size = n;
624
625 // If we truncated, we need to clean up the last occupied word if necessary.
626 if (n < old_size) clean();
627 }
628 return *this;
629 }
630
634 constexpr void clean() {
635 // NOTE: This works fine even if `size() == 0`.
636 auto shift = m_size % bits_per_word;
637 if (shift != 0) m_store[words() - 1] &= Word(~(MAX<Word> << shift));
638 }
639
643
656 constexpr BitVector& push(bool b) {
657 resize(size() + 1);
658 if (b) this->set(size() - 1, true);
659 return *this;
660 }
661
679 constexpr std::optional<bool> pop() {
680 if (m_size == 0) return std::nullopt;
681 bool b = this->back();
682 resize(m_size - 1);
683 return b;
684 }
685
689
704 template<Unsigned Src>
705 constexpr auto append(Src src) {
706 auto old_size = size();
707 resize(old_size + BITS<Src>);
708 this->span(old_size, size()).copy(src);
709 return *this;
710 }
711
727 template<typename Iter>
728 requires std::is_unsigned_v<typename std::iterator_traits<Iter>::value_type>
729 constexpr auto append(Iter src_begin, Iter src_end) {
730 // How many bits are we appending?
731 using src_type = typename std::iterator_traits<Iter>::value_type;
732 auto src_words = static_cast<std::size_t>(std::distance(src_begin, src_end));
733 auto src_bits = src_words * BITS<src_type>;
734
735 // Resize & copy.
736 auto old_size = size();
737 resize(old_size + src_bits);
738 this->span(old_size, size()).copy(src_begin, src_end);
739 return *this;
740 }
741
742
757 template<BitStore Src>
758 constexpr BitVector& append(Src const& src) {
759 auto old_size = size();
760 resize(old_size + src.size());
761 this->span(old_size, size()).copy(src);
762 return *this;
763 }
764
774 template<usize N>
775 auto append(std::bitset<N> const& src) {
776 auto old_size = size();
777 resize(old_size + src.size());
778 this->span(old_size, size()).copy(src);
779 return *this;
780 }
781
802 constexpr BitVector& append_digit(char c, int base) {
803 // The known bases are 2, 4, 8, and 16.
804 static constexpr std::array<int, 4> known_bases = {2, 4, 8, 16};
805 if (std::ranges::contains(known_bases, base)) {
806 // Try to convert the character to an integer.
807 usize x;
808 if (std::from_chars(&c, &c + 1, x, base).ec == std::errc{}) {
809 // Success! Push the digits onto the bit-vector.
810 auto digits = static_cast<usize>(std::log2(base));
811 auto old_len = size();
812 resize(old_len + digits);
813 for (auto i = 0uz; i < digits; ++i) this->set(old_len + i, (x >> (digits - i - 1)) & 1);
814 }
815 }
816 return *this;
817 }
818
836 constexpr BitVector& append_hex_digit(char c) {
837 // Try to convert the hex digit to an integer.
838 int x;
839 if (std::from_chars(&c, &c + 1, x, 16).ec == std::errc{}) {
840 // Success! Push the digits onto the bit-vector.
841 auto old_len = size();
842 resize(old_len + 4);
843 for (auto i = 0uz; i < 4; ++i) this->set(old_len + i, (x >> (3 - i)) & 1);
844 }
845 return *this;
846 }
847
851
868 BitVector result;
869 split_off(at, result);
870 return result;
871 }
872
889 constexpr void split_off(usize at, BitVector<Word>& dst) {
890 gf2_assert(at <= m_size, "split point {} is beyond the end of the bit-vector", at);
891 dst.clear();
892 dst.append(this->span(at, m_size));
893 resize(at);
894 }
895
919 template<Unsigned Dst = Word>
920 constexpr std::optional<Dst> split_off_unsigned() {
921 // Edge case ...
922 if (size() == 0) return std::nullopt;
923
924 // Perhaps we can safely cast an `Word` into a `Dst` without any loss of information.
925 constexpr usize bits_per_dst = BITS<Dst>;
926 if constexpr (bits_per_dst <= bits_per_word) {
927 // Easy cases when we can safely cast an `Word` into a `Dst` without any loss of information.
928 // 1. Just one word in the store & we know that all unused bits in that word are zeros.
929 // 2. More than one word in the store but the last word is fully occupied.
930 auto n_words = words();
931 auto shift = size() % bits_per_word;
932 if (n_words == 1 || shift == 0) {
933 auto result = static_cast<Dst>(m_store[n_words - 1]);
934 resize(size() - bits_per_dst);
935 return result;
936 }
937
938 // The last word is not fully occupied so we need to combine it with the next to last word to form a
939 // value that can be cast to a `Dst`.
940 auto lo = m_store[n_words - 2] >> shift;
941 auto hi = m_store[n_words - 1] << (bits_per_word - shift);
942 auto result = static_cast<Dst>(lo | hi);
943 resize(size() - bits_per_dst);
944 return result;
945 } else {
946 // `Dst` is larger than `Word` -- it should be an integer multiple of `bits_per_word` is size.
947 static_assert(bits_per_dst % bits_per_word == 0, "sizeof(Dst) % sizeof(Word) != 0");
948
949 // Pop an appropriate number of `Word` sized chunks off the end of the bit-vector.
950 auto words_per_dst = bits_per_dst / bits_per_word;
951 std::vector<Word> chunks(words_per_dst);
952 for (auto i = 0uz; i < words_per_dst; ++i) chunks[i] = *split_off_unsigned<Word>();
953
954 // Combine the chunks into a `Dst` value.
955 Dst result = 0;
956 for (auto i = words_per_dst; i-- > 0;) result |= static_cast<Dst>(chunks[i] << (i * bits_per_word));
957
958 return result;
959 }
960 }
961
965
978 constexpr bool get(usize i) const { return gf2::get(*this, i); }
979
993 constexpr bool operator[](usize i) const { return gf2::get(*this, i); }
994
1007 constexpr bool front() const { return gf2::front(*this); }
1008
1021 constexpr bool back() const { return gf2::back(*this); }
1022
1026
1040 constexpr auto set(usize i, bool value = true) {
1041 gf2::set(*this, i, value);
1042 return *this;
1043 }
1044
1066 constexpr auto operator[](usize i) { return gf2::ref(*this, i); }
1067
1083 constexpr auto flip(usize i) {
1084 gf2::flip(*this, i);
1085 return *this;
1086 }
1087
1107 constexpr auto swap(usize i0, usize i1) {
1108 gf2::swap(*this, i0, i1);
1109 return *this;
1110 }
1111
1115
1125 constexpr bool is_empty() const { return gf2::is_empty(*this); }
1126
1138 constexpr bool any() const { return gf2::any(*this); }
1139
1153 constexpr bool all() const { return gf2::all(*this); }
1154
1166 constexpr bool none() const { return gf2::none(*this); }
1167
1171
1182 constexpr auto set_all(bool value = true) {
1183 gf2::set_all(*this, value);
1184 return *this;
1185 }
1186
1195 constexpr auto flip_all() {
1196 gf2::flip_all(*this);
1197 return *this;
1198 }
1199
1203
1225 template<Unsigned Src>
1226 constexpr auto copy(Src src) {
1227 gf2::copy(src, *this);
1228 return *this;
1229 }
1230
1249 template<typename Iter>
1250 requires std::is_unsigned_v<typename std::iterator_traits<Iter>::value_type>
1251 constexpr void copy(Iter src_begin, Iter src_end) {
1252 gf2::copy(src_begin, src_end, *this);
1253 }
1254
1274 template<BitStore Src>
1275 constexpr auto copy(Src const& src) {
1276 gf2::copy(src, *this);
1277 return *this;
1278 }
1279
1296 template<usize N>
1297 constexpr auto copy(std::bitset<N> const& src) {
1298 gf2::copy(src, *this);
1299 return *this;
1300 }
1301
1305
1315 constexpr auto copy(std::invocable<usize> auto f) {
1316 gf2::copy(*this, f);
1317 return *this;
1318 }
1319
1337 constexpr auto fill_random(double p = 0.5, u64 seed = 0) {
1338 gf2::fill_random(*this, p, seed);
1339 return *this;
1340 }
1341
1345
1355 constexpr usize count_ones() const { return gf2::count_ones(*this); }
1356
1366 constexpr usize count_zeros() const { return gf2::count_zeros(*this); }
1367
1379 constexpr usize leading_zeros() const { return gf2::leading_zeros(*this); }
1380
1390 constexpr usize trailing_zeros() const { return gf2::trailing_zeros(*this); }
1391
1395
1411 constexpr std::optional<usize> first_set() const { return gf2::first_set(*this); }
1412
1426 constexpr std::optional<usize> last_set() const { return gf2::last_set(*this); }
1427
1440 constexpr std::optional<usize> next_set(usize index) const { return gf2::next_set(*this, index); }
1441
1454 constexpr std::optional<usize> previous_set(usize index) const { return gf2::previous_set(*this, index); }
1455
1459
1475 constexpr std::optional<usize> first_unset() const { return gf2::first_unset(*this); }
1476
1492 constexpr std::optional<usize> last_unset() const { return gf2::last_unset(*this); }
1493
1508 constexpr std::optional<usize> next_unset(usize index) const { return gf2::next_unset(*this, index); }
1509
1525 constexpr std::optional<usize> previous_unset(usize index) const { return gf2::previous_unset(*this, index); }
1526
1530
1544 constexpr auto bits() const { return gf2::bits(*this); }
1545
1560 constexpr auto bits() { return gf2::bits(*this); }
1561
1573 constexpr auto set_bits() const { return gf2::set_bits(*this); }
1574
1586 constexpr auto unset_bits() const { return gf2::unset_bits(*this); }
1587
1600 constexpr auto store_words() const { return gf2::store_words(*this); }
1601
1605
1624 constexpr void to_words(std::output_iterator<word_type> auto out) { gf2::to_words(*this, out); }
1625
1636 constexpr auto to_words() const { return gf2::to_words(*this); }
1637
1641
1655 constexpr auto span(usize begin, usize end) const { return gf2::span(*this, begin, end); }
1656
1673 constexpr auto span(usize begin, usize end) { return gf2::span(*this, begin, end); }
1674
1678
1693 constexpr auto sub(usize begin, usize end) const { return gf2::sub(*this, begin, end); }
1694
1698
1721 constexpr void split_at(usize at, BitVector<word_type>& left, BitVector<word_type>& right) const {
1722 return gf2::split(*this, at, left, right);
1723 }
1724
1743 constexpr auto split_at(usize at) const { return gf2::split(*this, at); }
1744
1748
1763 constexpr void riffled(BitVector<word_type>& dst) const { return gf2::riffle(*this, dst); }
1764
1777 constexpr auto riffled() const { return gf2::riffle(*this); }
1778
1782
1799 std::string to_binary_string(std::string_view sep = "", std::string_view pre = "",
1800 std::string_view post = "") const {
1801 return gf2::to_binary_string(*this, sep, pre, post);
1802 }
1803
1820 std::string to_string(std::string_view sep = "", std::string_view pre = "", std::string_view post = "") const {
1821 return gf2::to_string(*this, sep, pre, post);
1822 }
1823
1836 std::string to_pretty_string() const { return gf2::to_pretty_string(*this); }
1837
1868 std::string to_hex_string() const { return gf2::to_hex_string(*this); }
1869
1873 std::string describe() const { return gf2::describe(*this); }
1874
1876};
1877
1878} // namespace gf2
A BitRef is a proxy type that references a single bit in a bit-store. See the BitRef page for more ...
Non-owning views of a range of bits from some underlying contiguous unsigned words....
A concept for types that can access individual bits packed into contiguous primitive unsigned words,...
Five bit-store iterators that serve different purposes. See the Iterators page for more details.
#define gf2_debug_assert(cond,...)
A confirmation macro that checks a boolean condition cond. On failure, the confirmation prints an e...
Definition assert.h:68
#define gf2_assert(cond,...)
A confirmation macro that checks a boolean condition cond. On failure, the confirmation prints an e...
Definition assert.h:98
constexpr const Word * store() const
Returns a const pointer to the underlying store of words .
Definition BitVector.h:116
constexpr auto bits()
Returns a non-const iterator over the values of the bits in the mutable bit-vector.
Definition BitVector.h:1560
constexpr std::optional< usize > last_set() const
Returns the index of the last set bit in the bit-vector or {} if no bits are set.
Definition BitVector.h:1426
constexpr auto sub(usize begin, usize end) const
Returns a clone of the elements in the half-open range [begin, end) as a new bit-vector.
Definition BitVector.h:1693
constexpr auto span(usize begin, usize end) const
Returns an immutable bit-span encompassing the bit-vector's bits in the half-open range [begin,...
Definition BitVector.h:1655
static constexpr BitVector from(usize size, std::invocable< usize > auto f)
Factory method to construct a bit-vector by repeatedly calling f(i) for i in [0, size).
Definition BitVector.h:345
constexpr BitVector(usize size=0)
Constructs a bit-vector of length n with all the bit elements set to 0.
Definition BitVector.h:150
constexpr Word * store()
Returns a pointer to the underlying store of words.
Definition BitVector.h:128
constexpr auto unset_bits() const
Returns an iterator over the indices of any unset bits in the bit-vector.
Definition BitVector.h:1586
static std::optional< BitVector > from_string(std::string_view sv)
Factory method to construct a bit-vector from a string s, returning std::nullopt on failure.
Definition BitVector.h:436
constexpr auto copy(Src const &src)
Copies all the bits from any src bit-store to this equal-sized bit-vector and returns a reference to ...
Definition BitVector.h:1275
static std::optional< BitVector > from_binary_string(std::string_view sv, bool no_punctuation=false)
Factory method to construct a bit-vector from a binary string, returning std::nullopt on failure.
Definition BitVector.h:473
static BitVector biased_random(usize size, double p)
Factory method to generate a bit-vector of size size where the elements are from independent fair coi...
Definition BitVector.h:410
constexpr usize trailing_zeros() const
Returns the number of trailing zeros in the bit-vector.
Definition BitVector.h:1390
constexpr BitVector< Word > split_off(usize at)
Splits a bit-vector into two at the given index, returning a new BitVector.
Definition BitVector.h:867
constexpr auto copy(std::bitset< N > const &src)
Copies all the bits from a std::bitset to this equal-sized bit-vector and returns a reference to this...
Definition BitVector.h:1297
static constexpr BitVector with_capacity(usize capacity)
Factory method to construct an empty bit-vector with at least the specified capacity.
Definition BitVector.h:183
constexpr bool is_empty() const
Returns true if the bit-vector is empty, false otherwise.
Definition BitVector.h:1125
constexpr void copy(Iter src_begin, Iter src_end)
Copies all the bits from an iteration of any unsigned integral src values to this equal-sized bit-vec...
Definition BitVector.h:1251
constexpr auto append(Iter src_begin, Iter src_end)
Appends all the bits from an iteration of any Unsigneds and returns a reference to this for chaining.
Definition BitVector.h:729
static constexpr BitVector unit(usize n, usize i)
Factory method to generate a "unit" bit-vector of length n where only element i is set.
Definition BitVector.h:226
constexpr usize remaining_capacity() const
Returns the number of additional elements we can store in the bit-vector without reallocating.
Definition BitVector.h:578
constexpr usize leading_zeros() const
Returns the number of leading zeros in the bit-vector.
Definition BitVector.h:1379
static constexpr u8 bits_per_word
Definition BitVector.h:36
constexpr auto operator[](usize i)
Returns a "reference" to the bit element i.
Definition BitVector.h:1066
static constexpr BitVector from(Src src)
Factory method to construct a bit-vector by copying all the bits from any Unsigned instance....
Definition BitVector.h:259
constexpr bool get(usize i) const
Returns true if the bit at the given index i is set, false otherwise.
Definition BitVector.h:978
constexpr auto set_bits() const
Returns an iterator over the indices of any set bits in the bit-vector.
Definition BitVector.h:1573
constexpr bool operator[](usize i) const
Returns the boolean value of the bit element i.
Definition BitVector.h:993
static BitVector random(usize size, double p=0.5, u64 seed=0)
Factory method to generate a bit-vector of size size where the elements are picked at random.
Definition BitVector.h:373
constexpr usize capacity() const
Definition BitVector.h:569
constexpr auto copy(std::invocable< usize > auto f)
Fills the bit-vector by repeatedly calling f(i) and returns a reference to this for chaining.
Definition BitVector.h:1315
constexpr BitVector & shrink_to_fit()
Shrinks the bit-vector's capacity as much as possible.
Definition BitVector.h:591
constexpr auto riffled() const
Returns a new bit-vector that is the result of riffling the bits in this bit-vector with zeros.
Definition BitVector.h:1777
constexpr BitVector & append(Src const &src)
Appends all the bits from any BitStore src onto the end of the bit-vector and returns this for chaini...
Definition BitVector.h:758
static constexpr BitVector zeros(usize n)
Factory method to generate a bit-vector of length n where the elements are all 0.
Definition BitVector.h:196
static constexpr BitVector constant(usize n, bool value)
Factory method to generate a bit-vector of length n where the elements are set to value.
Definition BitVector.h:215
constexpr void split_at(usize at, BitVector< word_type > &left, BitVector< word_type > &right) const
Views the bit-vector as two parts containing the elements [0, at) and [at, size()) respectively.
Definition BitVector.h:1721
constexpr u8 offset() const
Returns the offset (in bits) of the first bit in the bit-vector within the first word.
Definition BitVector.h:133
constexpr auto set(usize i, bool value=true)
Sets the bit-element i to the specified boolean value & returns this for chaining....
Definition BitVector.h:1040
constexpr std::optional< usize > first_set() const
Returns the index of the first set bit in the bit-vector or {} if no bits are set.
Definition BitVector.h:1411
constexpr BitVector & append_digit(char c, int base)
Appends a single character c onto the end of bit-vector and returns this for chaining.
Definition BitVector.h:802
constexpr std::optional< bool > pop()
Removes the last bit from the bit-vector and returns it or std::nullopt if the bit-vector is empty.
Definition BitVector.h:679
std::string to_binary_string(std::string_view sep="", std::string_view pre="", std::string_view post="") const
Returns a binary string representation of the bit-vector.
Definition BitVector.h:1799
constexpr void clean()
Sets any unused bits in the last occupied word to 0.
Definition BitVector.h:634
constexpr void split_off(usize at, BitVector< Word > &dst)
Splits a bit-vector into two at the given index, returning the second part in dst.
Definition BitVector.h:889
constexpr BitVector(usize size, Word word)
Constructs a bit-vector with size elements by repeatedly copying all the bits from word.
Definition BitVector.h:166
constexpr auto copy(Src src)
Copies all the bits from any unsigned integral src value to this equal-sized bit-vector....
Definition BitVector.h:1226
constexpr auto bits() const
Returns a const iterator over the bool values of the bits in the const bit-vector.
Definition BitVector.h:1544
constexpr std::optional< usize > previous_set(usize index) const
Returns the index of the previous set bit before index in the bit-vector or {} if there are none.
Definition BitVector.h:1454
static constexpr BitVector from(Iter src_begin, Iter src_end)
Factory method to construct a bit-vector by copying all the bits from an iteration of any Unsigneds.
Definition BitVector.h:280
constexpr usize size() const
Returns the number of bit-elements in the bit-vector.
Definition BitVector.h:50
constexpr auto split_at(usize at) const
Views the bit-vector as two parts containing the elements [0, at) and [at, size()) respectively.
Definition BitVector.h:1743
constexpr std::optional< usize > previous_unset(usize index) const
Returns the index of the previous unset bit before index in the bit-vector or {} if no more unset bit...
Definition BitVector.h:1525
constexpr usize words() const
Returns the number of words in the bit-vector's underlying word store.
Definition BitVector.h:63
constexpr auto set_all(bool value=true)
Sets the bits in the bit-vector to the boolean value and returns a reference to this for chaining.
Definition BitVector.h:1182
static std::optional< BitVector > from_hex_string(std::string_view sv, bool no_punctuation=false)
Factory method to construct a bit-vector from a hex string, returning std::nullopt on failure.
Definition BitVector.h:514
constexpr Word word(usize i) const
Returns word i from the bit-vector's underlying word store.
Definition BitVector.h:80
constexpr BitVector & append_hex_digit(char c)
Appends a single hex digit character c onto the end of bit-vector and returns this for chaining.
Definition BitVector.h:836
std::string describe() const
Returns a multi-line string describing the bit-vector in some detail.
Definition BitVector.h:1873
constexpr std::optional< Dst > split_off_unsigned()
Split off a single arbitrary sized unsigned integer off the end of the bit-vector and returns it or s...
Definition BitVector.h:920
constexpr BitVector & resize(usize n)
Resize the bit-vector so that its size() is n.
Definition BitVector.h:619
constexpr auto fill_random(double p=0.5, u64 seed=0)
Fill the bit-vector with random bits and returns a reference to this for chaining.
Definition BitVector.h:1337
constexpr std::optional< usize > next_unset(usize index) const
Returns the index of the next unset bit after index in the bit-vector or {} if no more unset bits exi...
Definition BitVector.h:1508
constexpr std::optional< usize > next_set(usize index) const
Returns the index of the next set bit after index in the bit-vector or {} if no more set bits exist.
Definition BitVector.h:1440
constexpr BitVector & push(bool b)
Pushes a single bit b onto the bit-vector.
Definition BitVector.h:656
constexpr void set_word(usize i, Word word)
Sets word i in the bit-vector's underlying word store to value (masked if necessary).
Definition BitVector.h:100
constexpr bool front() const
Returns true if the first bit element is set, false otherwise.
Definition BitVector.h:1007
constexpr auto swap(usize i0, usize i1)
Swaps the bits in the bit-vector at indices i0 and i1 and returns this for chaining.
Definition BitVector.h:1107
static constexpr BitVector ones(usize n)
Factory method to generate a bit-vector of length n where the elements are all 1.
Definition BitVector.h:204
constexpr auto to_words() const
Returns a copy of the words underlying this bit-vector as a new std::vector<word_type>.
Definition BitVector.h:1636
constexpr usize count_ones() const
Returns the number of set bits in the bit-vector.
Definition BitVector.h:1355
constexpr bool any() const
Returns true if at least one bit in the bit-vector is set, false otherwise.
Definition BitVector.h:1138
static constexpr BitVector from(std::bitset< N > const &src)
Factory method to construct a bit-vector from the bits of a std::bitset.
Definition BitVector.h:328
Word word_type
Definition BitVector.h:33
constexpr usize count_zeros() const
Returns the number of unset bits in the bit-vector.
Definition BitVector.h:1366
std::string to_string(std::string_view sep="", std::string_view pre="", std::string_view post="") const
Returns a binary string representation of the bit-vector.
Definition BitVector.h:1820
constexpr void riffled(BitVector< word_type > &dst) const
Interleaves the bits of this bit-vector with zeros storing the result into the bit-vector dst.
Definition BitVector.h:1763
constexpr bool none() const
Returns true if no bits in the bit-vector are set, false otherwise.
Definition BitVector.h:1166
constexpr auto flip(usize i)
Flips the value of the bit-element i and returns this for chaining.
Definition BitVector.h:1083
constexpr std::optional< usize > first_unset() const
Returns the index of the first unset bit in the bit-vector or {} if no bits are unset.
Definition BitVector.h:1475
constexpr void to_words(std::output_iterator< word_type > auto out)
Returns a copy of the words underlying this bit-vector and puts them into the passed output iterator.
Definition BitVector.h:1624
constexpr BitVector & clear()
Removes all elements from the bit-vector so size()==0.
Definition BitVector.h:600
constexpr std::optional< usize > last_unset() const
Returns the index of the last unset bit in the bit-vector or {} if no bits are unset.
Definition BitVector.h:1492
static BitVector seeded_random(usize size, u64 seed)
Factory method to generate a bit-vector of size size where the elements are from independent fair coi...
Definition BitVector.h:396
constexpr bool all() const
Returns true if all bits in the bit-vector are set, false otherwise.
Definition BitVector.h:1153
constexpr bool back() const
Returns true if the last bit element is set, false otherwise.
Definition BitVector.h:1021
static constexpr BitVector from(Src const &src)
Factory method to construct a bit-vector by copying all the bits from any other bit-store instance.
Definition BitVector.h:310
std::string to_pretty_string() const
Returns a "pretty" string representation of the bit-vector.
Definition BitVector.h:1836
constexpr auto store_words() const
Returns a const iterator over all the words underlying the bit-vector.
Definition BitVector.h:1600
auto append(std::bitset< N > const &src)
Appends all the bits from a std::bitset onto the end of the bit-vector and returns this for chaining.
Definition BitVector.h:775
static constexpr BitVector alternating(usize n)
Factory method to generate a bit-vector of length n looking like 101010....
Definition BitVector.h:239
constexpr auto append(Src src)
Appends all the bits from any unsigned integral src value and returns a reference to this for chainin...
Definition BitVector.h:705
constexpr auto span(usize begin, usize end)
Returns a mutable bit-span encompassing the bit-vector's bits in the half-open range [begin,...
Definition BitVector.h:1673
std::string to_hex_string() const
Returns the "hex" string representation of the bits in the bit-vector.
Definition BitVector.h:1868
constexpr auto flip_all()
Flips the value of the bits in the bit-vector and returns a reference to this for chaining.
Definition BitVector.h:1195
The namespace for the gf2 library.
Definition assert.h:119
constexpr void set(Store &store, usize i, bool value=true)
Sets the bit-element at the given index to the specified boolean value (default value is true).
Definition BitStore.h:254
constexpr void set_all(Store &store, bool value=true)
Sets the bits in the store to the boolean value.
Definition BitStore.h:439
constexpr std::optional< usize > first_unset(Store const &store)
Returns the index of the first unset bit in the bit-store or {} if no bits are unset.
Definition BitStore.h:974
constexpr std::optional< usize > first_set(Store const &store)
Returns the index of the first set bit in the bit-store or {} if no bits are set.
Definition BitStore.h:841
constexpr bool is_empty(Store const &store)
Returns true if the store is empty, false otherwise.
Definition BitStore.h:345
constexpr std::optional< usize > next_unset(Store const &store, usize index)
Returns the index of the next unset bit after index in the store or {} if no more unset bits exist.
Definition BitStore.h:1039
constexpr void swap(Store &store, usize i0, usize i1)
Swaps the bits in the bit-store at indices i0 and i1.
Definition BitStore.h:307
constexpr Word ALTERNATING
The Unsigned instance with alternating bits set to 0 and 1.
Definition Unsigned.h:91
static std::string to_string(Store const &store, std::string_view sep="", std::string_view pre="", std::string_view post="")
Returns a binary string representation of a store.
Definition BitStore.h:1588
constexpr auto ref(Store &store, usize i)
Returns a "reference" to the bit element i in the given bit-store.
Definition BitStore.h:197
constexpr usize count_zeros(Store const &store)
Returns the number of unset bits in the store.
Definition BitStore.h:762
constexpr void split(Store const &store, usize at, BitVector< typename Store::word_type > &left, BitVector< typename Store::word_type > &right)
Views a bit-store as two parts containing the elements [0, at) and [at, size()) respectively....
Definition BitStore.h:1387
constexpr bool get(Store const &store, usize i)
Returns the bool value of the bit at index i in the given bit-store.
Definition BitStore.h:168
constexpr auto set_bits(Store const &store)
Returns an iterator over the indices of any set bits in the bit-store.
Definition BitStore.h:1170
constexpr bool back(Store const &store)
Returns true if the final bit element is set, false otherwise.
Definition BitStore.h:235
static std::string to_pretty_string(Store const &store)
Returns a "pretty" string representation of a store.
Definition BitStore.h:1606
std::uint64_t u64
Word type alias for a 64-bit unsigned integer.
Definition Unsigned.h:39
constexpr std::optional< usize > previous_set(Store const &store, usize index)
Returns the index of the previous set bit before index in the store or {} if there are none.
Definition BitStore.h:928
constexpr auto store_words(Store const &store)
Returns a const iterator over all the words underlying the bit-store.
Definition BitStore.h:1211
constexpr std::optional< usize > next_set(Store const &store, usize index)
Returns the index of the next set bit after index in the store or {} if no more set bits exist.
Definition BitStore.h:890
std::uint8_t u8
Word type alias for an 8-bit unsigned integer.
Definition Unsigned.h:30
constexpr bool all(Store const &store)
Returns true if all bits in the store are set, false otherwise.
Definition BitStore.h:385
constexpr auto sub(Store const &store, usize begin, usize end)
Returns a clone of the elements in the half-open range [begin, end) as a new bit-vector.
Definition BitStore.h:1356
static constexpr auto span(Store const &store, usize begin, usize end)
Constructs a read-only bit-span over the const bit-store store for its bits in the range [begin,...
Definition BitStore.h:1277
constexpr void flip_all(Store &store)
Flips the value of the bits in the store.
Definition BitStore.h:455
constexpr auto bits(Store const &store)
Returns a const iterator over the bool values of the bits in the const bit-store.
Definition BitStore.h:1133
constexpr auto unset_bits(Store const &store)
Returns an iterator over the indices of any unset bits in the bit-store.
Definition BitStore.h:1187
constexpr void flip(Store &store, usize i)
Flips the value of the bit-element at the given index.
Definition BitStore.h:279
static std::string to_hex_string(Store const &store)
Returns the "hex" string representation of the bits in the bit-store.
Definition BitStore.h:1642
constexpr usize count_ones(Store const &store)
Returns the number of set bits in the store.
Definition BitStore.h:745
constexpr usize leading_zeros(Store const &store)
Returns the number of leading zeros in the store.
Definition BitStore.h:779
constexpr std::optional< usize > previous_unset(Store const &store, usize index)
Returns the index of the previous unset bit before index in the store or {} if no more unset bits exi...
Definition BitStore.h:1084
constexpr void copy(Src src, Store &store)
Copies all the bits from any unsigned integral src value to an equal-sized bit-store.
Definition BitStore.h:485
constexpr bool front(Store const &store)
Returns true if the first bit element is set, false otherwise.
Definition BitStore.h:216
constexpr void to_words(Store const &store, std::output_iterator< typename Store::word_type > auto out)
Returns a copy of the words underlying this bit-store and puts them into the passed output iterator.
Definition BitStore.h:1235
constexpr usize trailing_zeros(Store const &store)
Returns the number of trailing zeros in the store.
Definition BitStore.h:800
std::size_t usize
Word type alias for the platform's "native"-sized unsigned integer.
Definition Unsigned.h:42
constexpr bool none(Store const &store)
Returns true if no bits in the store are set, false otherwise.
Definition BitStore.h:419
constexpr void riffle(Store const &store, BitVector< typename Store::word_type > &dst)
Interleaves the bits of a bit-store with zeros storing the result into the passed bit-vector dst.
Definition BitStore.h:1468
constexpr void fill_random(Store &store, double p=0.5, u64 seed=0)
Fill the store with random bits based on an optional probability p and an optional seed for the RNG.
Definition BitStore.h:697
constexpr Word MAX
The Unsigned instance with all its bits set to 1.
Definition Unsigned.h:82
constexpr u8 BITS
The number of bits in an Unsigned returned as a u8.
Definition Unsigned.h:55
constexpr bool any(Store const &store)
Returns true if at least one bit in the store is set, false otherwise.
Definition BitStore.h:363
constexpr std::optional< usize > last_unset(Store const &store)
Returns the index of the last unset bit in the bit-store or {} if no bits are unset.
Definition BitStore.h:1007
constexpr usize words_needed(usize n_bits)
Returns the number of Unsigneds needed to store n_bits bits.
Definition Unsigned.h:530
static std::string describe(Store const &store)
Detailed Description of a Bit-Store.
Definition BitStore.h:1685
static std::string to_binary_string(Store const &store, std::string_view sep="", std::string_view pre="", std::string_view post="")
Returns a binary string representation of a store.
Definition BitStore.h:1537
constexpr std::optional< usize > last_set(Store const &store)
Returns the index of the last set bit in the bit-store or {} if no bits are set.
Definition BitStore.h:866