UDocumentation UE5.7 10.02.2026 (Source)
API documentation for Unreal Engine 5.7
ExpressionParserTypes.inl
Go to the documentation of this file.
1// Copyright Epic Games, Inc. All Rights Reserved.
2
3#pragma once
4
5#include "CoreFwd.h"
6#include <type_traits>
7
8#define LOCTEXT_NAMESPACE "ExpressionParser"
9
10class FExpressionNode;
11template <typename CharType> class TExpressionToken;
13
14namespace Impl
15{
18 {
19 virtual ~IExpressionNodeStorage() = default;
21 virtual void Reseat(uint8* Dst) = 0;
23 virtual void MoveAssign(uint8* Dst) = 0;
25 virtual FExpressionNode Copy() const = 0;
26 };
27
30 template<typename T>
32 {
35
40
41 const T* Access() const
42 {
43 return &Value;
44 }
45
46 virtual void Reseat(uint8* Dst) override
47 {
48 ::new((void*)Dst) FInlineDataStorage(MoveTemp(Value));
49 }
50
51 virtual void MoveAssign(uint8* Dst) override
52 {
53 reinterpret_cast<FInlineDataStorage*>(Dst)->Value = MoveTemp(Value);
54 }
55
56 virtual FExpressionNode Copy() const override
57 {
58 return Value;
59 }
60 };
61
63 template<typename T>
65 {
68
74
75 const T* Access() const
76 {
77 return Value.Get();
78 }
79
80 virtual void Reseat(uint8* Dst) override
81 {
82 ::new((void*)Dst) FHeapDataStorage(MoveTemp(*this));
83 }
84
85 virtual void MoveAssign(uint8* Dst) override
86 {
87 reinterpret_cast<FHeapDataStorage*>(Dst)->Value = MoveTemp(Value);
88 }
89 virtual FExpressionNode Copy() const override
90 {
91 return *Value;
92 }
93 };
94
95 template<typename T, uint32 MaxStackAllocationSize>
97 {
98 using Type = std::conditional_t<sizeof(FInlineDataStorage<T>) <= MaxStackAllocationSize, FInlineDataStorage<T>, FHeapDataStorage<T>>;
99 };
100
101
103 template <typename> struct TCallableInfo;
104 template <typename> struct TCallableInfoImpl;
105
106 template <typename Ret_, typename T, typename Arg1_>
107 struct TCallableInfoImpl<Ret_ (T::*)(Arg1_)>
108 {
109 using Ret = Ret_;
110 using Arg1 = Arg1_;
111 static constexpr uint32 NumArgs = 1;
112 };
113
114 template <typename Ret_, typename T, typename Arg1_>
115 struct TCallableInfoImpl<Ret_ (T::*)(Arg1_) const>
116 {
117 using Ret = Ret_;
118 using Arg1 = Arg1_;
119 static constexpr uint32 NumArgs = 1;
120 };
121
122 template <typename Ret_, typename T, typename Arg1_, typename Arg2_>
123 struct TCallableInfoImpl<Ret_ (T::*)(Arg1_, Arg2_)>
124 {
125 using Ret = Ret_;
126 using Arg1 = Arg1_;
127 using Arg2 = Arg2_;
128 static constexpr uint32 NumArgs = 2;
129 };
130
131 template <typename Ret_, typename T, typename Arg1_, typename Arg2_>
132 struct TCallableInfoImpl<Ret_ (T::*)(Arg1_, Arg2_) const>
133 {
134 using Ret = Ret_;
135 using Arg1 = Arg1_;
136 using Arg2 = Arg2_;
137 static constexpr uint32 NumArgs = 2;
138 };
139
140 template <typename Ret_, typename T, typename Arg1_, typename Arg2_, typename Arg3_>
141 struct TCallableInfoImpl<Ret_ (T::*)(Arg1_, Arg2_, Arg3_)>
142 {
143 using Ret = Ret_;
144 using Arg1 = Arg1_;
145 using Arg2 = Arg2_;
146 using Arg3 = Arg3_;
147 static constexpr uint32 NumArgs = 3;
148 };
149
150 template <typename Ret_, typename T, typename Arg1_, typename Arg2_, typename Arg3_>
151 struct TCallableInfoImpl<Ret_ (T::*)(Arg1_, Arg2_, Arg3_) const>
152 {
153 using Ret = Ret_;
154 using Arg1 = Arg1_;
155 using Arg2 = Arg2_;
156 using Arg3 = Arg3_;
157 static constexpr uint32 NumArgs = 3;
158 };
159
160 template <typename T>
161 struct TCallableInfo : TCallableInfoImpl<decltype(&T::operator())>
162 {
163 };
164
166 template<typename T>
168 {
169 return MakeValue(MoveTemp(Result));
170 }
172 {
173 return MoveTemp(Result);
174 }
175
177 template<typename OperandType, typename ContextType, typename FuncType>
179 {
181
182 if constexpr (NumArgs == 1)
183 {
184 // Ignore the context
185 return [=](const FExpressionNode& InOperand, const ContextType* Context)
186 {
187 return ForwardReturnType(In(*InOperand.Cast<OperandType>()));
188 };
189 }
190 else if constexpr (NumArgs == 2)
191 {
192 return [=](const FExpressionNode& InOperand, const ContextType* Context)
193 {
194 return ForwardReturnType(In(*InOperand.Cast<OperandType>(), Context));
195 };
196 }
197 else
198 {
199 // sizeof(OperandType) == 0 is used to create a false value based on a template parameter
200 static_assert(sizeof(OperandType) == 0, "FuncType has an unexpected number of parameters");
201 return nullptr;
202 }
203 }
204
206 template<typename LeftOperandType, typename RightOperandType, typename ContextType, typename FuncType>
208 {
210
211 if constexpr (NumArgs == 2)
212 {
213 // Ignore the context
214 return [=](const FExpressionNode& InLeftOperand, const FExpressionNode& InRightOperand, const ContextType* Context)
215 {
216 return ForwardReturnType(In(*InLeftOperand.Cast<LeftOperandType>(), *InRightOperand.Cast<RightOperandType>()));
217 };
218 }
219 else if constexpr (NumArgs == 3)
220 {
221 return [=](const FExpressionNode& InLeftOperand, const FExpressionNode& InRightOperand, const ContextType* Context)
222 {
223 return ForwardReturnType(In(*InLeftOperand.Cast<LeftOperandType>(), *InRightOperand.Cast<RightOperandType>(), Context));
224 };
225 }
226 else
227 {
228 // sizeof(LeftOperandType) == 0 is used to create a false value based on a template parameter
229 static_assert(sizeof(LeftOperandType) == 0, "FuncType has an unexpected number of parameters");
230 return nullptr;
231 }
232 }
233
235 template<typename OperandType, typename ContextType, typename FuncType>
237 {
239
240 if constexpr (NumArgs == 1)
241 {
242 // Ignore the context
243 return [=](const FExpressionNode& InOperand, const ContextType* Context)
244 {
245 return In(*InOperand.Cast<OperandType>());
246 };
247 }
248 else if constexpr (NumArgs == 2)
249 {
250 return [=](const FExpressionNode& InOperand, const ContextType* Context)
251 {
252 return In(*InOperand.Cast<OperandType>(), Context);
253 };
254 }
255 else
256 {
257 // sizeof(OperandType) == 0 is used to create a false value based on a template parameter
258 static_assert(sizeof(OperandType) == 0, "FuncType has an unexpected number of parameters");
259 return nullptr;
260 }
261 }
262}
263
264template <
265 typename T
266 UE_REQUIRES_DEFINITION(!std::is_convertible_v<T*, FExpressionNode*>)
267>
269 : TypeId(TGetExpressionNodeTypeId<T>::GetTypeId())
270{
271 // Choose the relevant allocation strategy based on the size of the type
272 ::new((void*)InlineBytes) typename Impl::TStorageTypeDeduction<T, MaxStackAllocationSize>::Type(MoveTemp(In));
273}
274
275template<typename T>
276const T* FExpressionNode::Cast() const
277{
279 {
280 return reinterpret_cast<const typename Impl::TStorageTypeDeduction<T, MaxStackAllocationSize>::Type*>(InlineBytes)->Access();
281 }
282 return nullptr;
283}
284
285// End FExpresionNode
286
287template<typename ContextType, typename CharType>
289{
290 FOperatorFunctionID ID = { Operator.Node.GetTypeId(), L.Node.GetTypeId(), R.Node.GetTypeId() };
291 if (const auto* Func = BinaryOps.Find(ID))
292 {
293 return (*Func)(L.Node, R.Node, Context);
294 }
295
297 Args.Add(FText::FromString(Operator.Context.GetString()));
298 Args.Add(FText::FromString(L.Context.GetString()));
299 Args.Add(FText::FromString(R.Context.GetString()));
300 return MakeError(FText::Format(LOCTEXT("BinaryExecutionError", "Binary operator {0} cannot operate on {1} and {2}"), Args));
301}
302
303template<typename ContextType, typename CharType>
305{
306 FOperatorFunctionID ID = { Operator.Node.GetTypeId(), L.Node.GetTypeId(), FGuid() };
307 if (const auto* Func = BinaryShortCircuits.Find(ID))
308 {
309 return (*Func)(L.Node, Context);
310 }
311
312 return false;
313}
314
315template<typename ContextType, typename CharType>
317{
318 FOperatorFunctionID ID = { Operator.Node.GetTypeId(), FGuid(), R.Node.GetTypeId() };
319 if (const auto* Func = PreUnaryOps.Find(ID))
320 {
321 return (*Func)(R.Node, Context);
322 }
325 Args.Add(FText::FromString(Operator.Context.GetString()));
326 Args.Add(FText::FromString(R.Context.GetString()));
327 return MakeError(FText::Format(LOCTEXT("PreUnaryExecutionError", "Pre-unary operator {0} cannot operate on {1}"), Args));
328}
329
330template<typename ContextType, typename CharType>
332{
333 FOperatorFunctionID ID = { Operator.Node.GetTypeId(), L.Node.GetTypeId(), FGuid() };
334 if (const auto* Func = PostUnaryOps.Find(ID))
335 {
336 return (*Func)(L.Node, Context);
337 }
338
340 Args.Add(FText::FromString(Operator.Context.GetString()));
341 Args.Add(FText::FromString(L.Context.GetString()));
342 return MakeError(FText::Format(LOCTEXT("PostUnaryExecutionError", "Post-unary operator {0} cannot operate on {1}"), Args));
343}
344
345template<typename ContextType, typename CharType>
346template<typename OperatorType, typename FuncType>
349 using OperandType = std::decay_t<typename Impl::TCallableInfo<FuncType>::Arg1>;
350
353 FGuid(),
355 };
356
357 PreUnaryOps.Add(ID, Impl::WrapUnaryFunction<OperandType, ContextType>(InFunc));
358}
359
360template<typename ContextType, typename CharType>
361template<typename OperatorType, typename FuncType>
363{
364 using OperandType = std::decay_t<typename Impl::TCallableInfo<FuncType>::Arg1>;
365
369 FGuid()
370 };
371
372 PostUnaryOps.Add(ID, Impl::WrapUnaryFunction<OperandType, ContextType>(InFunc));
373}
374
375template<typename ContextType, typename CharType>
376template<typename OperatorType, typename FuncType>
378{
379 using LeftOperandType = std::decay_t<typename Impl::TCallableInfo<FuncType>::Arg1>;
380 using RightOperandType = std::decay_t<typename Impl::TCallableInfo<FuncType>::Arg2>;
381
386 };
387
388 BinaryOps.Add(ID, Impl::WrapBinaryFunction<LeftOperandType, RightOperandType, ContextType>(InFunc));
390
391template<typename ContextType, typename CharType>
392template<typename OperatorType, typename FuncType>
394{
395 using OperandType = std::decay_t<typename Impl::TCallableInfo<FuncType>::Arg1>;
396
400 FGuid()
401 };
402
403 BinaryShortCircuits.Add(ID, Impl::WrapShortCircuitFunction<OperandType, ContextType>(InFunc));
404}
405
406
408
409#undef LOCTEXT_NAMESPACE
UE_FORCEINLINE_HINT TSharedRef< CastToType, Mode > StaticCastSharedRef(TSharedRef< CastFromType, Mode > const &InSharedRef)
Definition SharedPointer.h:127
#define LOCTEXT(InKey, InTextLiteral)
Definition Internationalization.h:295
#define UE_REQUIRES_DEFINITION(...)
Definition Requires.h:88
UE_FORCEINLINE_HINT TUniquePtr< T > MakeUnique(TArgs &&... Args)
Definition UniquePtr.h:918
UE_INTRINSIC_CAST UE_REWRITE constexpr std::remove_reference_t< T > && MoveTemp(T &&Obj) noexcept
Definition UnrealTemplate.h:520
UE_REWRITE TValueOrError_ErrorProxy< ArgTypes... > MakeError(ArgTypes &&... Args UE_LIFETIMEBOUND)
Definition ValueOrError.h:41
UE_REWRITE TValueOrError_ValueProxy< ArgTypes... > MakeValue(ArgTypes &&... Args UE_LIFETIMEBOUND)
Definition ValueOrError.h:35
uint8_t uint8
Definition binka_ue_file_header.h:8
uint32_t uint32
Definition binka_ue_file_header.h:6
Definition ExpressionParserTypes.h:217
FExpressionNode()=default
CORE_API const FGuid & GetTypeId() const
Definition ExpressionParser.cpp:430
const T * Cast() const
Definition ExpressionParserTypes.inl:276
static CORE_API FText FromString(const ANSICHAR *String)
Definition Text.cpp:1081
static CORE_API FText Format(FTextFormat Fmt, const FFormatNamedArguments &InArguments)
Definition Text.cpp:469
UE_NODEBUG UE_FORCEINLINE_HINT SizeType Add(ElementType &&Item)
Definition Array.h:2696
Definition ExpressionParserTypes.h:263
TStringToken< CharType > Context
Definition ExpressionParserTypes.h:272
FExpressionNode Node
Definition ExpressionParserTypes.h:271
Definition AndroidPlatformMisc.h:14
Definition UniquePtr.h:107
Definition ValueOrError.h:58
Definition ExpressionParserTypes.h:21
TOperatorJumpTable< ContextType >::FUnaryFunction WrapUnaryFunction(FuncType In)
Definition ExpressionParserTypes.inl:178
TOperatorJumpTable< ContextType >::FShortCircuit WrapShortCircuitFunction(FuncType In)
Definition ExpressionParserTypes.inl:236
TOperatorJumpTable< ContextType >::FBinaryFunction WrapBinaryFunction(FuncType In)
Definition ExpressionParserTypes.inl:207
FExpressionResult ForwardReturnType(T &&Result)
Definition ExpressionParserTypes.inl:167
Definition Guid.h:109
Definition ExpressionParserTypes.h:295
Definition ExpressionParserTypes.inl:65
virtual void MoveAssign(uint8 *Dst) override
Definition ExpressionParserTypes.inl:85
const T * Access() const
Definition ExpressionParserTypes.inl:75
virtual FExpressionNode Copy() const override
Definition ExpressionParserTypes.inl:89
virtual void Reseat(uint8 *Dst) override
Definition ExpressionParserTypes.inl:80
FHeapDataStorage(T InValue)
Definition ExpressionParserTypes.inl:70
TUniquePtr< T > Value
Definition ExpressionParserTypes.inl:67
Definition ExpressionParserTypes.inl:32
virtual void Reseat(uint8 *Dst) override
Definition ExpressionParserTypes.inl:46
virtual FExpressionNode Copy() const override
Definition ExpressionParserTypes.inl:56
T Value
Definition ExpressionParserTypes.inl:34
FInlineDataStorage(T InValue)
Definition ExpressionParserTypes.inl:36
virtual void MoveAssign(uint8 *Dst) override
Definition ExpressionParserTypes.inl:51
const T * Access() const
Definition ExpressionParserTypes.inl:41
Definition ExpressionParserTypes.inl:18
virtual void Reseat(uint8 *Dst)=0
virtual void MoveAssign(uint8 *Dst)=0
virtual FExpressionNode Copy() const =0
virtual ~IExpressionNodeStorage()=default
Arg2_ Arg2
Definition ExpressionParserTypes.inl:155
Ret_ Ret
Definition ExpressionParserTypes.inl:153
Arg1_ Arg1
Definition ExpressionParserTypes.inl:154
Arg3_ Arg3
Definition ExpressionParserTypes.inl:156
Arg1_ Arg1
Definition ExpressionParserTypes.inl:144
Arg2_ Arg2
Definition ExpressionParserTypes.inl:145
Ret_ Ret
Definition ExpressionParserTypes.inl:143
Arg3_ Arg3
Definition ExpressionParserTypes.inl:146
Arg2_ Arg2
Definition ExpressionParserTypes.inl:136
Arg1_ Arg1
Definition ExpressionParserTypes.inl:135
Ret_ Ret
Definition ExpressionParserTypes.inl:134
Arg2_ Arg2
Definition ExpressionParserTypes.inl:127
Arg1_ Arg1
Definition ExpressionParserTypes.inl:126
Ret_ Ret
Definition ExpressionParserTypes.inl:125
Arg1_ Arg1
Definition ExpressionParserTypes.inl:118
Ret_ Ret
Definition ExpressionParserTypes.inl:117
Ret_ Ret
Definition ExpressionParserTypes.inl:109
Arg1_ Arg1
Definition ExpressionParserTypes.inl:110
Definition ExpressionParserTypes.inl:104
Definition ExpressionParserTypes.inl:162
Definition ExpressionParserTypes.inl:97
std::conditional_t< sizeof(FInlineDataStorage< T >)<=MaxStackAllocationSize, FInlineDataStorage< T >, FHeapDataStorage< T > > Type
Definition ExpressionParserTypes.inl:98
Definition ExpressionParserTypes.h:205
Definition ExpressionParserTypes.h:424
FExpressionResult ExecPreUnary(const TExpressionToken< CharType > &Operator, const TExpressionToken< CharType > &R, const ContextType *Context) const
Definition ExpressionParserTypes.inl:316
void MapPostUnary(FuncType InFunc)
Definition ExpressionParserTypes.inl:362
FExpressionResult ExecPostUnary(const TExpressionToken< CharType > &Operator, const TExpressionToken< CharType > &L, const ContextType *Context) const
Definition ExpressionParserTypes.inl:331
bool ShouldShortCircuit(const TExpressionToken< CharType > &Operator, const TExpressionToken< CharType > &L, const ContextType *Context) const
Definition ExpressionParserTypes.inl:304
FExpressionResult ExecBinary(const TExpressionToken< CharType > &Operator, const TExpressionToken< CharType > &L, const TExpressionToken< CharType > &R, const ContextType *Context) const
Definition ExpressionParserTypes.inl:288
void MapPreUnary(FuncType InFunc)
Definition ExpressionParserTypes.inl:347
void MapBinary(FuncType InFunc)
Definition ExpressionParserTypes.inl:377
void MapShortCircuit(FuncType InFunc)
Definition ExpressionParserTypes.inl:393