git / moonbite-core / src/libmw/include/mw/common/BitSet.h · raw
#pragma once#include <mw/common/Traits.h>#include <boost/dynamic_bitset.hpp>#include <serialize.h>#include <vector>struct BitSet : public Traits::ISerializable{ boost::dynamic_bitset<> bitset; BitSet() = default; BitSet(const size_t size) : bitset(size) { } static BitSet From(const std::vector<uint8_t>& bytes) { BitSet ret; ret.bitset.reserve(bytes.size() * 8); for (uint8_t byte : bytes) { for (uint8_t i = 0; i < 8; i++) { ret.bitset.push_back(byte & (0x80 >> i)); } } return ret; } std::vector<uint8_t> bytes() const noexcept { std::vector<uint8_t> bytes((bitset.size() + 7) / 8); for (size_t i = 0; i < bytes.size(); i++) { for (uint8_t j = 0; j < 8; j++) { size_t bit_index = (i * 8) + j; if (bitset.size() > bit_index && bitset.test(bit_index)) { bytes[i] |= (0x80 >> j); } } } return bytes; } std::string str() const noexcept { std::string val; boost::to_string(bitset, val); // Reverse for ascending order return std::string(val.crbegin(), val.crend()); } bool test(uint64_t idx) const noexcept { return bitset.size() > idx && bitset.test(idx); } uint64_t count() const noexcept { return bitset.count(); } uint64_t size() const noexcept { return bitset.size(); } /// <summary> /// Calculates the number of set bits that are smaller or equal to idx. /// </summary> /// <param name="idx">The index to calculate the rank for.</param> /// <returns>The calculated rank.</returns> uint64_t rank(uint64_t idx) const noexcept { uint64_t rank = 0; for (uint64_t i = 0; i < idx; i++) { if (i >= size()) { break; } if (test(i)) { ++rank; } } return rank; } void set(size_t idx, bool val = true) noexcept { bitset.set(idx, val); } void set(size_t idx, size_t len, bool val) noexcept { for (size_t i = idx; i < (idx + len); i++) { bitset.set(i, val); } } void push_back(bool val) noexcept { bitset.push_back(val); } IMPL_SERIALIZED(BitSet); template <typename Stream> void Serialize(Stream& s) const { std::vector<uint8_t> vec = bytes(); ::Serialize(s, vec); } template <typename Stream> void Unserialize(Stream& s) { std::vector<uint8_t> vec; ::Unserialize(s, vec); *this = BitSet::From(vec); }};