UDocumentation UE5.7 10.02.2026 (Source)
API documentation for Unreal Engine 5.7
StaticBitArray.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 "HAL/UnrealMemory.h"
10
12template<typename T>
14{
15public:
16
18 : Data(InData)
19 , Mask(InMask)
20 {
21 }
22
23 [[nodiscard]] UE_FORCEINLINE_HINT operator bool() const
24 {
25 return (Data & Mask) != 0;
26 }
27 inline void operator=(const bool NewValue)
28 {
29 if(NewValue)
30 {
31 Data |= Mask;
32 }
33 else
34 {
35 Data &= ~Mask;
36 }
37 }
38
39private:
40
41 T& Data;
42 T Mask;
43};
44
45
47template<typename T>
49{
50public:
51
53 : Data(InData)
54 , Mask(InMask)
55 {
56 }
57
58 [[nodiscard]] UE_FORCEINLINE_HINT operator bool() const
59 {
60 return (Data & Mask) != 0;
61 }
62
63private:
64
65 const T& Data;
66 T Mask;
67};
68
69
73template<uint32 NumBits>
75{
76 typedef uint64 WordType;
77
78 struct FBoolType;
79 typedef int32* FBoolType::* UnspecifiedBoolType;
80 typedef float* FBoolType::* UnspecifiedZeroType;
81
82public:
83
86 {
87 Clear_();
88 }
89
91 UE_DEPRECATED(5.4, "Implicitly constructing a TStaticBitArray from 0 has been deprecated - please use the default constructor instead")
93 {
94 Clear_();
95 }
96
101 {
102 /***********************************************************************
103
104 If this line fails to compile you are attempting to construct a bit
105 array with an out-of bounds bit index. Follow the compiler errors to
106 the initialization point
107
108 ***********************************************************************/
109// static_assert(InBitIndex >= 0 && InBitIndex < NumBits, "Invalid bit value.");
110
111 check((NumBits > 0) ? (InBitIndex<NumBits):1);
112
113 uint32 DestWordIndex = InBitIndex / NumBitsPerWord;
114 WordType Word = (WordType)1 << (InBitIndex & (NumBitsPerWord - 1));
115
116 for(int32 WordIndex = 0; WordIndex < NumWords; ++WordIndex)
117 {
118 Words[WordIndex] = WordIndex == DestWordIndex ? Word : (WordType)0;
119 }
120 }
121
125 [[nodiscard]] explicit TStaticBitArray(const FString& Str)
126 {
127 int32 Length = Str.Len();
128
129 // Trim count to length of bit array
130 if(NumBits < Length)
131 {
132 Length = NumBits;
133 }
134 Clear_();
135
136 int32 Pos = Length;
137 for(int32 Index = 0; Index < Length; ++Index)
138 {
139 const TCHAR ch = Str[--Pos];
140 if(ch == TEXT('1'))
141 {
142 operator[](Index) = true;
143 }
144 else if(ch != TEXT('0'))
145 {
146 ErrorInvalid_();
147 }
148 }
149 }
150
151 [[nodiscard]] inline bool HasAnyBitsSet() const
152 {
153 WordType And = 0;
154 for(int32 Index = 0; Index < NumWords; ++Index)
155 {
156 And |= Words[Index];
157 }
158
159 return And != 0;
160 }
161
162 // Explicit conversion to bool
163 [[nodiscard]] UE_FORCEINLINE_HINT explicit operator bool() const
164 {
165 return this->HasAnyBitsSet();
166 }
167
168 // Accessors.
170 {
171 return NumBits;
172 }
174 {
175 check(Index>=0 && Index<NumBits);
177 Words[Index / NumBitsPerWord],
178 (WordType)1 << (Index & (NumBitsPerWord - 1))
179 );
180 }
182 {
183 check(Index>=0 && Index<NumBits);
185 Words[Index / NumBitsPerWord],
186 (WordType)1 << (Index & (NumBitsPerWord - 1))
187 );
188 }
189
190 // Modifiers.
192 {
193 for(int32 Index = 0; Index < NumWords; ++Index)
194 {
195 Words[Index] |= Other.Words[Index];
196 }
197 return *this;
198 }
200 {
201 for(int32 Index = 0; Index < NumWords; ++Index)
202 {
203 Words[Index] &= Other.Words[Index];
204 }
205 return *this;
206 }
208 {
209 for(int32 Index = 0; Index < NumWords; ++Index)
210 {
211 Words[Index] ^= Other.Words[Index];
212 }
213 return *this;
214 }
216 {
217 TStaticBitArray Result;
218 for(int32 Index = 0; Index < NumWords; ++Index)
219 {
220 Result.Words[Index] = ~A.Words[Index];
221 }
222 Result.Trim_();
223 return Result;
224 }
226 {
227 // is not calling |= because doing it in here has less LoadHitStores and is therefore faster.
228 TStaticBitArray Results(0);
229
230 const WordType* RESTRICT APtr = (const WordType* RESTRICT)A.Words;
231 const WordType* RESTRICT BPtr = (const WordType* RESTRICT)B.Words;
232 WordType* RESTRICT ResultsPtr = (WordType* RESTRICT)Results.Words;
233 for(int32 Index = 0; Index < NumWords; ++Index)
234 {
236 }
237
238 return Results;
239 }
241 {
242 // is not calling &= because doing it in here has less LoadHitStores and is therefore faster.
243 TStaticBitArray Results(0);
244
245 const WordType* RESTRICT APtr = (const WordType* RESTRICT)A.Words;
246 const WordType* RESTRICT BPtr = (const WordType* RESTRICT)B.Words;
247 WordType* RESTRICT ResultsPtr = (WordType* RESTRICT)Results.Words;
248 for(int32 Index = 0; Index < NumWords; ++Index)
249 {
251 }
252
253 return Results;
254 }
256 {
257 TStaticBitArray Results(A);
258 Results ^= B;
259 return Results;
260 }
261 [[nodiscard]] inline bool operator==(const TStaticBitArray<NumBits>& B) const
262 {
263 for(int32 Index = 0; Index < NumWords; ++Index)
264 {
265 if(Words[Index] != B.Words[Index])
266 {
267 return false;
268 }
269 }
270 return true;
271 }
273 UE_DEPRECATED(5.4, "Comparing a TStaticBitArray to zero has been deprecated - please use !BitArray.HasAnyBitsSet() instead")
274 [[nodiscard]] friend UE_FORCEINLINE_HINT bool operator==(const TStaticBitArray<NumBits>& A, UnspecifiedBoolType Value)
275 {
276 return (UnspecifiedBoolType)A == Value;
277 }
280 {
281 return !(*this == B);
282 }
284 UE_DEPRECATED(5.4, "Comparing a TStaticBitArray to zero has been deprecated - please use BitArray.HasAnyBitsSet() instead")
285 [[nodiscard]] friend UE_FORCEINLINE_HINT bool operator!=(const TStaticBitArray<NumBits>& A, UnspecifiedBoolType Value)
286 {
287 return !(A == Value);
288 }
289
295 {
296 const int32 LocalNumBits = NumBits;
297
298 int32 WordIndex = 0;
299 // Iterate over the array until we see a word with a unset bit.
300 while (WordIndex < NumWords && Words[WordIndex] == WordType(-1))
301 {
302 ++WordIndex;
303 }
304
305 if (WordIndex < NumWords)
306 {
307 // Flip the bits, then we only need to find the first one bit -- easy.
308 const WordType Bits = ~(Words[WordIndex]);
309 UE_ASSUME(Bits != 0);
310
311 const int32 LowestBitIndex = (int32)FMath::CountTrailingZeros64(Bits) + (WordIndex << NumBitsPerWordLog2);
313 {
314 return LowestBitIndex;
315 }
316 }
317
318 return INDEX_NONE;
319 }
320
326 {
327 const int32 LocalNumBits = NumBits;
328
329 int32 WordIndex = 0;
330 // Iterate over the array until we see a word with a set bit.
331 while (WordIndex < NumWords && Words[WordIndex] == WordType(0))
332 {
333 ++WordIndex;
334 }
335
336 if (WordIndex < NumWords)
337 {
338 const WordType Bits = Words[WordIndex];
339 UE_ASSUME(Bits != 0);
340
341 const int32 LowestBitIndex = (int32)FMath::CountTrailingZeros64(Bits) + (WordIndex << NumBitsPerWordLog2);
343 {
344 return LowestBitIndex;
345 }
346 }
347
348 return INDEX_NONE;
349 }
350
354 [[nodiscard]] FString ToString() const
355 {
356 FString Str;
357 Str.Empty(NumBits);
358
359 for(int32 Index = NumBits - 1; Index >= 0; --Index)
360 {
361 Str += operator[](Index) ? TEXT('1') : TEXT('0');
362 }
363
364 return Str;
365 }
366
368 {
369 uint32 ArchivedNumWords = NumWords;
370 Ar << ArchivedNumWords;
371
372 if (Ar.IsLoading())
373 {
374 FMemory::Memset(Words, 0, sizeof(Words));
375 ArchivedNumWords = FMath::Min(NumWords, ArchivedNumWords);
376 }
377
378 Ar.Serialize(Words, ArchivedNumWords * sizeof(Words[0]));
379 }
380
384 void Fill(bool Value)
385 {
386 FMemory::Memset(Words, Value ? 0xFF : 0x00, sizeof(Words));
387 }
388
389 static constexpr uint32 NumOfBits = NumBits;
390
391private:
392 static constexpr uint32 NumBitsPerWord = sizeof(WordType) * 8;
393 static constexpr uint32 NumBitsPerWordLog2 = 6;
394 static_assert(NumBitsPerWord == (1u << NumBitsPerWordLog2), "Update NumBitsPerWordLog2 to reflect WordType");
395 static constexpr uint32 NumWords = ((NumBits + NumBitsPerWord - 1) & ~(NumBitsPerWord - 1)) / NumBitsPerWord;
396 WordType Words[NumWords];
397
398 // Helper class for bool conversion
399 struct FBoolType
400 {
401 int32* Valid;
402 };
403
407 inline void Clear_()
408 {
409 for(int32 Index = 0; Index < NumWords; ++Index)
410 {
411 Words[Index] = 0;
412 }
413 }
414
418 void Trim_()
419 {
420 constexpr uint32 NumOverflowBits = NumBits % NumBitsPerWord; //-V1064 The 'NumBits' operand of the modulo operation is less than the 'NumBitsPerWord' operand. The result is always equal to the left operand.
421 if constexpr (NumOverflowBits != 0)
422 {
423 Words[NumWords-1] &= (WordType(1) << NumOverflowBits) - 1;
424 }
425 }
426
430 void ErrorInvalid_() const
431 {
432 LowLevelFatalError(TEXT("invalid TStaticBitArray<NumBits> character"));
433 }
434};
435
439template<uint32 NumBits>
441{
442 BitArray.Serialize(Ar);
443 return Ar;
444}
@ Valid
Definition AndroidInputInterface.h:103
#define check(expr)
Definition AssertionMacros.h:314
#define LowLevelFatalError(Format,...)
Definition AssertionMacros.h:554
@ INDEX_NONE
Definition CoreMiscDefines.h:150
#define UE_DEPRECATED(Version, Message)
Definition CoreMiscDefines.h:302
#define TEXT(x)
Definition Platform.h:1272
FPlatformTypes::TCHAR TCHAR
Either ANSICHAR or WIDECHAR, depending on whether the platform supports wide characters or the requir...
Definition Platform.h:1135
#define UE_ASSUME(x)
Definition Platform.h:833
FPlatformTypes::int32 int32
A 32-bit signed integer.
Definition Platform.h:1125
#define UE_FORCEINLINE_HINT
Definition Platform.h:723
#define RESTRICT
Definition Platform.h:706
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
const bool
Definition NetworkReplayStreaming.h:178
FArchive & operator<<(FArchive &Ar, TStaticBitArray< NumBits > &BitArray)
Definition StaticBitArray.h:440
uint32_t uint32
Definition binka_ue_file_header.h:6
Definition Archive.h:1208
virtual void Serialize(void *V, int64 Length)
Definition Archive.h:1689
UE_FORCEINLINE_HINT bool IsLoading() const
Definition Archive.h:236
Definition StaticBitArray.h:49
TConstStaticBitReference(const T &InData, T InMask)
Definition StaticBitArray.h:52
Definition StaticBitArray.h:75
UE_FORCEINLINE_HINT TStaticBitArray(UnspecifiedZeroType)
Definition StaticBitArray.h:92
UE_FORCEINLINE_HINT bool operator!=(const TStaticBitArray< NumBits > &B) const
Definition StaticBitArray.h:279
void Serialize(FArchive &Ar)
Definition StaticBitArray.h:367
friend UE_FORCEINLINE_HINT bool operator!=(const TStaticBitArray< NumBits > &A, UnspecifiedBoolType Value)
Definition StaticBitArray.h:285
friend TStaticBitArray< NumBits > operator^(const TStaticBitArray< NumBits > &A, const TStaticBitArray< NumBits > &B)
Definition StaticBitArray.h:255
TStaticBitArray & operator|=(const TStaticBitArray &Other)
Definition StaticBitArray.h:191
TStaticBitArray & operator&=(const TStaticBitArray &Other)
Definition StaticBitArray.h:199
TStaticBitArray(bool, uint32 InBitIndex)
Definition StaticBitArray.h:100
TStaticBitReference< WordType > operator[](int32 Index)
Definition StaticBitArray.h:173
friend UE_FORCEINLINE_HINT bool operator==(const TStaticBitArray< NumBits > &A, UnspecifiedBoolType Value)
Definition StaticBitArray.h:274
static UE_FORCEINLINE_HINT int32 Num()
Definition StaticBitArray.h:169
void Fill(bool Value)
Definition StaticBitArray.h:384
int32 FindFirstSetBit() const
Definition StaticBitArray.h:325
UE_FORCEINLINE_HINT TStaticBitArray()
Definition StaticBitArray.h:85
friend TStaticBitArray< NumBits > operator&(const TStaticBitArray< NumBits > &A, const TStaticBitArray< NumBits > &B)
Definition StaticBitArray.h:240
bool operator==(const TStaticBitArray< NumBits > &B) const
Definition StaticBitArray.h:261
friend TStaticBitArray< NumBits > operator|(const TStaticBitArray< NumBits > &A, const TStaticBitArray< NumBits > &B)
Definition StaticBitArray.h:225
friend TStaticBitArray< NumBits > operator~(const TStaticBitArray< NumBits > &A)
Definition StaticBitArray.h:215
const TConstStaticBitReference< WordType > operator[](int32 Index) const
Definition StaticBitArray.h:181
FString ToString() const
Definition StaticBitArray.h:354
TStaticBitArray(const FString &Str)
Definition StaticBitArray.h:125
static constexpr uint32 NumOfBits
Definition StaticBitArray.h:389
bool HasAnyBitsSet() const
Definition StaticBitArray.h:151
int32 FindFirstClearBit() const
Definition StaticBitArray.h:294
TStaticBitArray & operator^=(const TStaticBitArray &Other)
Definition StaticBitArray.h:207
Definition StaticBitArray.h:14
void operator=(const bool NewValue)
Definition StaticBitArray.h:27
TStaticBitReference(T &InData, T InMask)
Definition StaticBitArray.h:17
U16 Index
Definition radfft.cpp:71
static UE_FORCEINLINE_HINT void * Memset(void *Dest, uint8 Char, SIZE_T Count)
Definition UnrealMemory.h:119