UDocumentation UE5.7 10.02.2026 (Source)
API documentation for Unreal Engine 5.7
Union.h
Go to the documentation of this file.
1// Copyright Epic Games, Inc. All Rights Reserved.
2
3#pragma once
4
8
9
10//
11// Macros that can be used to specify multiple template parameters in a macro parameter.
12// This is necessary to prevent the macro parsing from interpreting the template parameter
13// delimiting comma as a macro parameter delimiter.
14//
15
16#define TEMPLATE_PARAMETERS2(X,Y) X,Y
17
18namespace uLang {
19
21template<uint32_t>
23{
25};
26
27
28class FNull
29{
30public:
31
32 bool operator==(const FNull&) const
33 {
34 return true;
35 }
36
37 bool operator!=(const FNull&) const
38 {
39 return false;
40 }
41};
42
43
49template<typename TypeA, typename TypeB = FNull, typename TypeC = FNull, typename TypeD = FNull, typename TypeE = FNull, typename TypeF = FNull>
50class TUnion
51{
52public:
53
55 TUnion() //-V730
56 : CurrentSubtypeIndex(uint8_t(-1))
57 { }
58
65
72
79
86
93
100
103 : CurrentSubtypeIndex(uint8_t(-1))
104 {
105 *this = Other;
106 }
107
110 {
111 // Destruct any subtype value the union may have.
112 Reset();
113 }
114
116 template<typename Subtype>
117 bool HasSubtype() const
118 {
119 // Determine the subtype's index and reference.
121 const Subtype* SubtypeValuePointer;
123
124 return CurrentSubtypeIndex == SubtypeIndex;
125 }
126
128 template<typename Subtype>
130 {
131 // Determine the subtype's index and reference.
133 Subtype* SubtypeValuePointer;
135
136 // Only reset the value if it is of the specified subtype.
137 if (CurrentSubtypeIndex == SubtypeIndex)
138 {
139 CurrentSubtypeIndex = uint8_t(-1);
140
141 // Destruct the subtype.
142 SubtypeValuePointer->~Subtype();
143 }
144 }
145
147 template<typename Subtype>
148 const Subtype& GetSubtype() const
149 {
150 // Determine the subtype's index and reference.
152 const Subtype* SubtypeValuePointer;
154
155 // Validate that the union has a value of the requested subtype.
156 ULANG_ASSERTF(CurrentSubtypeIndex == SubtypeIndex, "Union is not of this type");
157
158 return *SubtypeValuePointer;
159 }
160
162 template<typename Subtype>
163 Subtype& GetSubtype()
164 {
165 // Determine the subtype's index and reference.
167 Subtype* SubtypeValuePointer;
169
170 // Validate that the union has a value of the requested subtype.
171 ULANG_ASSERTF(CurrentSubtypeIndex == SubtypeIndex, "Union is not of this type");
172
173 return *SubtypeValuePointer;
174 }
175
177 template<typename Subtype>
178 Subtype* SetSubtype(typename TCallTraits<Subtype>::ParamType NewValue)
179 {
181 Subtype* SubtypeValuePointer;
183
184 Reset();
185
186 new(SubtypeValuePointer) Subtype(NewValue);
187
188 CurrentSubtypeIndex = (uint8_t)SubtypeIndex;
189 return SubtypeValuePointer;
190 }
191
194 {
195 return CurrentSubtypeIndex;
196 }
197
199 void Reset()
200 {
201 switch (CurrentSubtypeIndex)
202 {
203 case uint8_t(-1): break;
204 case 0: ResetSubtype<TypeA>(); break;
205 case 1: ResetSubtype<TypeB>(); break;
206 case 2: ResetSubtype<TypeC>(); break;
207 case 3: ResetSubtype<TypeD>(); break;
208 case 4: ResetSubtype<TypeE>(); break;
209 case 5: ResetSubtype<TypeF>(); break;
210 default: FatalErrorUndefinedSubtype(); break;
211 };
212 }
213
215 {
216 // Copy the value of the appropriate subtype from the other union
217 switch (Other.CurrentSubtypeIndex)
218 {
219 case uint8_t(-1): break;
220 case 0: SetSubtype<TypeA>(Other.GetSubtype<TypeA>()); break;
221 case 1: SetSubtype<TypeB>(Other.GetSubtype<TypeB>()); break;
222 case 2: SetSubtype<TypeC>(Other.GetSubtype<TypeC>()); break;
223 case 3: SetSubtype<TypeD>(Other.GetSubtype<TypeD>()); break;
224 case 4: SetSubtype<TypeE>(Other.GetSubtype<TypeE>()); break;
225 case 5: SetSubtype<TypeF>(Other.GetSubtype<TypeF>()); break;
226 default: FatalErrorUndefinedSubtype(); break;
227 };
228
229 return *this;
230 }
231
233 bool operator==(const TUnion& Other) const
234 {
235 if (CurrentSubtypeIndex == Other.CurrentSubtypeIndex)
236 {
237 switch (CurrentSubtypeIndex)
238 {
239 case uint8_t(-1): return true;
240 case 0: return GetSubtype<TypeA>() == Other.GetSubtype<TypeA>(); break;
241 case 1: return GetSubtype<TypeB>() == Other.GetSubtype<TypeB>(); break;
242 case 2: return GetSubtype<TypeC>() == Other.GetSubtype<TypeC>(); break;
243 case 3: return GetSubtype<TypeD>() == Other.GetSubtype<TypeD>(); break;
244 case 4: return GetSubtype<TypeE>() == Other.GetSubtype<TypeE>(); break;
245 case 5: return GetSubtype<TypeF>() == Other.GetSubtype<TypeF>(); break;
246 default: FatalErrorUndefinedSubtype(); break;
247 };
248 }
249
250 return false;
251 }
252
253private:
254
256 union
257 {
264 } Values;
265
267 uint8_t CurrentSubtypeIndex;
268
270 template<typename Subtype>
271 Subtype& InitSubtype()
272 {
273 Subtype* NewSubtype = &GetSubtype<Subtype>();
274 return *new(NewSubtype) Subtype;
275 }
276
278 template<typename Subtype, typename PointerType>
279 static void GetSubtypeIndexAndReference(
280 const TUnion& Union,
281 int32_t& OutIndex,
282 PointerType& OutValuePointer
283 )
284 {
286 {
287 OutIndex = 0;
288 OutValuePointer = (PointerType)&Union.Values.A;
289 }
291 {
292 OutIndex = 1;
293 OutValuePointer = (PointerType)&Union.Values.B;
294 }
296 {
297 OutIndex = 2;
298 OutValuePointer = (PointerType)&Union.Values.C;
299 }
301 {
302 OutIndex = 3;
303 OutValuePointer = (PointerType)&Union.Values.D;
304 }
306 {
307 OutIndex = 4;
308 OutValuePointer = (PointerType)&Union.Values.E;
309 }
311 {
312 OutIndex = 5;
313 OutValuePointer = (PointerType)&Union.Values.F;
314 }
315 else
316 {
317 static_assert(
318 TAreTypesEqual<TEMPLATE_PARAMETERS2(TypeA, Subtype)>::Value ||
319 TAreTypesEqual<TEMPLATE_PARAMETERS2(TypeB, Subtype)>::Value ||
320 TAreTypesEqual<TEMPLATE_PARAMETERS2(TypeC, Subtype)>::Value ||
321 TAreTypesEqual<TEMPLATE_PARAMETERS2(TypeD, Subtype)>::Value ||
322 TAreTypesEqual<TEMPLATE_PARAMETERS2(TypeE, Subtype)>::Value ||
323 TAreTypesEqual<TEMPLATE_PARAMETERS2(TypeF, Subtype)>::Value,
324 "Type is not subtype of union.");
325 OutIndex = uint8_t(-1);
327 }
328 }
329
330 static void FatalErrorUndefinedSubtype()
331 {
332 ULANG_ERRORF("Unrecognized TUnion subtype");
333 }
334};
335
336
337}
#define NULL
Definition oodle2base.h:134
UE_FORCEINLINE_HINT TSharedRef< CastToType, Mode > StaticCastSharedRef(TSharedRef< CastFromType, Mode > const &InSharedRef)
Definition SharedPointer.h:127
#define ULANG_ERRORF(format,...)
Definition Common.h:289
#define ULANG_ASSERTF(expr, format,...)
Definition Common.h:290
#define TEMPLATE_PARAMETERS2(X, Y)
Definition UnrealTemplate.h:500
Definition Union.h:64
Definition Union.h:29
bool operator!=(const FNull &) const
Definition Union.h:37
bool operator==(const FNull &) const
Definition Union.h:32
Definition Union.h:51
TUnion(typename TCallTraits< TypeB >::ParamType InValue, TDisambiguater< 1 > Disambiguater=TDisambiguater< 1 >())
Definition Union.h:67
TUnion()
Definition Union.h:55
TTypeCompatibleBytes< TypeC > C
Definition Union.h:260
TTypeCompatibleBytes< TypeB > B
Definition Union.h:259
TUnion(typename TCallTraits< TypeF >::ParamType InValue, TDisambiguater< 5 > Disambiguater=TDisambiguater< 5 >())
Definition Union.h:95
Subtype * SetSubtype(typename TCallTraits< Subtype >::ParamType NewValue)
Definition Union.h:178
TTypeCompatibleBytes< TypeD > D
Definition Union.h:261
bool operator==(const TUnion &Other) const
Definition Union.h:233
TUnion(typename TCallTraits< TypeD >::ParamType InValue, TDisambiguater< 3 > Disambiguater=TDisambiguater< 3 >())
Definition Union.h:81
bool HasSubtype() const
Definition Union.h:117
TUnion(const TUnion &Other)
Definition Union.h:102
TTypeCompatibleBytes< TypeE > E
Definition Union.h:262
TUnion(typename TCallTraits< TypeA >::ParamType InValue, TDisambiguater< 0 > Disambiguater=TDisambiguater< 0 >())
Definition Union.h:60
Subtype & GetSubtype()
Definition Union.h:163
TTypeCompatibleBytes< TypeA > A
Definition Union.h:258
const Subtype & GetSubtype() const
Definition Union.h:148
TUnion(typename TCallTraits< TypeC >::ParamType InValue, TDisambiguater< 2 > Disambiguater=TDisambiguater< 2 >())
Definition Union.h:74
void ResetSubtype()
Definition Union.h:129
TUnion(typename TCallTraits< TypeE >::ParamType InValue, TDisambiguater< 4 > Disambiguater=TDisambiguater< 4 >())
Definition Union.h:88
void Reset()
Definition Union.h:199
TTypeCompatibleBytes< TypeF > F
Definition Union.h:263
TUnion & operator=(const TUnion &Other)
Definition Union.h:214
~TUnion()
Definition Union.h:109
uint8_t GetCurrentSubtypeIndex() const
Definition Union.h:193
Definition VVMEngineEnvironment.h:23
@ Value
Definition TypeTraits.h:37
typename TCallTraitsParamTypeHelper< T, PassByValue >::ParamType ParamType
Definition TypeTraits.h:378
Definition Union.h:23
TDisambiguater()
Definition Union.h:24
Definition Storage.h:106