UDocumentation UE5.7 10.02.2026 (Source)
API documentation for Unreal Engine 5.7
SparseBitSet.h
Go to the documentation of this file.
1// Copyright Epic Games, Inc. All Rights Reserved.
2
3#pragma once
4
5#include "CoreTypes.h"
7#include "Containers/Array.h"
8
9namespace UE::MovieScene
10{
11
12template<typename T, int32 InlineSize>
13struct TDynamicSparseBitSetBucketStorage;
14
15template<typename T>
16struct TFixedSparseBitSetBucketStorage;
17
18template<typename HashType, typename BucketStorage = TDynamicSparseBitSetBucketStorage<uint8, 4>>
19struct TFixedSparseBitSet;
20
21template<typename HashType, typename BucketStorage = TDynamicSparseBitSetBucketStorage<uint8, 4>>
22struct TDynamicSparseBitSet;
23
25{
28};
29
30namespace Private
31{
32 static uint32 CountTrailingZeros(uint8 In)
33 {
34 const uint32 X = 0xFFFFFF00 | uint32(In);
35 return FMath::CountTrailingZeros(X);
36 }
37 static uint32 CountTrailingZeros(uint16 In)
38 {
39 const uint32 X = 0xFFFF0000 | uint32(In);
40 return FMath::CountTrailingZeros(X);
41 }
42 static uint32 CountTrailingZeros(uint32 In)
43 {
44 return FMath::CountTrailingZeros(In);
45 }
46 static uint32 CountTrailingZeros(uint64 In)
47 {
48 return static_cast<uint32>(FMath::CountTrailingZeros64(In));
49 }
50
52 template<typename T, typename U>
53 static T BitOffsetToLowBitMask(U BitOffset)
54 {
55 constexpr T One(1);
56 const T Index = static_cast<T>(BitOffset);
57 return (One << Index)-One;
58 }
59
61 template<typename T, typename U>
62 static T BitOffsetToHighBitMask(U BitOffset)
63 {
64 return ~BitOffsetToLowBitMask<T>(BitOffset);
65 }
66}
67
78template<typename HashType, typename BucketStorage>
80{
81 using BucketType = typename BucketStorage::BucketType;
82 static constexpr uint32 HashSize = sizeof(HashType)*8;
83 static constexpr uint32 BucketSize = sizeof(typename BucketStorage::BucketType)*8;
84 static constexpr uint32 MaxNumBits = HashSize * BucketSize;
85
87 : BucketHash(0)
88 {}
89
90 template<typename ...StorageArgs>
91 explicit TFixedSparseBitSet(StorageArgs&& ...Storage)
92 : Buckets(Forward<StorageArgs>(Storage)...)
93 , BucketHash(0)
94 {}
95
98
101
102 template<typename OtherHashType, typename OtherStorageType>
104 {
105 static_assert(TFixedSparseBitSet<OtherHashType, OtherStorageType>::BucketSize == BucketSize, "Cannot copy sparse bitsets of different bucket sizes");
106
107 // Copy the buckets
108 const uint32 NumBuckets = FMath::CountBits(Other.BucketHash);
109 Other.Buckets.SetNum(NumBuckets);
111 }
112
114 template<typename OtherHashType, typename OtherStorageType>
116 {
117 static_assert(TFixedSparseBitSet<OtherHashType, OtherStorageType>::BucketSize == BucketSize, "Cannot copy sparse bitsets of different bucket sizes");
118
119 const uint32 ThisNumBuckets = this->NumBuckets();
120 checkf(OtherBucketCapacity >= ThisNumBuckets, TEXT("Attempting to copy a sparse bitset without enough capacity in the destination (%d, required %d)"), OtherBucketCapacity, ThisNumBuckets);
121
122 // Copy the hash
123 Other.BucketHash = this->BucketHash;
124
125 // Copy the buckets
126 FMemory::Memcpy(Other.Buckets.GetData(), this->Buckets.Storage.GetData(), sizeof(typename BucketStorage::BucketType)*ThisNumBuckets);
127 }
128
130 {
131 using namespace Private;
132
133 HashType One(1u);
134 HashType NewHash = Other.BucketHash | BucketHash;
135 HashType OtherHash = Other.BucketHash;
136
138 uint32 OtherBucketBitIndex = Private::CountTrailingZeros(OtherHash);
139
141 {
142 const HashType HashBit = HashType(1) << OtherBucketBitIndex;
143 const uint32 ThisBucketIndex = FMath::CountBits(BucketHash & (HashBit-1));
144
145 if ((BucketHash & HashBit) == 0)
146 {
147 Buckets.Insert(Other.Buckets.Get(OtherBucketIndex), ThisBucketIndex);
148 }
149 else
150 {
151 Buckets.Get(ThisBucketIndex) |= Other.Buckets.Get(OtherBucketIndex);
152 }
153
154 BucketHash |= HashBit;
155
157
158 // Mask out this bit and find the index of the next one
160 OtherBucketBitIndex = Private::CountTrailingZeros(OtherHash);
161 }
162
163 return *this;
164 }
165
170 {
171 return FMath::CountBits(this->BucketHash);
172 }
173
175 {
176 uint32 Total = 0;
178 for (uint32 Index = 0; Index < TotalNumBuckets; ++Index)
179 {
180 Total += FMath::CountBits(Buckets.Get(Index));
181 }
182 return Total;
183 }
184
186 {
187 return MaxNumBits;
188 }
189
190 bool IsEmpty() const
191 {
192 return this->BucketHash == 0;
193 }
194
202 {
203 CheckIndex(BitIndex);
204
205 FBitOffsets Offsets(BucketHash, BitIndex);
206
207 // Do we need to add a new bucket?
208 if ( (BucketHash & Offsets.HashBit) == 0)
209 {
210 BucketHash |= Offsets.HashBit;
211 Buckets.Insert(Offsets.BitMaskWithinBucket, Offsets.BucketIndex);
213 }
214 else if ((Buckets.Get(Offsets.BucketIndex) & Offsets.BitMaskWithinBucket) == 0)
215 {
216 Buckets.Get(Offsets.BucketIndex) |= Offsets.BitMaskWithinBucket;
218 }
219
221 }
222
226 bool IsBitSet(uint32 BitIndex) const
227 {
228 CheckIndex(BitIndex);
229
230 const uint32 Hash = BitIndex / BucketSize;
231 const HashType HashBit = (HashType(1) << Hash);
232 if (BucketHash & HashBit)
233 {
234 const uint32 BucketIndex = FMath::CountBits(BucketHash & (HashBit-1));
235 const uint32 ThisBitIndex = (BitIndex-BucketSize*Hash);
237
238 return Buckets.Get(BucketIndex) & ThisBitMask;
239 }
240 return false;
241 }
242
247 {
248 CheckIndex(BitIndex);
249
250 const uint32 Hash = BitIndex / BucketSize;
251 const HashType HashBit = (HashType(1) << Hash);
252 if (BucketHash & HashBit)
253 {
254 uint32 BucketIndex = FMath::CountBits(BucketHash & (HashBit-1));
255
256 const uint32 ThisBitIndex = (BitIndex-BucketSize*Hash);
257 const BucketType ThisBitMask = static_cast<BucketType>(BucketType(1u) << ThisBitIndex);
258
259 BucketType ThisBucket = Buckets.Get(BucketIndex);
261 {
262 // Compute the offset
263 int32 SparseIndex = FMath::CountBits(ThisBucket & (ThisBitMask-1));
264
265 // Count all the preceding buckets to find the final sparse index
266 while (BucketIndex > 0)
267 {
268 --BucketIndex;
269 SparseIndex += FMath::CountBits(Buckets.Get(BucketIndex));
270 }
271 return SparseIndex;
272 }
273 }
274 return INDEX_NONE;
275 }
276
278 {
280 : BitSet(nullptr)
281 , BucketBitIndex(0)
282 , IndexWithinBucket(0)
283 , CurrentBucket(0)
284 {
285 }
286
288 {
289 FIterator It;
290 It.BitSet = InBitSet;
291 It.CurrentBucket = 0;
292
293 if (InBitSet->BucketHash != 0)
294 {
295 It.BucketBitIndex = Private::CountTrailingZeros(InBitSet->BucketHash);
296 It.CurrentBucket = InBitSet->Buckets.Get(0);
297 It.IndexWithinBucket = Private::CountTrailingZeros(It.CurrentBucket);
298 }
299 else
300 {
301 It.BucketBitIndex = HashSize;
302 It.IndexWithinBucket = 0;
303 }
304 return It;
305 }
307 {
308 FIterator It;
309 It.BitSet = InBitSet;
310 It.CurrentBucket = 0;
311 It.BucketBitIndex = HashSize;
312 It.IndexWithinBucket = 0;
313 return It;
314 }
315
317 {
318 using namespace Private;
319
320 // Clear the lowest 1 bit
321 CurrentBucket = CurrentBucket & (CurrentBucket - 1);
322
323 if (CurrentBucket != 0)
324 {
325 IndexWithinBucket = CountTrailingZeros(CurrentBucket);
326 }
327 else
328 {
329 // If this was the last bit, reset the iterator to end()
330 if (BucketBitIndex == HashSize-1)
331 {
332 IndexWithinBucket = 0;
333 BucketBitIndex = HashSize;
334 return;
335 }
336
337 HashType UnvisitedBucketBitMask = BitOffsetToHighBitMask<HashType>(BucketBitIndex+1);
338 BucketBitIndex = CountTrailingZeros(HashType(BitSet->BucketHash & UnvisitedBucketBitMask));
339
340 // Check whether we're at the end
341 if (BucketBitIndex == HashSize)
342 {
343 IndexWithinBucket = 0;
344 }
345 else
346 {
347 const uint8 NextBucketIndex = FMath::CountBits(BitSet->BucketHash & BitOffsetToLowBitMask<HashType>(BucketBitIndex));
348 CurrentBucket = BitSet->Buckets.Get(NextBucketIndex);
349 IndexWithinBucket = CountTrailingZeros(CurrentBucket);
350 }
351 }
352 }
353
355 {
356 return BucketSize*BucketBitIndex + IndexWithinBucket;
357 }
358
359 explicit operator bool() const
360 {
361 return BucketBitIndex < HashSize;
362 }
363
364 friend bool operator==(const FIterator& A, const FIterator& B)
365 {
366 return A.BitSet == B.BitSet && A.BucketBitIndex == B.BucketBitIndex && A.IndexWithinBucket == B.IndexWithinBucket;
367 }
368 friend bool operator!=(const FIterator& A, const FIterator& B)
369 {
370 return !(A == B);
371 }
372private:
373
375 uint8 BucketBitIndex;
376 uint8 IndexWithinBucket;
377
378 BucketType CurrentBucket;
379 };
380
383
384private:
385
386 template<typename, typename>
387 friend struct TFixedSparseBitSet;
388
389 inline void CheckIndex(uint32 BitIndex) const
390 {
391 checkfSlow(BitIndex < MaxNumBits, TEXT("Invalid index (%d) specified for a sparse bitset of maximum size (%d)"), BitIndex, MaxNumBits);
392 }
393
394 struct FBitOffsets
395 {
396 HashType HashBit;
397 BucketType BitMaskWithinBucket;
398 int32 BucketIndex;
399 FBitOffsets(HashType InBucketHash, uint32 BitIndex)
400 {
401 const HashType Hash(BitIndex / BucketSize);
402 HashBit = HashType(1) << Hash;
403
404 BucketIndex = FMath::CountBits(InBucketHash & (HashBit-1u));
405
406 const uint32 ThisBitIndex = (BitIndex-BucketSize*Hash);
407 BitMaskWithinBucket = BucketType(1u) << ThisBitIndex;
408 }
409 };
410
411 BucketStorage Buckets;
412 HashType BucketHash;
413};
414
415
416
417template<typename T, int32 InlineSize = 8>
419{
420 using BucketType = T;
421
423
424 void Insert(BucketType InitialValue, int32 Index)
425 {
426 Storage.Insert(InitialValue, Index);
427 }
428
429 BucketType* GetData() { return Storage.GetData(); }
430
432 BucketType Get(int32 Index) const { return Storage[Index]; }
433};
434
435template<typename T>
437{
438 using BucketType = T;
439
441
442 void Insert(BucketType InitialValue, int32 Index)
443 {
444 Storage.Insert(InitialValue, Index);
445 }
446
447 BucketType* GetData() { return Storage.GetData(); }
448
450 BucketType Get(int32 Index) const { return Storage[Index]; }
451};
452
453template<typename T>
479
486template<typename HashType, typename BucketStorage>
488{
493 {
494 return MAX_uint32;
495 }
496
497
505 {
506 const uint32 Bucket = Bit / NumBitsInBucket;
507
508 Bit -= Bucket*NumBitsInBucket;
509
510 FEntry* EntrPtr = Entries.GetData();
511
512 const int32 Num = Entries.Num();
513 for (int32 EntryIndex = 0; EntryIndex < Num; ++EntryIndex)
514 {
515 if (EntrPtr[EntryIndex].Offset == Bucket)
516 {
517 return EntrPtr[EntryIndex].Bits.SetBit(Bit);
518 }
519 else if (EntrPtr[EntryIndex].Offset > Bucket)
520 {
521 Entries.InsertUninitialized(EntryIndex);
522 new(&Entries[EntryIndex]) FEntry(Bucket, Bit);
524 }
525 }
526
527 Entries.Emplace(Bucket, Bit);
529 }
530
531
535 bool IsEmpty() const
536 {
537 return Entries.Num() == 0;
538 }
539
540
544 bool IsBitSet(uint32 Bit) const
545 {
546 const uint32 Bucket = Bit / NumBitsInBucket;
547
548 const FEntry* EntrPtr = Entries.GetData();
549
550 const int32 Num = Entries.Num();
551 for (int32 EntryIndex = 0; EntryIndex < Num; ++EntryIndex)
552 {
553 if (EntrPtr[EntryIndex].Offset == Bucket)
554 {
555 return EntrPtr[EntryIndex].Bits.IsBitSet(Bit);
556 }
557 if (EntrPtr[EntryIndex].Offset > Bucket)
558 {
559 return false;
560 }
561 }
562
563 return false;
564 }
565
570 {
571 uint32 SetBits = 0;
572 for (const FEntry& Entry : Entries)
573 {
574 SetBits += Entry.Bits.CountSetBits();
575 }
576 return SetBits;
577 }
578
579
581 {
582 if (Other.Entries.Num() == 0)
583 {
584 return *this;
585 }
586
587 if (Entries.Num() == 0)
588 {
589 *this = Other;
590 return *this;
591 }
592
593
594 int32 ThisIndex = 0;
595 int32 OtherIndex = 0;
596
597 while (OtherIndex < Other.Entries.Num() && Other.Entries[OtherIndex].Offset < Entries[0].Offset)
598 {
599 ++OtherIndex;
600 }
601
602 if (OtherIndex > 0)
603 {
604 Entries.Insert(Other.Entries.GetData(), OtherIndex, 0);
605 }
606
607 while (OtherIndex < Other.Entries.Num() && ThisIndex < Entries.Num())
608 {
609 if (Other.Entries[OtherIndex].Offset < Entries[ThisIndex].Offset)
610 {
611 Entries.Insert(Other.Entries[OtherIndex], ThisIndex);
612 ++OtherIndex;
613 }
614 else if (Other.Entries[OtherIndex].Offset == Entries[ThisIndex].Offset)
615 {
616 Entries[ThisIndex].Bits |= Other.Entries[OtherIndex].Bits;
617 ++OtherIndex;
618 ++ThisIndex;
619 }
620 else
621 {
622 ++ThisIndex;
623 }
624 }
625
626 return *this;
627 }
628
629
630private:
631
633
634 static constexpr uint32 NumBitsInBucket = FBucketBitSet::MaxNumBits;
635
636 struct FEntry
637 {
638 FEntry(uint32 InOffset)
639 : Offset(InOffset)
640 {
641 }
642 FEntry(uint32 InOffset, uint32 InBit)
643 : Offset(InOffset)
644 {
646 Bits.SetBit(InBit);
647 }
648
649 FBucketBitSet Bits;
650 uint32 Offset;
651 };
652
653public:
654
656 {
658 {
659 FIterator It;
660 It.Entries = InBitSet->Entries.GetData();
661 It.NumEntries = InBitSet->Entries.Num();
662 It.EntryIndex = 0;
663 It.CurrentOffsetInBits = 0;
664
665 if (It.NumEntries != 0)
666 {
667 It.CurrentOffsetInBits = It.Entries[0].Offset * NumBitsInBucket;
668 It.BucketIt = BucketIterator::Begin(&It.Entries[0].Bits);
669 }
670 return It;
671 }
673 {
674 FIterator It;
675 It.Entries = InBitSet->Entries.GetData();
676 It.NumEntries = InBitSet->Entries.Num();
677 It.EntryIndex = It.NumEntries;
678 It.CurrentOffsetInBits = 0;
679 return It;
680 }
681
683 {
684 using namespace Private;
685
686 ++BucketIt;
687 if (!BucketIt)
688 {
689 ++EntryIndex;
690 if (EntryIndex < NumEntries)
691 {
692 CurrentOffsetInBits = Entries[EntryIndex].Offset * NumBitsInBucket;
693 BucketIt = BucketIterator::Begin(&Entries[EntryIndex].Bits);
694 }
695 else
696 {
697 CurrentOffsetInBits = 0;
698 BucketIt = BucketIterator();
699 }
700 }
701 }
702
704 {
705 return CurrentOffsetInBits + *BucketIt;
706 }
707
708 explicit operator bool() const
709 {
710 return EntryIndex < NumEntries;
711 }
712
713 friend bool operator==(const FIterator& A, const FIterator& B)
714 {
715 return A.Entries == B.Entries && A.EntryIndex == B.EntryIndex && A.BucketIt == B.BucketIt;
716 }
717 friend bool operator!=(const FIterator& A, const FIterator& B)
718 {
719 return !(A == B);
720 }
721private:
722 FIterator() = default;
723
724 using BucketIterator = typename TFixedSparseBitSet<HashType, BucketStorage>::FIterator;
725
727 BucketIterator BucketIt;
728 int32 NumEntries;
729 int32 EntryIndex;
730 int32 CurrentOffsetInBits;
731 };
732
735
737};
738
739} // namespace UE::MovieScene
#define checkSlow(expr)
Definition AssertionMacros.h:332
#define checkfSlow(expr, format,...)
Definition AssertionMacros.h:333
#define checkf(expr, format,...)
Definition AssertionMacros.h:315
@ INDEX_NONE
Definition CoreMiscDefines.h:150
#define TEXT(x)
Definition Platform.h:1272
FPlatformTypes::int32 int32
A 32-bit signed integer.
Definition Platform.h:1125
FPlatformTypes::uint64 uint64
A 64-bit unsigned integer.
Definition Platform.h:1117
UE_FORCEINLINE_HINT TSharedRef< CastToType, Mode > StaticCastSharedRef(TSharedRef< CastFromType, Mode > const &InSharedRef)
Definition SharedPointer.h:127
#define X(Name, Desc)
Definition FormatStringSan.h:47
@ Num
Definition MetalRHIPrivate.h:234
const bool
Definition NetworkReplayStreaming.h:178
#define MAX_uint32
Definition NumericLimits.h:21
@ One
Definition PropertyPathHelpersTest.h:16
uint32 Offset
Definition VulkanMemory.cpp:4033
uint8_t uint8
Definition binka_ue_file_header.h:8
uint16_t uint16
Definition binka_ue_file_header.h:7
uint32_t uint32
Definition binka_ue_file_header.h:6
Definition Array.h:670
UE_REWRITE SizeType Num() const
Definition Array.h:1144
UE_NODEBUG UE_FORCEINLINE_HINT void InsertUninitialized(SizeType Index)
Definition Array.h:1782
UE_NODEBUG UE_FORCEINLINE_HINT ElementType * GetData() UE_LIFETIMEBOUND
Definition Array.h:1027
UE_FORCEINLINE_HINT SizeType Emplace(ArgsType &&... Args)
Definition Array.h:2561
SizeType Insert(std::initializer_list< ElementType > InitList, const SizeType InIndex)
Definition Array.h:1875
Definition OverriddenPropertySet.cpp:45
Definition ConstraintsManager.h:14
ESparseBitSetBitResult
Definition SparseBitSet.h:25
U16 Index
Definition radfft.cpp:71
static UE_FORCEINLINE_HINT void * Memcpy(void *Dest, const void *Src, SIZE_T Count)
Definition UnrealMemory.h:160
void Insert(BucketType InitialValue, int32 Index)
Definition SparseBitSet.h:442
BucketType Get(int32 Index) const
Definition SparseBitSet.h:450
BucketType * GetData()
Definition SparseBitSet.h:447
BucketType & Get(int32 Index)
Definition SparseBitSet.h:449
TArray< BucketType > Storage
Definition SparseBitSet.h:440
T BucketType
Definition SparseBitSet.h:420
BucketType * GetData()
Definition SparseBitSet.h:429
void Insert(BucketType InitialValue, int32 Index)
Definition SparseBitSet.h:424
BucketType & Get(int32 Index)
Definition SparseBitSet.h:431
BucketType Get(int32 Index) const
Definition SparseBitSet.h:432
TArray< BucketType, TInlineAllocator< InlineSize > > Storage
Definition SparseBitSet.h:422
friend bool operator!=(const FIterator &A, const FIterator &B)
Definition SparseBitSet.h:717
static FIterator Begin(const TDynamicSparseBitSet< HashType, BucketStorage > *InBitSet)
Definition SparseBitSet.h:657
friend bool operator==(const FIterator &A, const FIterator &B)
Definition SparseBitSet.h:713
static FIterator End(const TDynamicSparseBitSet< HashType, BucketStorage > *InBitSet)
Definition SparseBitSet.h:672
int32 operator*() const
Definition SparseBitSet.h:703
void operator++()
Definition SparseBitSet.h:682
Definition SparseBitSet.h:488
bool IsEmpty() const
Definition SparseBitSet.h:535
TDynamicSparseBitSet< HashType, BucketStorage > & operator|=(const TDynamicSparseBitSet< HashType, BucketStorage > &Other)
Definition SparseBitSet.h:580
uint32 CountSetBits() const
Definition SparseBitSet.h:569
bool IsBitSet(uint32 Bit) const
Definition SparseBitSet.h:544
ESparseBitSetBitResult SetBit(uint32 Bit)
Definition SparseBitSet.h:504
friend FIterator end(const TDynamicSparseBitSet< HashType, BucketStorage > &In)
Definition SparseBitSet.h:734
uint32 GetMaxNumBits() const
Definition SparseBitSet.h:492
TArray< FEntry > Entries
Definition SparseBitSet.h:736
friend FIterator begin(const TDynamicSparseBitSet< HashType, BucketStorage > &In)
Definition SparseBitSet.h:733
TFixedSparseBitSetBucketStorage(TFixedSparseBitSetBucketStorage &&)=delete
BucketType Get(int32 Index) const
Definition SparseBitSet.h:477
BucketType * GetData()
Definition SparseBitSet.h:474
BucketType * Storage
Definition SparseBitSet.h:472
TFixedSparseBitSetBucketStorage()
Definition SparseBitSet.h:458
T BucketType
Definition SparseBitSet.h:456
void operator=(TFixedSparseBitSetBucketStorage &&)=delete
void operator=(const TFixedSparseBitSetBucketStorage &)=delete
TFixedSparseBitSetBucketStorage(BucketType *StoragePtr)
Definition SparseBitSet.h:462
TFixedSparseBitSetBucketStorage(const TFixedSparseBitSetBucketStorage &)=delete
BucketType & Get(int32 Index)
Definition SparseBitSet.h:476
friend bool operator!=(const FIterator &A, const FIterator &B)
Definition SparseBitSet.h:368
static FIterator End(const TFixedSparseBitSet< HashType, BucketStorage > *InBitSet)
Definition SparseBitSet.h:306
FIterator()
Definition SparseBitSet.h:279
static FIterator Begin(const TFixedSparseBitSet< HashType, BucketStorage > *InBitSet)
Definition SparseBitSet.h:287
friend bool operator==(const FIterator &A, const FIterator &B)
Definition SparseBitSet.h:364
void operator++()
Definition SparseBitSet.h:316
int32 operator*() const
Definition SparseBitSet.h:354
Definition SparseBitSet.h:80
uint32 GetMaxNumBits() const
Definition SparseBitSet.h:185
static constexpr uint32 HashSize
Definition SparseBitSet.h:82
TFixedSparseBitSet & operator=(TFixedSparseBitSet &&)=default
TFixedSparseBitSet(const TFixedSparseBitSet &)=default
bool IsBitSet(uint32 BitIndex) const
Definition SparseBitSet.h:226
friend FIterator begin(const TFixedSparseBitSet< HashType, BucketStorage > &In)
Definition SparseBitSet.h:381
static constexpr uint32 MaxNumBits
Definition SparseBitSet.h:84
bool IsEmpty() const
Definition SparseBitSet.h:190
void CopyToUnsafe(TFixedSparseBitSet< OtherHashType, OtherStorageType > &Other, uint32 OtherBucketCapacity) const
Definition SparseBitSet.h:115
friend FIterator end(const TFixedSparseBitSet< HashType, BucketStorage > &In)
Definition SparseBitSet.h:382
uint32 CountSetBits() const
Definition SparseBitSet.h:174
typename BucketStorage::BucketType BucketType
Definition SparseBitSet.h:81
static constexpr uint32 BucketSize
Definition SparseBitSet.h:83
TFixedSparseBitSet & operator|=(const TFixedSparseBitSet &Other)
Definition SparseBitSet.h:129
TFixedSparseBitSet & operator=(const TFixedSparseBitSet &)=default
TFixedSparseBitSet(TFixedSparseBitSet &&)=default
TFixedSparseBitSet(StorageArgs &&...Storage)
Definition SparseBitSet.h:91
ESparseBitSetBitResult SetBit(uint32 BitIndex)
Definition SparseBitSet.h:201
TFixedSparseBitSet()
Definition SparseBitSet.h:86
void CopyTo(TFixedSparseBitSet< OtherHashType, OtherStorageType > &Other) const
Definition SparseBitSet.h:103
uint32 NumBuckets() const
Definition SparseBitSet.h:169
int32 GetSparseBucketIndex(uint32 BitIndex) const
Definition SparseBitSet.h:246