MT Core (C++)
Core library for replacing C++ standard in project usage
Loading...
Searching...
No Matches
mtcore::BitsetFixed< NumBits > Struct Template Reference

Represents a bitset with dynamically allocated memory (using an mtcore allocator) Allows operating on an arbitrary number of bits. More...

#include <bitset.hpp>

Collaboration diagram for mtcore::BitsetFixed< NumBits >:

Classes

struct  BitsetAccess
 Helper for accessing a bitset position (including for setting bits) More...
 
struct  SetBitIter
 Simple bit set iterator that uses next() iteration to return the indices of all set bits. More...
 

Public Member Functions

void init (u64 val)
 
Result< void, BitStrInitErrorinit (const Slice< const char > binaryStr)
 Initializes a bitset from a binary string of 1's and 0's.
 
BitsetAccess operator[] (const size_t index)
 Access an individual bit at a specific position.
 
bool operator[] (const size_t index) const
 Access an individual bit at a specific position.
 
constexpr size_t size () const
 Gets the size of the bitset.
 
bool at (const size_t pos) const
 Reads a bit at a specific position.
 
BitsetFixedset (const size_t pos, const bool val)
 Sets a bit at a position to a specific value.
 
Bitsettoggle (const size_t pos)
 Toggles a bit at a specific position.
 
Optional< size_t > last_set () const
 Returns the position of the last set bit (if one is set) Otherwise, returns a null Optional.
 
Optional< size_t > first_set () const
 Returns the position of the first set bit (if one is set) Otherwise, returns a null Optional.
 
size_t pop_count () const
 Counts the number of set bits in the bitset.
 
SetBitIter set_bits () const
 Iterates over the indices of all set bits in the bitset.
 
BitsetFixedoperator&= (const BitsetFixed &other)
 
BitsetFixedoperator|= (const BitsetFixed &other)
 
BitsetFixedoperator^= (const BitsetFixed &other)
 
void set_all (const bool value)
 Sets all bits to a specific value.
 
BitsetFixedoperator<<= (const size_t amount)
 
BitsetFixedoperator>>= (const size_t amount)
 

Public Attributes

std::array< u64,(NumBits+63)/64 > bytes = {0}
 
Slice< u64bits = mut_slice_from(bytes)
 

Detailed Description

template<size_t NumBits = 64>
struct mtcore::BitsetFixed< NumBits >

Represents a bitset with dynamically allocated memory (using an mtcore allocator) Allows operating on an arbitrary number of bits.

Definition at line 826 of file bitset.hpp.

Member Function Documentation

◆ at()

template<size_t NumBits = 64>
bool mtcore::BitsetFixed< NumBits >::at ( const size_t pos) const
inlinenodiscard

Reads a bit at a specific position.

Parameters
posBit index to read
Returns
whether it is set or not

Definition at line 912 of file bitset.hpp.

912 {
913 ensure(pos < NumBits, "OUT OF BOUNDS ACCESS");
914 const auto block = pos / 64;
915 const auto bit = pos % 64;
916 const u64 bitMask = static_cast<u64>(0x1) << bit;
917 return (bits[block] & bitMask) != 0;
918 }
#define ensure(check,...)
Ensures that a check holds true, aborts the program if not true Will print error if the condition is ...
Represents a bitset with dynamically allocated memory (using an mtcore allocator) Allows operating on...
Definition bitset.hpp:826
Slice< u64 > bits
Definition bitset.hpp:828
Here is the caller graph for this function:

◆ first_set()

template<size_t NumBits = 64>
Optional< size_t > mtcore::BitsetFixed< NumBits >::first_set ( ) const
inlinenodiscard

Returns the position of the first set bit (if one is set) Otherwise, returns a null Optional.

Returns
Optional with first set bit position

Definition at line 974 of file bitset.hpp.

974 {
975 for (size_t i = 0; i < bits.len; ++i) {
976 if (bits[i]) {
977 return 64 * i + std::countr_zero(bits[i]);
978 }
979 }
980 return nullopt;
981 }
Here is the caller graph for this function:

◆ init() [1/2]

template<size_t NumBits = 64>
Result< void, BitStrInitError > mtcore::BitsetFixed< NumBits >::init ( const Slice< const char > binaryStr)
inline

Initializes a bitset from a binary string of 1's and 0's.

Parameters
binaryStrBinary string to use for initializing bits

Definition at line 841 of file bitset.hpp.

841 {
842 {
843 char cur = '\0';
844 auto iter = binaryStr.iter();
845 while (iter.next().copy_if_present(cur)) {
846 if (cur != '1' && cur != '0') {
848 }
849 }
850 }
851
852 char cur = '\0';
853 auto iter = binaryStr.iter();
854 size_t index = 0;
855 while (iter.next().copy_if_present(cur)) {
856 mtdefer { ++index; };
857 if (cur == '1') {
858 set(index, true);
859 }
860 }
861 return success();
862 }
Success< void > success()
Creates a successful void Result object.
Definition result.hpp:398
Error< Underlying > error(Underlying err)
Creates an error.
Definition result.hpp:425
BitsetFixed & set(const size_t pos, const bool val)
Sets a bit at a position to a specific value.
Definition bitset.hpp:925
Here is the call graph for this function:

◆ init() [2/2]

template<size_t NumBits = 64>
void mtcore::BitsetFixed< NumBits >::init ( u64 val)
inline

Definition at line 830 of file bitset.hpp.

830 {
831 bits[bits.size() - 1] = val;
832 if constexpr (NumBits % 64 != 0) {
833 *this <<= (NumBits % 64);
834 }
835 }
Here is the caller graph for this function:

◆ last_set()

template<size_t NumBits = 64>
Optional< size_t > mtcore::BitsetFixed< NumBits >::last_set ( ) const
inlinenodiscard

Returns the position of the last set bit (if one is set) Otherwise, returns a null Optional.

Returns
Optional with last set bit position

Definition at line 959 of file bitset.hpp.

959 {
960 for (size_t i = bits.len; i > 0; --i) {
961 auto indx = i - 1;
962 if (bits[indx]) {
963 return 64 * indx + 63 - std::countl_zero(bits[indx]);
964 }
965 }
966 return nullopt;
967 }
Here is the caller graph for this function:

◆ operator&=()

template<size_t NumBits = 64>
BitsetFixed & mtcore::BitsetFixed< NumBits >::operator&= ( const BitsetFixed< NumBits > & other)
inline

Definition at line 1027 of file bitset.hpp.

1027 {
1028 size_t i = 0;
1029 for (; i < other.bits.len && i < bits.len; ++i) {
1030 bits[i] &= other.bits[i];
1031 }
1032 for (; i < bits.len; ++i) {
1033 bits[i] = 0;
1034 }
1035 return *this;
1036 }

◆ operator<<=()

template<size_t NumBits = 64>
BitsetFixed & mtcore::BitsetFixed< NumBits >::operator<<= ( const size_t amount)
inline

Definition at line 1070 of file bitset.hpp.

1070 {
1071 const auto blockShift = amount / 64;
1072 const auto bitShift = amount % 64;
1073 if (blockShift > bits.len) {
1074 set_all(false);
1075 }
1076 else {
1077 for (size_t i = 0; i < bits.len - blockShift; ++i) {
1078 const auto finalIndex = bits.len - i - 1;
1079 const auto sourceIndex = bits.len - i - 1 - blockShift;
1081 }
1082 for (size_t i = 0; i < blockShift; ++i) {
1083 bits[i] = 0;
1084 }
1085
1087 if (bitShift) {
1088 const u64 keepMask = fullMask >> bitShift;
1089 const u64 carryMask = ~keepMask;
1090
1091 u64 carry = 0;
1092 for (size_t i = 0; i < bits.len; ++i) {
1093 const auto newCarry = (bits[i] & carryMask) >> (64 - bitShift);
1094 bits[i] = ((bits[i] & keepMask) << bitShift) | carry;
1095 carry = newCarry;
1096 }
1097 }
1098
1099 const u64 finalMask = fullMask >> (NumBits % 64);
1100 bits[bits.len - 1] &= finalMask;
1101 }
1102 return *this;
1103 }
void set_all(const bool value)
Sets all bits to a specific value.
Definition bitset.hpp:1056
Here is the call graph for this function:

◆ operator>>=()

template<size_t NumBits = 64>
BitsetFixed & mtcore::BitsetFixed< NumBits >::operator>>= ( const size_t amount)
inline

Definition at line 1105 of file bitset.hpp.

1105 {
1106 const auto blockShift = amount / 64;
1107 const auto bitShift = amount % 64;
1108 if (blockShift > bits.len) {
1109 set_all(false);
1110 }
1111 else {
1112 for (size_t i = 0; i < bits.len - blockShift; ++i) {
1113 const auto finalIndex = i;
1114 const auto sourceIndex = i + blockShift;
1116 }
1117 for (size_t i = bits.len - blockShift; i < bits.len; ++i) {
1118 bits[i] = 0;
1119 }
1120
1122 if (bitShift) {
1123 const u64 keepMask = fullMask << bitShift;
1124 const u64 carryMask = ~keepMask;
1125
1126 u64 carry = 0;
1127 for (size_t i = 0; i < bits.len; ++i) {
1128 const auto newCarry = (bits[i] & carryMask) << (64 - bitShift);
1129 bits[i] = ((bits[i] & keepMask) >> bitShift) | carry;
1130 carry = newCarry;
1131 }
1132 }
1133
1134 const u64 finalMask = fullMask << (NumBits % 64);
1135 bits[bits.len - 1] &= finalMask;
1136 }
1137 return *this;
1138 }
Here is the call graph for this function:

◆ operator[]() [1/2]

template<size_t NumBits = 64>
BitsetAccess mtcore::BitsetFixed< NumBits >::operator[] ( const size_t index)
inlinenodiscard

Access an individual bit at a specific position.

Parameters
indexBit index to access
Returns
Wrapper for reading/setting bit

Definition at line 889 of file bitset.hpp.

889 {
890 ensure(index < NumBits, "OUT OF BOUNDS ACCESS");
891 return {.pos = index, .bs = *this};
892 }

◆ operator[]() [2/2]

template<size_t NumBits = 64>
bool mtcore::BitsetFixed< NumBits >::operator[] ( const size_t index) const
inlinenodiscard

Access an individual bit at a specific position.

Parameters
indexBit index to access
Returns
Wrapper for reading/setting bit

Definition at line 899 of file bitset.hpp.

899{ return at(index); }
bool at(const size_t pos) const
Reads a bit at a specific position.
Definition bitset.hpp:912
Here is the call graph for this function:

◆ operator^=()

template<size_t NumBits = 64>
BitsetFixed & mtcore::BitsetFixed< NumBits >::operator^= ( const BitsetFixed< NumBits > & other)
inline

Definition at line 1045 of file bitset.hpp.

1045 {
1046 for (size_t i = 0; i < other.bits.len && i < bits.len; ++i) {
1047 bits[i] ^= other.bits[i];
1048 }
1049 return *this;
1050 }

◆ operator|=()

template<size_t NumBits = 64>
BitsetFixed & mtcore::BitsetFixed< NumBits >::operator|= ( const BitsetFixed< NumBits > & other)
inline

Definition at line 1038 of file bitset.hpp.

1038 {
1039 for (size_t i = 0; i < other.bits.len && i < bits.len; ++i) {
1040 bits[i] |= other.bits[i];
1041 }
1042 return *this;
1043 }

◆ pop_count()

template<size_t NumBits = 64>
size_t mtcore::BitsetFixed< NumBits >::pop_count ( ) const
inlinenodiscard

Counts the number of set bits in the bitset.

Returns
count of set bits

Definition at line 987 of file bitset.hpp.

987 {
988 size_t count = 0;
989 for (size_t i = 0; i < bits.len; ++i) {
991 }
992 return count;
993 }

◆ set()

template<size_t NumBits = 64>
BitsetFixed & mtcore::BitsetFixed< NumBits >::set ( const size_t pos,
const bool val )
inline

Sets a bit at a position to a specific value.

Parameters
posBit index to set
valBit value to set to

Definition at line 925 of file bitset.hpp.

925 {
926 ensure(pos < NumBits, "OUT OF BOUNDS ACCESS");
927 const u64 block = pos / 64;
928 const u64 bit = pos % 64;
929 ensure(bit + block * 64 == pos, 'BAD POSITION DECONSTRUCT');
930 const u64 bitMask = static_cast<u64>(0x1) << bit;
931 if (val) {
932 bits[block] |= bitMask;
933 }
934 else {
935 bits[block] &= ~bitMask;
936 }
937 return *this;
938 }
Here is the caller graph for this function:

◆ set_all()

template<size_t NumBits = 64>
void mtcore::BitsetFixed< NumBits >::set_all ( const bool value)
inline

Sets all bits to a specific value.

Parameters
valueto set to

Definition at line 1056 of file bitset.hpp.

1056 {
1058
1059 // For the first n 64-bit segments, just set them all
1060 for (size_t i = 0; i < bits.len - 1; ++i) {
1061 bits[i] = mask;
1062 }
1063
1064 // For the last segment, just set what we have allocated
1065 for (size_t i = (bits.len - 1) * 64; i < size(); ++i) {
1066 set(i, value);
1067 }
1068 }
constexpr size_t size() const
Gets the size of the bitset.
Definition bitset.hpp:905
Here is the call graph for this function:
Here is the caller graph for this function:

◆ set_bits()

template<size_t NumBits = 64>
SetBitIter mtcore::BitsetFixed< NumBits >::set_bits ( ) const
inlinenodiscard

Iterates over the indices of all set bits in the bitset.

Returns
an iterator over all set bits

Definition at line 1025 of file bitset.hpp.

1025{ return SetBitIter{*this, bits[0], 0}; }
Simple bit set iterator that uses next() iteration to return the indices of all set bits.
Definition bitset.hpp:999

◆ size()

template<size_t NumBits = 64>
size_t mtcore::BitsetFixed< NumBits >::size ( ) const
inlinenodiscardconstexpr

Gets the size of the bitset.

Returns
number of bits in bitset (not number of bytes allocated)

Definition at line 905 of file bitset.hpp.

905{ return NumBits; }
Here is the caller graph for this function:

◆ toggle()

template<size_t NumBits = 64>
Bitset & mtcore::BitsetFixed< NumBits >::toggle ( const size_t pos)
inline

Toggles a bit at a specific position.

Parameters
posBit index to toggle
Returns
a reference to the current bitset

Definition at line 945 of file bitset.hpp.

945 {
946 ensure(pos < NumBits, "OUT OF BOUNDS ACCESS");
947 const u64 block = pos / 64;
948 const u64 bit = pos % 64;
949 const u64 bitMask = 0x1 << bit;
950 bits[block] ^= bitMask;
951 return *this;
952 }

Member Data Documentation

◆ bits

template<size_t NumBits = 64>
Slice<u64> mtcore::BitsetFixed< NumBits >::bits = mut_slice_from(bytes)

Definition at line 828 of file bitset.hpp.

◆ bytes

template<size_t NumBits = 64>
std::array<u64, (NumBits + 63) / 64> mtcore::BitsetFixed< NumBits >::bytes = {0}

Definition at line 827 of file bitset.hpp.

827{0};

The documentation for this struct was generated from the following file: