UDocumentation UE5.7 10.02.2026 (Source)
API documentation for Unreal Engine 5.7
BitStack.h
Go to the documentation of this file.
1// Copyright Epic Games, Inc. All Rights Reserved.
2
3#pragma once
4
5#if (defined(__AUTORTFM) && __AUTORTFM)
6
8#include "Stack.h"
9#include "Utils.h"
10
11#include <cstddef>
12#include <cstdint>
13
14namespace AutoRTFM
15{
16
17// A dynamically sized stack of bits.
18//
19// Notes:
20// * Heap allocated memory is not automatically freed when popping elements.
21// Only calling Reset() or destructing the stack will free heap allocated
22// memory.
23// * This class is not relocatable and so is not safe to use in UE's containers
24// which require elements to be relocatable.
25//
26// Template parameters:
27// InlineCapacity - the number of elements that can be held before spilling to
28// the heap.
29// Validation - if Disabled, do not perform validity assertions.
30template<size_t InlineCapacity, EContainerValidation Validation = EContainerValidation::Enabled>
31class TBitStack
32{
33 using WordType = uint64_t;
34 static constexpr size_t NumWordBits = 64;
35 static_assert(NumWordBits == sizeof(WordType) * 8);
36
37public:
38 // A reference to a single bit in the stack.
39 // Becomes invalid if the stack holding the bit is modified.
40 class FBitRef
41 {
42 public:
43 // Constructor
44 FBitRef(WordType& Word, WordType Mask) : Word(Word), Mask(Mask) {}
45
46 // Returns true if the bit is set.
47 operator bool() const
48 {
49 return (Word & Mask) != 0;
50 }
51
52 // Copy assignment operator.
53 // Changes the value of the referenced bit in the stack.
54 FBitRef& operator = (const FBitRef& Other)
55 {
56 return *this = static_cast<bool>(Other);
57 }
58
59 // Assignment operator.
60 // Changes the value of the referenced bit in the stack.
61 FBitRef& operator = (bool Value)
62 {
63 Word = Value ? (Word | Mask) : (Word & ~Mask);
64 return *this;
65 }
66
67 private:
68 WordType& Word;
69 const WordType Mask;
70 };
71
72 // Constructor.
73 TBitStack() = default;
74 // Copy constructor.
75 TBitStack(const TBitStack& Other) = default;
76 // Move constructor.
77 TBitStack(TBitStack&& Other) : Words{std::move(Other.Words)}, Count{Other.Count}
78 {
79 if (&Other != this)
80 {
81 Other.Count = 0;
82 }
83 }
84 // Destructor.
85 ~TBitStack() = default;
86 // Copy assignment operator.
87 TBitStack& operator=(const TBitStack& Other) = default;
88 // Move assignment operator.
89 TBitStack& operator=(TBitStack&& Other)
90 {
91 if (&Other != this)
92 {
93 Words = std::move(Other.Words);
94 Count = Other.Count;
95 Other.Count = 0;
96 }
97 return *this;
98 }
99
100 // Clears all the items from the stack, preserving the capacity.
101 void Clear()
102 {
103 Words.Clear();
104 Count = 0;
105 }
106
107 // Clears all the items from the stack, freeing all heap allocations and
108 // resetting the capacity to InlineCapacity
109 void Reset()
110 {
111 Words.Reset();
112 Count = 0;
113 }
114
115 // Pushes a new bit on to the stack.
116 inline void Push(bool Bit)
117 {
118 const WordType WordBitIndex = Count & (NumWordBits - 1);
119 if (WordBitIndex == 0)
120 {
121 Words.Push(Bit ? 1 : 0);
122 }
123 else
124 {
125 WordType& Word = Words.Back();
126 WordType Mask = static_cast<WordType>(1) << WordBitIndex;
127 Word = Bit ? (Word | Mask) : (Word & ~Mask);
128 }
129 ++Count;
130 AUTORTFM_ASSERT(Validation == EContainerValidation::Disabled || NumWordsFor(Count) == Words.Num());
131 }
132
133 // Removes the last item on the stack.
134 inline bool Pop()
135 {
136 AUTORTFM_ASSERT(Validation == EContainerValidation::Disabled || Count > 0);
137 --Count;
138 const WordType WordBitIndex = Count & (NumWordBits - 1);
139 const WordType Word = Words.Back();
140 const bool Value = ((Word >> WordBitIndex) & 1) != 0;
141 if (WordBitIndex == 0)
142 {
143 Words.Pop();
144 }
145 AUTORTFM_ASSERT(Validation == EContainerValidation::Disabled || NumWordsFor(Count) == Words.Num());
146 return Value;
147 }
148
149 // Reserves memory for NewCapacity bits.
150 inline void Reserve(size_t NewCapacity)
151 {
152 Words.Reserve(NumWordsFor(NewCapacity));
153 }
154
155 // Returns the number of bits held by the stack.
156 inline size_t Num() const { return Count; }
157
158 // Returns true if the stack holds no bits.
159 inline bool IsEmpty() const { return Count == 0; }
160
161 // Index operator.
162 // Returns a reference to the bit with the given index in the stack.
163 FBitRef operator[](size_t Index)
164 {
165 AUTORTFM_ASSERT(Validation == EContainerValidation::Disabled || Index < Count);
166 WordType& Word = Words[Index / NumWordBits];
167 WordType Mask = static_cast<WordType>(1) << (Index & (NumWordBits-1));
168 return FBitRef{Word, Mask};
169 }
170
171 // Constant index operator.
172 // Returns true if the bit with the given index is set.
173 bool operator[](size_t Index) const
174 {
175 AUTORTFM_ASSERT(Validation == EContainerValidation::Disabled || Index < Count);
176 WordType Word = Words[Index / NumWordBits];
177 WordType Mask = static_cast<WordType>(1) << (Index & (NumWordBits-1));
178 return (Word & Mask) != 0;
179 }
180
181private:
182 static constexpr size_t NumWordsFor(size_t NumBits)
183 {
184 return (NumBits + (NumWordBits-1)) / NumWordBits;
185 }
186
187 TStack<WordType, NumWordsFor(InlineCapacity), Validation> Words;
188 size_t Count = 0; // In bits
189};
190
191}
192
193#endif // (defined(__AUTORTFM) && __AUTORTFM)
UE_FORCEINLINE_HINT TSharedRef< CastToType, Mode > StaticCastSharedRef(TSharedRef< CastFromType, Mode > const &InSharedRef)
Definition SharedPointer.h:127
@ Num
Definition MetalRHIPrivate.h:234
const bool
Definition NetworkReplayStreaming.h:178
Definition API.cpp:57
U16 Index
Definition radfft.cpp:71