Inside Bitcoin
Opening the selected file…
Inside Bitcoin
Opening the selected file…
The code behind the network, with room to understand it.
Release published 2026-10-28 · Snapshot fetched 2026-11-01. Latest stable release at fetch time; development branches and Git history are excluded. Only the selected code window and visible folders load here.
251/** Iterator type returned by begin(), which efficiently iterates all 1 positions. */252class Iterator253{254friend class MultiIntBitSet;255const std::array<I, N>* m_ptr; /**< Pointer to array to fetch bits from. */256I m_val; /**< The remaining bits of (*m_ptr)[m_idx]. */257unsigned m_pos; /**< The last reported position. */258unsigned m_idx; /**< The index in *m_ptr currently being iterated over. */259constexpr Iterator(const std::array<I, N>& ref) noexcept : m_ptr(&ref), m_idx(0)260{261do {262m_val = (*m_ptr)[m_idx];263if (m_val) {264m_pos = std::countr_zero(m_val) + m_idx * LIMB_BITS;265break;266}267++m_idx;268} while(m_idx < N);269}271public:272/** Do not allow external code to construct an Iterator. */273Iterator() = delete;274// Copying is allowed.275constexpr Iterator(const Iterator&) noexcept = default;276constexpr Iterator& operator=(const Iterator&) noexcept = default;277/** Test whether we are done (can only compare with IteratorEnd). */278friend constexpr bool operator==(const Iterator& a, const IteratorEnd&) noexcept279{280return a.m_idx == N;281}282/** Progress to the next 1 bit (only if != IteratorEnd). */283constexpr Iterator& operator++() noexcept284{285Assume(m_idx < N);286m_val &= m_val - I{1U};287if (m_val == 0) {288while (true) {289++m_idx;290if (m_idx == N) break;291m_val = (*m_ptr)[m_idx];292if (m_val) {293m_pos = std::countr_zero(m_val) + m_idx * LIMB_BITS;294break;295}296}297} else {298m_pos = std::countr_zero(m_val) + m_idx * LIMB_BITS;299}300return *this;301}302/** Get the current bit position (only if != IteratorEnd). */303constexpr unsigned operator*() const noexcept304{305Assume(m_idx < N);306return m_pos;307}308};310public:311/** Construct an all-zero bitset. */312constexpr MultiIntBitSet() noexcept : m_val{} {}313/** Copy construct a bitset. */314constexpr MultiIntBitSet(const MultiIntBitSet&) noexcept = default;315/** Copy assign a bitset. */316constexpr MultiIntBitSet& operator=(const MultiIntBitSet&) noexcept = default;317/** Set a bit to 1. */318void constexpr Set(unsigned pos) noexcept319{320Assume(pos < MAX_SIZE);321m_val[pos / LIMB_BITS] |= I{1U} << (pos % LIMB_BITS);322}323/** Set a bit to the specified value. */324void constexpr Set(unsigned pos, bool val) noexcept325{326Assume(pos < MAX_SIZE);327m_val[pos / LIMB_BITS] = (m_val[pos / LIMB_BITS] & ~I(I{1U} << (pos % LIMB_BITS))) |328(I{val} << (pos % LIMB_BITS));329}330/** Construct a bitset from a list of values. */331constexpr MultiIntBitSet(std::initializer_list<unsigned> ilist) noexcept : m_val{}332{333for (auto pos : ilist) Set(pos);334}335/** Set a bitset to a list of values. */336constexpr MultiIntBitSet& operator=(std::initializer_list<unsigned> ilist) noexcept337{338m_val.fill(0);339for (auto pos : ilist) Set(pos);340return *this;341}342/** Set a bit to 0. */343void constexpr Reset(unsigned pos) noexcept344{345Assume(pos < MAX_SIZE);346m_val[pos / LIMB_BITS] &= ~I(I{1U} << (pos % LIMB_BITS));347}348/** Retrieve a bit at the given position. */349bool constexpr operator[](unsigned pos) const noexcept350{351Assume(pos < MAX_SIZE);352return (m_val[pos / LIMB_BITS] >> (pos % LIMB_BITS)) & 1U;353}354/** Construct a bitset with the singleton pos. */355static constexpr MultiIntBitSet Singleton(unsigned pos) noexcept356{357Assume(pos < MAX_SIZE);358MultiIntBitSet ret;359ret.m_val[pos / LIMB_BITS] = I{1U} << (pos % LIMB_BITS);360return ret;361}362/** Construct a bitset with bits 0..count-1 (inclusive) set to 1. */363static constexpr MultiIntBitSet Fill(unsigned count) noexcept364{365Assume(count <= MAX_SIZE);366MultiIntBitSet ret;367if (count) {368unsigned i = 0;369while (count > LIMB_BITS) {370ret.m_val[i++] = I(~I{0});371count -= LIMB_BITS;372}373ret.m_val[i] = I(~I{0}) >> (LIMB_BITS - count);374}375return ret;376}377/** Return the number of bits that this object holds. */378static constexpr unsigned Size() noexcept { return MAX_SIZE; }379/** Compute the number of 1 bits in the bitset. */380unsigned constexpr Count() const noexcept381{382unsigned ret{0};383for (I v : m_val) ret += PopCount(v);384return ret;385}386/** Check if all bits are 0. */387bool constexpr None() const noexcept388{389for (auto v : m_val) {390if (v != 0) return false;391}392return true;393}394/** Check if any bits are 1. */395bool constexpr Any() const noexcept { return !None(); }396/** Return an object that iterates over all 1 bits (++ and * only allowed when != end()). */397Iterator constexpr begin() const noexcept { return Iterator(m_val); }398/** Return a dummy object to compare Iterators with. */399IteratorEnd constexpr end() const noexcept { return IteratorEnd(); }400/** Find the first element (requires Any()). */401unsigned constexpr First() const noexcept402{403unsigned p = 0;404while (m_val[p] == 0) {405++p;406Assume(p < N);407}408return std::countr_zero(m_val[p]) + p * LIMB_BITS;409}410/** Find the last element (requires Any()). */411unsigned constexpr Last() const noexcept412{413unsigned p = N - 1;414while (m_val[p] == 0) {415Assume(p > 0);416--p;417}418return std::bit_width(m_val[p]) - 1 + p * LIMB_BITS;419}420/** Set this object's bits to be the binary OR between respective bits from this and a. */421constexpr MultiIntBitSet& operator|=(const MultiIntBitSet& a) noexcept422{423for (unsigned i = 0; i < N; ++i) {424m_val[i] |= a.m_val[i];425}426return *this;427}428/** Set this object's bits to be the binary AND between respective bits from this and a. */429constexpr MultiIntBitSet& operator&=(const MultiIntBitSet& a) noexcept430{431for (unsigned i = 0; i < N; ++i) {432m_val[i] &= a.m_val[i];433}434return *this;435}436/** Set this object's bits to be the binary AND NOT between respective bits from this and a. */437constexpr MultiIntBitSet& operator-=(const MultiIntBitSet& a) noexcept438{439for (unsigned i = 0; i < N; ++i) {440m_val[i] &= ~a.m_val[i];441}442return *this;443}444/** Set this object's bits to be the binary XOR between respective bits from this and a. */445constexpr MultiIntBitSet& operator^=(const MultiIntBitSet& a) noexcept446{447for (unsigned i = 0; i < N; ++i) {448m_val[i] ^= a.m_val[i];449}450return *this;451}452/** Check whether the intersection between two sets is non-empty. */453constexpr bool Overlaps(const MultiIntBitSet& a) const noexcept454{455for (unsigned i = 0; i < N; ++i) {456if (m_val[i] & a.m_val[i]) return true;457}458return false;459}460/** Return an object with the binary AND between respective bits from a and b. */461friend constexpr MultiIntBitSet operator&(const MultiIntBitSet& a, const MultiIntBitSet& b) noexcept462{463MultiIntBitSet r;464for (unsigned i = 0; i < N; ++i) {465r.m_val[i] = a.m_val[i] & b.m_val[i];466}467return r;468}469/** Return an object with the binary OR between respective bits from a and b. */470friend constexpr MultiIntBitSet operator|(const MultiIntBitSet& a, const MultiIntBitSet& b) noexcept471{472MultiIntBitSet r;473for (unsigned i = 0; i < N; ++i) {474r.m_val[i] = a.m_val[i] | b.m_val[i];475}476return r;477}478/** Return an object with the binary AND NOT between respective bits from a and b. */479friend constexpr MultiIntBitSet operator-(const MultiIntBitSet& a, const MultiIntBitSet& b) noexcept480{481MultiIntBitSet r;482for (unsigned i = 0; i < N; ++i) {483r.m_val[i] = a.m_val[i] & ~b.m_val[i];484}485return r;486}487/** Return an object with the binary XOR between respective bits from a and b. */488friend constexpr MultiIntBitSet operator^(const MultiIntBitSet& a, const MultiIntBitSet& b) noexcept489{490MultiIntBitSet r;491for (unsigned i = 0; i < N; ++i) {492r.m_val[i] = a.m_val[i] ^ b.m_val[i];493}494return r;495}496/** Check if bitset a is a superset of bitset b (= every 1 bit in b is also in a). */497constexpr bool IsSupersetOf(const MultiIntBitSet& a) const noexcept498{499for (unsigned i = 0; i < N; ++i) {500if (a.m_val[i] & ~m_val[i]) return false;
Independent explanations by MyBitcoinExplorer. Not affiliated with or endorsed by Bitcoin Core. Guides are educational and do not replace the source or its tests.
Bitcoin Core source © its contributors, distributed under the MIT license. Original notices and bundled third-party licenses are retained in the source tree.