7#include "MRPch/MRBindingMacros.h"
26 using block_type = Uint64;
27 inline static constexpr size_t bits_per_block =
sizeof( block_type ) * 8;
28 inline static constexpr size_t npos = (size_t)-1;
30 using size_type = size_t;
31 using IndexType = size_t;
34 BitSet() noexcept = default;
37 explicit
BitSet(
size_t numBits,
bool fillValue = false ) {
resize( numBits, fillValue ); }
40 static BitSet fromBlocks( std::vector<block_type> && blocks )
43 res.blocks_ = std::move( blocks );
44 res.numBits_ = res.blocks_.size() * bits_per_block;
48 void reserve( size_type numBits ) { blocks_.reserve( calcNumBlocks_( numBits ) ); }
50 void clear() { numBits_ = 0; blocks_.clear(); }
51 void shrink_to_fit() { blocks_.shrink_to_fit(); }
53 [[nodiscard]]
bool empty() const noexcept {
return numBits_ == 0; }
54 [[nodiscard]] size_type size() const noexcept {
return numBits_; }
55 [[nodiscard]] size_type num_blocks() const noexcept {
return blocks_.size(); }
56 [[nodiscard]] size_type capacity() const noexcept {
return blocks_.capacity() * bits_per_block; }
58 [[nodiscard]]
bool uncheckedTest( IndexType n )
const { assert( n < size() );
return blocks_[blockIndex_( n )] & bitMask_( n ); }
59 [[nodiscard]]
bool uncheckedTestSet( IndexType n,
bool val =
true ) { assert( n < size() );
bool b = uncheckedTest( n );
if ( b != val )
set( n, val );
return b; }
62 [[nodiscard]]
bool test( IndexType n )
const {
return n < size() && uncheckedTest( n ); }
63 [[nodiscard]]
bool test_set( IndexType n,
bool val =
true ) {
return ( val || n < size() ) ?
uncheckedTestSet( n, val ) : false; }
67 BitSet &
set( IndexType n ) { assert( n < size() ); blocks_[blockIndex_( n )] |= bitMask_( n );
return *
this; }
71 BitSet &
reset( IndexType n ) {
if ( n < size() ) blocks_[blockIndex_( n )] &= ~bitMask_( n );
return *
this; }
75 BitSet &
flip( IndexType n ) { assert( n < size() ); blocks_[blockIndex_( n )] ^= bitMask_( n );
return *
this; }
82 void push_back(
bool val ) {
auto n = numBits_++;
if ( bitIndex_( n ) == 0 ) blocks_.push_back( block_type{} );
set( n, val ); }
85 void pop_back() { assert( numBits_ > 0 ); {
if ( bitIndex_( numBits_ ) == 1 ) blocks_.pop_back();
else reset( numBits_ - 1 ); } --numBits_; }
88 [[nodiscard]]
const auto & bits()
const {
return blocks_; }
105 [[nodiscard]]
bool none()
const {
return !any(); }
108 [[nodiscard]]
MRMESH_API size_type count() const noexcept;
111 [[nodiscard]] IndexType find_first()
const {
return findSetBitAfter_( 0 ); }
114 [[nodiscard]] IndexType find_next( IndexType n )
const {
return findSetBitAfter_( n + 1 ); }
117 [[nodiscard]]
MRMESH_API IndexType find_last()
const;
120 [[nodiscard]]
MRMESH_API size_t nthSetBit(
size_t n )
const;
131 auto reserved = capacity();
132 if ( reserved > 0 && newSize > reserved )
134 while ( newSize > reserved )
142 void autoResizeSet(
size_t pos, size_type len,
bool val =
true )
144 if ( pos + len > size() )
146 set( pos, len, val );
153 bool const b = test( pos );
160 [[nodiscard]]
size_t heapBytes()
const {
return capacity() / 8; }
163 [[nodiscard]] IndexType backId()
const { assert( !empty() );
return IndexType{ size() - 1 }; }
166 [[nodiscard]]
static IndexType beginId() {
return IndexType{ 0 }; }
167 [[nodiscard]] IndexType endId()
const {
return IndexType{ size() }; }
171 [[nodiscard]]
static size_type calcNumBlocks_( size_type numBits )
noexcept {
return ( numBits + bits_per_block - 1 ) / bits_per_block; }
174 [[nodiscard]]
static size_type blockIndex_( IndexType n )
noexcept {
return n / bits_per_block; }
177 [[nodiscard]]
static size_type bitIndex_( IndexType n )
noexcept {
return n % bits_per_block; }
180 [[nodiscard]]
static block_type bitMask_( IndexType n )
noexcept {
return block_type( 1 ) << bitIndex_( n ); }
183 [[nodiscard]]
static block_type bitMask_( IndexType firstBit, IndexType lastBit )
noexcept
185 return ( ( block_type( 1 ) << firstBit ) - 1 )
187 ( lastBit == bits_per_block ? ~block_type{} : ( ( block_type( 1 ) << lastBit ) - 1 ) );
199 template<
class FullBlock,
class PartialBlock>
200 BitSet & rangeOp_( IndexType n, size_type len, FullBlock&&, PartialBlock&& );
203 MRMESH_API IndexType findSetBitAfter_( IndexType n )
const;
205 MRMESH_API friend std::ostream& operator<<( std::ostream& s,
const BitSet & bs );
209 std::vector<block_type> blocks_;
210 size_type numBits_ = 0;
240 [[nodiscard]]
bool test_set(
IndexType n,
bool val =
true ) {
return base::test_set( n, val ); }
272 template <
typename M>
281 template <
typename M>
300 return bs.heapBytes();
307 {
return static_cast<const BitSet &
>( a ) ==
static_cast<const BitSet &
>( b ); }
309template <
typename T,
typename U>
315 std::function<bool( I )> res;
317 res = [bitset]( I id ) {
return bitset->
test(
id ); };
328 return id.valid() && ( !bitset || bitset->
test(
id ) );
334 return id.valid() && bitset.
test(
id );
354 : bitset_( &bitset ), index_( bitset.find_first() )
359 index_ = bitset_->find_next( index_ );
369 [[nodiscard]]
const T *
bitset()
const {
return bitset_; }
375 const T * bitset_ =
nullptr;
376 IndexType index_ = IndexType( ~
size_t( 0 ) );
382[[nodiscard]] MR_BIND_IGNORE
inline auto end(
const BitSet & )
419 for (
auto b : *this )
420 if (
auto mapped = map( b ) )
433 for (
auto b : *this )
434 if (
auto mapped = map( b ) )
constexpr bool operator==(ImVec2 a, ImVec2 b)
Definition MRImGuiVectorOperators.h:117
constexpr auto operator*(A a, B b)
Definition MRImGuiVectorOperators.h:107
#define MRMESH_API
Definition MRMeshFwd.h:80
Definition MRMesh/MRBitSet.h:24
unsafe void autoResizeSet(ulong pos, ulong len, bool? val=null)
unsafe void resize(ulong numBits, bool? fillValue=null)
unsafe bool autoResizeTestSet(ulong pos, bool? val=null)
unsafe void reserve(ulong numBits)
unsafe void resizeWithReserve(ulong newSize)
unsafe MR.BitSet subtract(MR.Const_BitSet b, int bShiftInBlocks)
unsafe bool uncheckedTestSet(ulong n, bool? val=null)
iterator to enumerate all indices with set bits in BitSet class or its derivatives
Definition MRMesh/MRBitSet.h:340
SetBitIteratorT operator++(int)
Definition MRMesh/MRBitSet.h:362
const IndexType * pointer
Definition MRMesh/MRBitSet.h:348
SetBitIteratorT()=default
constructs end iterator
std::forward_iterator_tag iterator_category
Definition MRMesh/MRBitSet.h:344
const T * bitset() const
Definition MRMesh/MRBitSet.h:369
IndexType value_type
Definition MRMesh/MRBitSet.h:345
const IndexType reference
intentionally not a reference
Definition MRMesh/MRBitSet.h:347
typename T::IndexType IndexType
Definition MRMesh/MRBitSet.h:342
SetBitIteratorT & operator++()
Definition MRMesh/MRBitSet.h:357
SetBitIteratorT(const T &bitset)
constructs begin iterator
Definition MRMesh/MRBitSet.h:353
std::ptrdiff_t difference_type
Definition MRMesh/MRBitSet.h:346
Definition MRMesh/MRBitSet.h:217
IndexType find_last() const
Definition MRMesh/MRBitSet.h:244
TypedBitSet & operator|=(const TypedBitSet &b)
Definition MRMesh/MRBitSet.h:249
bool intersects(const TypedBitSet &a) const
returns true if, there is a bit which is set in this bitset, such that the corresponding bit in bitse...
Definition MRMesh/MRBitSet.h:265
bool test_set(IndexType n, bool val=true)
Definition MRMesh/MRBitSet.h:240
TypedBitSet getMapping(const HashMap< IndexType, IndexType > &map) const
Definition MRMesh/MRBitSet.h:278
friend TypedBitSet operator|(const TypedBitSet &a, const TypedBitSet &b)
Definition MRMesh/MRBitSet.h:254
friend TypedBitSet operator&(const TypedBitSet &a, const TypedBitSet &b)
Definition MRMesh/MRBitSet.h:253
static IndexType beginId()
[beginId(), endId()) is the range of all bits in the set
Definition MRMesh/MRBitSet.h:292
TypedBitSet(const BitSet &src)
copies all bits from another BitSet (or a descending class, e.g. TypedBitSet)
Definition MRMesh/MRBitSet.h:224
TypedBitSet & flip(IndexType n)
Definition MRMesh/MRBitSet.h:237
IndexType backId() const
returns the identifier of the back() element
Definition MRMesh/MRBitSet.h:289
TypedBitSet getMapping(const HashMap< IndexType, IndexType > &map, size_t resSize) const
Definition MRMesh/MRBitSet.h:285
TypedBitSet & operator-=(const TypedBitSet &b)
Definition MRMesh/MRBitSet.h:251
TypedBitSet & set(IndexType n, size_type len, bool val)
Definition MRMesh/MRBitSet.h:229
bool is_subset_of(const TypedBitSet &a) const
returns true if, for every bit that is set in this bitset, the corresponding bit in bitset a is also ...
Definition MRMesh/MRBitSet.h:262
TypedBitSet & reset(IndexType n, size_type len)
Definition MRMesh/MRBitSet.h:233
friend TypedBitSet operator-(const TypedBitSet &a, const TypedBitSet &b)
Definition MRMesh/MRBitSet.h:256
TypedBitSet & operator^=(const TypedBitSet &b)
Definition MRMesh/MRBitSet.h:250
TypedBitSet & set()
Definition MRMesh/MRBitSet.h:232
void autoResizeSet(IndexType pos, size_type len, bool val=true)
Definition MRMesh/MRBitSet.h:267
IndexType endId() const
Definition MRMesh/MRBitSet.h:293
I IndexType
Definition MRMesh/MRBitSet.h:221
TypedBitSet & flip()
Definition MRMesh/MRBitSet.h:238
TypedBitSet getMapping(const Vector< IndexType, IndexType > &map, size_t resSize) const
Definition MRMesh/MRBitSet.h:283
IndexType find_first() const
Definition MRMesh/MRBitSet.h:242
friend TypedBitSet operator^(const TypedBitSet &a, const TypedBitSet &b)
Definition MRMesh/MRBitSet.h:255
TypedBitSet & set(IndexType n, bool val)
Definition MRMesh/MRBitSet.h:230
TypedBitSet & flip(IndexType n, size_type len)
Definition MRMesh/MRBitSet.h:236
TypedBitSet & operator&=(const TypedBitSet &b)
Definition MRMesh/MRBitSet.h:248
TypedBitSet getMapping(const M &map, size_t resSize) const
this is a faster version if the result size is known beforehand
void autoResizeSet(IndexType pos, bool val=true)
Definition MRMesh/MRBitSet.h:268
IndexType find_next(IndexType pos) const
Definition MRMesh/MRBitSet.h:243
TypedBitSet & reset()
Definition MRMesh/MRBitSet.h:235
bool autoResizeTestSet(IndexType pos, bool val=true)
Definition MRMesh/MRBitSet.h:269
TypedBitSet(BitSet &&src)
moves all bits from another BitSet (or a descending class, e.g. TypedBitSet)
Definition MRMesh/MRBitSet.h:227
TypedBitSet & set(IndexType n)
Definition MRMesh/MRBitSet.h:231
TypedBitSet & subtract(const TypedBitSet &b, int bShiftInBlocks)
subtracts b from this, considering that bits in b are shifted right on bShiftInBlocks*bits_per_block
Definition MRMesh/MRBitSet.h:259
TypedBitSet getMapping(const Vector< IndexType, IndexType > &map) const
Definition MRMesh/MRBitSet.h:274
TypedBitSet & reset(IndexType n)
Definition MRMesh/MRBitSet.h:234
TypedBitSet getMapping(const M &map) const
constructs another bit set from this where every set bit index is transformed using given map
IndexType nthSetBit(size_t n) const
returns the location of nth set bit (where the first bit corresponds to n=0) or IndexType(npos) if th...
Definition MRMesh/MRBitSet.h:246
bool test(IndexType n) const
Definition MRMesh/MRBitSet.h:239
TypedBitSet getMapping(const BMap< IndexType, IndexType > &map) const
Definition MRMesh/MRBitSet.h:276
std::vector<T>-like container that requires specific indexing type,
Definition MRVector.h:19
BitSet operator-(const BitSet &a, const BitSet &b)
Definition MRMesh/MRBitSet.h:442
MR_BIND_IGNORE auto begin(const BitSet &a)
Definition MRMesh/MRBitSet.h:380
HashMap< I, int > makeHashMapWithSeqNums(const TypedBitSet< I > &bs)
creates a HashMap where for each set bit of input bitset its sequential number starting from 0 is ret...
Definition MRMesh/MRBitSet.h:405
MRMESH_API bool operator==(const BitSet &a, const BitSet &b)
compare that two bit sets have the same set bits (they can be equal even if sizes are distinct but la...
BitSet operator&(const BitSet &a, const BitSet &b)
Definition MRMesh/MRBitSet.h:439
Vector< int, I > makeVectorWithSeqNums(const TypedBitSet< I > &bs)
creates a Vector where for each set bit of input bitset its sequential number starting from 0 is retu...
Definition MRMesh/MRBitSet.h:394
bool contains(const TypedBitSet< I > *bitset, I id)
Definition MRMesh/MRBitSet.h:326
BitSet operator|(const BitSet &a, const BitSet &b)
Definition MRMesh/MRBitSet.h:440
MR_BIND_IGNORE auto end(const BitSet &)
Definition MRMesh/MRBitSet.h:382
std::function< bool(I)> makePredicate(const TypedBitSet< I > *bitset)
Definition MRMesh/MRBitSet.h:313
BitSet operator^(const BitSet &a, const BitSet &b)
Definition MRMesh/MRBitSet.h:441
size_t heapBytes(const BitSet &bs)
returns the amount of memory given BitSet occupies on heap
Definition MRMesh/MRBitSet.h:298
Definition MRCameraOrientationPlugin.h:8
T getAt(const Buffer< T, I > &bmap, I key, T def={})
given some buffer map and a key, returns the value associated with the key, or default value if key i...
Definition MRBuffer.h:119
flat map: I -> T
Definition MRBuffer.h:143
Buffer< T, I > b
Definition MRBuffer.h:144
size_t tsize
target size, all values inside b must be less than this value
Definition MRBuffer.h:145