GF2++
Loading...
Searching...
No Matches
BitSpan.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/BitVec.h>
13
14namespace gf2 {
15
29template<Unsigned Word = usize>
30class BitSpan {
31private:
32 // A pointer to the first word containing bits in the span (it may be partially occupied).
33 Word* m_store = nullptr;
34
35 // The bit-span begins at this bit-offset inside `m_store[0]`.
36 u8 m_offset = 0;
37
38 // The number of bits in the span.
39 usize m_size = 0;
40
41 // The number of words (synthesised) needed to hold the bits in the span (cached for efficiency).
42 usize m_words = 0;
43
44public:
45 // The underlying span uses words of this type (where we remove any `const` qualifier).
46 using word_type = std::remove_const_t<Word>;
47
49 static constexpr u8 bits_per_word = BITS<Word>;
50
53
74 BitSpan(Word* data, u8 offset, usize size) {
75
76 // Check that offset is valid.
77 gf2_debug_assert(offset < bits_per_word, "Span begins at bit-offset {} > bits in a word ({})!", offset,
79
80 // Set the member variables.
81 m_store = data;
82 m_offset = offset;
83 m_size = size;
84 m_words = gf2::words_needed<Word>(m_size);
85 }
86
90
99 constexpr usize size() const { return m_size; }
100
115 constexpr usize words() const { return m_words; }
116
132 constexpr word_type word(usize i) const {
133 // Get the recipe for the "word" at index `i` (we may need two real words to synthesise it).
134 auto [w0_bits, w1_bits] = recipe_for_word(i);
135
136 // Our return value starts with all unset bits.
137 word_type result = 0;
138
139 // Replace `w0_bits` low-order bits in `result` with the same number of high-order bits from `w0`
140 Word w0 = m_store[i];
141 gf2::replace_bits(result, 0, w0_bits, w0 >> m_offset);
142
143 // Perhaps our result spans two words.
144 if (w1_bits > 0) {
145 // Replace `w1_bits` high-order bits in result with the same number of low-order bits from `w1`
146 Word w1 = m_store[i + 1];
147 gf2::replace_bits(result, w0_bits, w0_bits + w1_bits, w1 << w0_bits);
148 }
149 return result;
150 }
151
169 constexpr void set_word(usize i, word_type value) {
170 if constexpr (std::is_const_v<Word>) {
171 // This should never get called for const bit-spans.
172 throw std::logic_error("Cannot set a word in a const bit-span.");
173 } else {
174 // Get the recipe for the "word" at index `i` (it may be a synthesis of two real words).
175 auto [w0_bits, w1_bits] = recipe_for_word(i);
176
177 // Replace `w0_bits` low-order bits in `w0` with the same number of high-order bits from `value`
178 // Shift `value` to the left to align its bits with the start of `w0`.
179 gf2::replace_bits(m_store[i], m_offset, m_offset + w0_bits, value << m_offset);
180
181 // Perhaps we also need to overwrite some bits in the second word.
182 if (w1_bits > 0) {
183 // Replace `w1_bits` low-order bits in `w1` with the same number of high-order bits from `value`
184 gf2::replace_bits(m_store[i + 1], 0, w1_bits, value >> w0_bits);
185 }
186 }
187 }
188
190 constexpr const Word* store() const { return m_store; }
191
193 constexpr Word* store() { return m_store; }
194
196 constexpr u8 offset() const { return m_offset; }
197
201
214 constexpr bool get(usize i) const { return gf2::get(*this, i); }
215
226 constexpr bool operator[](usize i) const { return gf2::get(*this, i); }
227
238 constexpr bool front() const { return gf2::front(*this); }
239
250 constexpr bool back() const { return gf2::back(*this); }
251
255
270 auto set(usize i, bool value = true) { return gf2::set(*this, i, value); }
271
293 constexpr auto operator[](usize i) { return gf2::ref(*this, i); }
294
308 auto flip(usize i) { return gf2::flip(*this, i); }
309
325 constexpr auto swap(usize i0, usize i1) { return gf2::swap(*this, i0, i1); }
326
330
341 constexpr bool is_empty() const { return gf2::is_empty(*this); }
342
355 constexpr bool any() const { return gf2::any(*this); }
356
371 constexpr bool all() const { return gf2::all(*this); }
372
385 constexpr bool none() const { return gf2::none(*this); }
386
390
403 auto set_all(bool value = true) { return gf2::set_all(*this, value); }
404
415 auto flip_all() { return gf2::flip_all(*this); }
416
420
442 template<Unsigned Src>
443 auto copy(Src src) {
444 return gf2::copy(src, *this);
445 }
446
461 template<BitStore Src>
462 auto copy(Src const& src) {
463 return gf2::copy(src, *this);
464 }
465
479 template<usize N>
480 auto copy(std::bitset<N> const& src) {
481 return gf2::copy(src, *this);
482 }
483
487
498 auto copy(std::invocable<usize> auto f) { return gf2::copy(*this, f); }
499
519 auto random_fill(double p = 0.5, u64 seed = 0) { return gf2::random_fill(*this, p, seed); }
520
524
535 constexpr usize count_ones() const { return gf2::count_ones(*this); }
536
547 constexpr usize count_zeros() const { return gf2::count_zeros(*this); }
548
561 constexpr usize leading_zeros() const { return gf2::leading_zeros(*this); }
562
575 constexpr usize trailing_zeros() const { return gf2::trailing_zeros(*this); }
576
580
593 constexpr std::optional<usize> first_set() const { return gf2::first_set(*this); }
594
608 constexpr std::optional<usize> last_set() const { return gf2::last_set(*this); }
609
622 constexpr std::optional<usize> next_set(usize index) const { return gf2::next_set(*this, index); }
623
636 constexpr std::optional<usize> previous_set(usize index) const { return gf2::previous_set(*this, index); }
637
641
654 constexpr std::optional<usize> first_unset() const { return gf2::first_unset(*this); }
655
669 constexpr std::optional<usize> last_unset() const { return gf2::last_unset(*this); }
670
684 constexpr std::optional<usize> next_unset(usize index) const { return gf2::next_unset(*this, index); }
685
698 constexpr std::optional<usize> previous_unset(usize index) const { return gf2::previous_unset(*this, index); }
699
703
717 constexpr auto bits() const { return gf2::bits(*this); }
718
734 constexpr auto bits() { return gf2::bits(*this); }
735
748 constexpr auto set_bits() const { return gf2::set_bits(*this); }
749
762 constexpr auto unset_bits() const { return gf2::unset_bits(*this); }
763
782 constexpr auto store_words() const { return gf2::store_words(*this); }
783
796 constexpr auto to_words() const { return gf2::to_words(*this); }
797
801
816 constexpr auto span(usize begin, usize end) const { return gf2::span(*this, begin, end); }
817
836 constexpr auto span(usize begin, usize end) { return gf2::span(*this, begin, end); }
837
841
857 constexpr auto sub(usize begin, usize end) const { return gf2::sub(*this, begin, end); }
858
862
885 constexpr void split_at(usize at, BitVec<word_type>& left, BitVec<word_type>& right) const {
886 return gf2::split(*this, at, left, right);
887 }
888
907 constexpr auto split_at(usize at) const { return gf2::split(*this, at); }
908
912
927 constexpr void riffled(BitVec<word_type>& dst) const { return gf2::riffle(*this, dst); }
928
941 constexpr auto riffled() const { return gf2::riffle(*this); }
942
946
964 std::string to_binary_string(std::string_view sep = "", std::string_view pre = "",
965 std::string_view post = "") const {
966 return gf2::to_binary_string(*this, sep, pre, post);
967 }
968
986 std::string to_string(std::string_view sep = "", std::string_view pre = "", std::string_view post = "") const {
987 return gf2::to_string(*this, sep, pre, post);
988 }
989
1003 std::string to_pretty_string() const { return gf2::to_pretty_string(*this); }
1004
1030 std::string to_hex_string() const { return gf2::to_hex_string(*this); }
1031
1035 std::string describe() const { return gf2::describe(*this); }
1036
1038
1039private:
1040 // A helper method to get the recipe used to "bake" the (generally synthetic) `word(i)`.
1041 //
1042 // Spans may not be aligned with the underlying unsigneds so we need to synthesise "words" as needed.
1043 // To synthesise word `i`, we use two contiguous words from the underlying vector of words, `w0`, and `w1`,
1044 // where `w0` is always m_words[i] and `w1` is always m_words[i + 1].
1045 //
1046 // We copy `w0_bits` high-order bits from `w0` and they become the low-order bits in the span "word": `word(i)`.
1047 // We copy `w1_bits` low-order bits from `w1` and they become the high-order bits in the span "word": `word(i)`.
1048 //
1049 // This "recipe" method returns the pair: `(w0_bits, w1_bits)` which tells you the numbers of needed bits.
1050 //
1051 // The only tricky part is that the last span word may not be fully occupied so we need to handle it differently
1052 // from the others.
1053 //
1054 // In debug mode we also check that the index `i` is valid.
1055 constexpr auto recipe_for_word(usize i) const {
1056 gf2_debug_assert(i < m_words, "Index {} should be less than {}", i, m_words);
1057
1058 // The default recipe (these sum to a whole word of bits).
1059 u8 w0_bits = bits_per_word - m_offset;
1060 u8 w1_bits = m_offset;
1061
1062 // The last word in the span may not be fully occupied so we need to adjust the bits accordingly.
1063 if (i == m_words - 1) {
1064 auto last_offset = static_cast<u8>((m_offset + m_size - 1) % bits_per_word);
1065 if (last_offset < m_offset) {
1066 // Still need to use two words but `w1-bits` may shrink.
1067 w1_bits = static_cast<u8>(last_offset + 1);
1068 } else {
1069 // Only need to use one word so no need for `w1_bits`.
1070 w0_bits = static_cast<u8>(last_offset - m_offset + 1);
1071 w1_bits = 0;
1072 }
1073 }
1074 return std::pair{w0_bits, w1_bits};
1075 }
1076};
1077
1078} // namespace gf2
A BitRef is a proxy type that references a single bit in a bit-store. See the BitRef page for more ...
A concept for types that can access individual bits packed into contiguous primitive unsigned words,...
Vectors over GF(2) with compactly stored bit-elements in a standard vector of primitive unsigned word...
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
constexpr usize leading_zeros() const
Returns the number of leading zeros in the span.
Definition BitSpan.h:561
constexpr auto sub(usize begin, usize end) const
Returns a clone of the span elements in the half-open range [begin, end) as a new bit-vector.
Definition BitSpan.h:857
auto set_all(bool value=true)
Sets the bits in the span to the boolean value and returns a reference to this for chaining.
Definition BitSpan.h:403
constexpr std::optional< usize > first_set() const
Returns the index of the first set bit in the bit-span or {} if no bits are set.
Definition BitSpan.h:593
std::string describe() const
Returns a multi-line string describing the bit-span in some detail.
Definition BitSpan.h:1035
constexpr auto unset_bits() const
Returns an iterator over the indices of any unset bits in the bit-span.
Definition BitSpan.h:762
auto copy(Src src)
Copies the bits from an unsigned integral src value and returns a reference to this for chaining.
Definition BitSpan.h:443
constexpr bool front() const
Returns true if the first bit element is set, false otherwise.
Definition BitSpan.h:238
constexpr usize size() const
Returns the number of bits in the span.
Definition BitSpan.h:99
constexpr std::optional< usize > next_set(usize index) const
Returns the index of the next set bit after index in the span or {} if no more set bits exist.
Definition BitSpan.h:622
constexpr bool any() const
Returns true if at least one bit in the span is set, false otherwise.
Definition BitSpan.h:355
static constexpr u8 bits_per_word
A constant – the number of bits in a Word.
Definition BitSpan.h:49
constexpr void riffled(BitVec< word_type > &dst) const
Interleaves the bits of this bit-span with zeros storing the result into the bit-vector dst.
Definition BitSpan.h:927
constexpr bool operator[](usize i) const
Returns the boolean value of the bit element i.
Definition BitSpan.h:226
constexpr auto split_at(usize at) const
Views a bit-span as two parts containing the elements [0, at) and [at, size()) respectively.
Definition BitSpan.h:907
constexpr auto bits()
Returns a non-const iterator over the values of the bits in the mutable bit-span.
Definition BitSpan.h:734
constexpr auto swap(usize i0, usize i1)
Swaps the bits in the bit-span at indices i0 and i1 and returns this for chaining.
Definition BitSpan.h:325
constexpr word_type word(usize i) const
Returns a "word"'s worth of bits from the bit-span.
Definition BitSpan.h:132
auto copy(Src const &src)
Copies the bits from an equal-sized src span and returns a reference to this for chaining.
Definition BitSpan.h:462
BitSpan(Word *data, u8 offset, usize size)
Constructs a non-owning view over bits stored in contiguous words — a bit-span.
Definition BitSpan.h:74
constexpr std::optional< usize > next_unset(usize index) const
Returns the index of the next unset bit after index in the span or {} if no more unset bits exist.
Definition BitSpan.h:684
constexpr auto span(usize begin, usize end)
Returns an mutable sub-span encompassing the span's bits in the half-open range [begin,...
Definition BitSpan.h:836
constexpr usize trailing_zeros() const
Returns the number of trailing zeros in the span.
Definition BitSpan.h:575
auto copy(std::bitset< N > const &src)
Copies the bits of an equal-sized std::bitset and returns a reference to this for chaining.
Definition BitSpan.h:480
constexpr bool all() const
Returns true if all bits in the span are set, false otherwise.
Definition BitSpan.h:371
constexpr const Word * store() const
Returns a pointer to the first span word in some underlying span of words (const version).
Definition BitSpan.h:190
auto random_fill(double p=0.5, u64 seed=0)
Fill the span with random bits and returns a reference to this for chaining.
Definition BitSpan.h:519
constexpr auto bits() const
Returns a const iterator over the bool values of the bits in the const bit-span.
Definition BitSpan.h:717
auto set(usize i, bool value=true)
Sets the bit-element i to the specified boolean value & returns this for chaining....
Definition BitSpan.h:270
constexpr void split_at(usize at, BitVec< word_type > &left, BitVec< word_type > &right) const
Views a bit-span as two parts containing the elements [0, at) and [at, size()) respectively.
Definition BitSpan.h:885
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 span.
Definition BitSpan.h:964
std::string to_string(std::string_view sep="", std::string_view pre="", std::string_view post="") const
Returns a binary string representation of the span.
Definition BitSpan.h:986
constexpr Word * store()
Returns a pointer to the first span word in some underlying span of words (non-const version).
Definition BitSpan.h:193
auto flip(usize i)
Flips the value of the bit-element i and returns this for chaining.
Definition BitSpan.h:308
constexpr bool is_empty() const
Returns true if the span is empty, false otherwise.
Definition BitSpan.h:341
constexpr std::optional< usize > first_unset() const
Returns the index of the first unset bit in the bit-span or {} if no bits are unset.
Definition BitSpan.h:654
constexpr void set_word(usize i, word_type value)
Sets a "word"'s worth of bits in the bit-span.
Definition BitSpan.h:169
constexpr auto span(usize begin, usize end) const
Returns an immutable sub-span encompassing the span's bits in the half-open range [begin,...
Definition BitSpan.h:816
std::string to_hex_string() const
Returns the "hex" string representation of the bits in the bit-span.
Definition BitSpan.h:1030
constexpr auto store_words() const
Returns a const iterator over all the words underlying the bit-span.
Definition BitSpan.h:782
std::string to_pretty_string() const
Returns a "pretty" string representation of the span.
Definition BitSpan.h:1003
constexpr auto set_bits() const
Returns an iterator over the indices of any set bits in the bit-span.
Definition BitSpan.h:748
constexpr std::optional< usize > previous_set(usize index) const
Returns the index of the previous set bit before index in the span or {} if there are none.
Definition BitSpan.h:636
constexpr std::optional< usize > last_unset() const
Returns the index of the last unset bit in the bit-span or {} if no bits are unset.
Definition BitSpan.h:669
constexpr usize count_zeros() const
Returns the number of unset bits in the span.
Definition BitSpan.h:547
auto copy(std::invocable< usize > auto f)
Fill the span by repeatedly calling f(i) and returns a reference to this for chaining.
Definition BitSpan.h:498
constexpr u8 offset() const
Returns the offset (in bits) of the first bit in the span within the first span word.
Definition BitSpan.h:196
auto flip_all()
Flips the value of the bits in the span and returns a reference to this for chaining.
Definition BitSpan.h:415
constexpr std::optional< usize > last_set() const
Returns the index of the last set bit in the bit-span or {} if no bits are set.
Definition BitSpan.h:608
constexpr usize words() const
Returns the minimum number of words needed to hold the bits in the span.
Definition BitSpan.h:115
constexpr std::optional< usize > previous_unset(usize index) const
Returns the index of the previous unset bit before index in the span or {} if no more unset bits exis...
Definition BitSpan.h:698
constexpr auto operator[](usize i)
Returns a "reference" to the bit element i.
Definition BitSpan.h:293
constexpr bool back() const
Returns true if the last bit element is set, false otherwise.
Definition BitSpan.h:250
constexpr bool get(usize i) const
Returns true if the bit at the given index i is set, false otherwise.
Definition BitSpan.h:214
constexpr bool none() const
Returns true if no bits in the span are set, false otherwise.
Definition BitSpan.h:385
constexpr auto riffled() const
Returns a new bit-vector that is the result of riffling the bits in this bit-span with zeros.
Definition BitSpan.h:941
constexpr usize count_ones() const
Returns the number of set bits in the span.
Definition BitSpan.h:535
constexpr auto to_words() const
Returns a copy of the words underlying this bit-span.
Definition BitSpan.h:796
A dynamically-sized vector over GF(2) with bit elements compactly stored in a standard vector of prim...
Definition BitVec.h:23
The namespace for the gf2 library.
Definition assert.h:119
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:903
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:770
constexpr bool is_empty(Store const &store)
Returns true if the store is empty, false otherwise.
Definition BitStore.h:337
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:968
constexpr void replace_bits(Word &word, u8 begin, u8 end, Other other)
Replace the bits of word in the range [begin, end) with the bits from other leaving the rest unchange...
Definition Unsigned.h:265
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:1482
constexpr auto & flip_all(Store &store)
Flips the value of the bits in the store and returns the store for chaining.
Definition BitStore.h:445
constexpr auto ref(Store &store, usize i)
Returns a "reference" to the bit element i in the given bit-store.
Definition BitStore.h:189
constexpr usize count_zeros(Store const &store)
Returns the number of unset bits in the store.
Definition BitStore.h:691
constexpr auto & flip(Store &store, usize i)
Flips the value of the bit-element at the given index and returns the store for chaining.
Definition BitStore.h:269
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:163
constexpr auto set_bits(Store const &store)
Returns an iterator over the indices of any set bits in the bit-store.
Definition BitStore.h:1097
constexpr bool back(Store const &store)
Returns true if the final bit element is set, false otherwise.
Definition BitStore.h:225
constexpr auto & random_fill(Store &store, double p=0.5, u64 seed=0)
Fill the store with random bits and returns the store for chaining.
Definition BitStore.h:631
static std::string to_pretty_string(Store const &store)
Returns a "pretty" string representation of a store.
Definition BitStore.h:1500
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:857
constexpr auto store_words(Store const &store)
Returns a const iterator over all the words underlying the bit-store.
Definition BitStore.h:1137
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:819
constexpr auto & set_all(Store &store, bool value=true)
Sets the bits in the store to the boolean value and returns the store for chaining.
Definition BitStore.h:428
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:375
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:1253
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:1176
constexpr auto to_words(Store const &store)
Returns a copy of the words underlying this bit-store.
Definition BitStore.h:1153
constexpr void split(Store const &store, usize at, BitVec< typename Store::word_type > &left, BitVec< typename Store::word_type > &right)
Views a bit-store as two parts containing the elements [0, at) and [at, size()) respectively....
Definition BitStore.h:1283
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:1061
constexpr auto unset_bits(Store const &store)
Returns an iterator over the indices of any unset bits in the bit-store.
Definition BitStore.h:1114
constexpr auto & set(Store &store, usize i, bool value=true)
Sets the bit-element at the given index to the specified boolean value and returns the store for chai...
Definition BitStore.h:244
static std::string to_hex_string(Store const &store)
Returns the "hex" string representation of the bits in the bit-store.
Definition BitStore.h:1536
constexpr usize count_ones(Store const &store)
Returns the number of set bits in the store.
Definition BitStore.h:674
constexpr usize leading_zeros(Store const &store)
Returns the number of leading zeros in the store.
Definition BitStore.h:708
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:1013
constexpr auto & copy(Src src, Store &store)
Copies the bits from an unsigned integral src value and returns the store for chaining.
Definition BitStore.h:474
constexpr bool front(Store const &store)
Returns true if the first bit element is set, false otherwise.
Definition BitStore.h:207
constexpr usize trailing_zeros(Store const &store)
Returns the number of trailing zeros in the store.
Definition BitStore.h:729
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:408
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:354
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:936
constexpr usize words_needed(usize n_bits)
Returns the number of Unsigneds needed to store n_bits bits.
Definition Unsigned.h:523
static std::string describe(Store const &store)
Detailed Description of a Bit-Store.
Definition BitStore.h:1579
constexpr void riffle(Store const &store, BitVec< 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:1362
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:1431
constexpr auto & swap(Store &store, usize i0, usize i1)
Swaps the bits in the bit-store at indices i0 and i1 and returns the store for chaining.
Definition BitStore.h:297
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:795