6#include "Templates/RemoveReference.h"
7#include "Templates/PointerIsConvertibleFromTo.h"
9#define LOCTEXT_NAMESPACE "ExpressionParser"
68 template<
typename T, uint32 MaxStackAllocationSize,
typename Enabled=
void>
struct TStorageTypeDeduction;
76 template <
typename>
struct TCallableInfo;
77 template <
typename>
struct TCallableInfoImpl;
79 template <
typename Ret_,
typename T,
typename Arg1_>
80 struct TCallableInfoImpl<Ret_ (T::*)(Arg1_)> {
typedef Ret_
Ret;
typedef Arg1_
Arg1;
enum {
NumArgs = 1 }; };
81 template <
typename Ret_,
typename T,
typename Arg1_>
82 struct TCallableInfoImpl<Ret_ (T::*)(Arg1_)
const> {
typedef Ret_
Ret;
typedef Arg1_
Arg1;
enum {
NumArgs = 1 }; };
84 template <
typename Ret_,
typename T,
typename Arg1_,
typename Arg2_>
85 struct TCallableInfoImpl<Ret_ (T::*)(Arg1_, Arg2_)> {
typedef Ret_
Ret;
typedef Arg1_
Arg1;
typedef Arg2_
Arg2;
enum {
NumArgs = 2 }; };
86 template <
typename Ret_,
typename T,
typename Arg1_,
typename Arg2_>
87 struct TCallableInfoImpl<Ret_ (T::*)(Arg1_, Arg2_)
const> {
typedef Ret_
Ret;
typedef Arg1_
Arg1;
typedef Arg2_
Arg2;
enum {
NumArgs = 2 }; };
89 template <
typename Ret_,
typename T,
typename Arg1_,
typename Arg2_,
typename Arg3_>
90 struct TCallableInfoImpl<Ret_ (T::*)(Arg1_, Arg2_, Arg3_)> {
typedef Ret_
Ret;
typedef Arg1_
Arg1;
typedef Arg2_
Arg2;
typedef Arg3_
Arg3;
enum {
NumArgs = 3 }; };
91 template <
typename Ret_,
typename T,
typename Arg1_,
typename Arg2_,
typename Arg3_>
92 struct TCallableInfoImpl<Ret_ (T::*)(Arg1_, Arg2_, Arg3_)
const> {
typedef Ret_
Ret;
typedef Arg1_
Arg1;
typedef Arg2_
Arg2;
typedef Arg3_
Arg3;
enum {
NumArgs = 3 }; };
107 template<
typename OperandType,
typename ContextType,
typename FuncType>
117 template<
typename OperandType,
typename ContextType,
typename FuncType>
127 template<
typename LeftOperandType,
typename RightOperandType,
typename ContextType,
typename FuncType>
137 template<
typename LeftOperandType,
typename RightOperandType,
typename ContextType,
typename FuncType>
147 template<
typename OperandType,
typename ContextType,
typename FuncType>
157 template<
typename OperandType,
typename ContextType,
typename FuncType>
168FExpressionNode::FExpressionNode(T In,
typename TEnableIf<!TPointerIsConvertibleFromTo<T,FExpressionNode>::Value>::Type*)
169 : TypeId(TGetExpressionNodeTypeId<T>::GetTypeId())
172 new(InlineBytes)
typename Impl::TStorageTypeDeduction<T, MaxStackAllocationSize>::Type(MoveTemp(In));
176const T* FExpressionNode::Cast()
const
178 if (TypeId == TGetExpressionNodeTypeId<T>::GetTypeId())
180 return reinterpret_cast<
const typename Impl::TStorageTypeDeduction<T, MaxStackAllocationSize>::Type*>(InlineBytes)->Access();
187template<
typename ContextType>
188FExpressionResult TOperatorJumpTable<ContextType>::ExecBinary(
const FExpressionToken& Operator,
const FExpressionToken& L,
const FExpressionToken& R,
const ContextType* Context)
const
190 FOperatorFunctionID ID = { Operator.Node.GetTypeId(), L.Node.GetTypeId(), R.Node.GetTypeId() };
191 if (
const auto* Func = BinaryOps.Find(ID))
193 return (*Func)(L.Node, R.Node, Context);
196 FFormatOrderedArguments Args;
197 Args.Add(FText::FromString(Operator.Context.GetString()));
198 Args.Add(FText::FromString(L.Context.GetString()));
199 Args.Add(FText::FromString(R.Context.GetString()));
200 return MakeError(FText::Format(LOCTEXT(
"BinaryExecutionError",
"Binary operator {0} cannot operate on {1} and {2}"), Args));
203template<
typename ContextType>
204bool TOperatorJumpTable<ContextType>::ShouldShortCircuit(
const FExpressionToken& Operator,
const FExpressionToken& L,
const ContextType* Context)
const
206 FOperatorFunctionID ID = { Operator.Node.GetTypeId(), L.Node.GetTypeId(), FGuid() };
207 if (
const auto* Func = BinaryShortCircuits.Find(ID))
209 return (*Func)(L.Node, Context);
215template<
typename ContextType>
216FExpressionResult TOperatorJumpTable<ContextType>::ExecPreUnary(
const FExpressionToken& Operator,
const FExpressionToken& R,
const ContextType* Context)
const
218 FOperatorFunctionID ID = { Operator.Node.GetTypeId(), FGuid(), R.Node.GetTypeId() };
219 if (
const auto* Func = PreUnaryOps.Find(ID))
221 return (*Func)(R.Node, Context);
224 FFormatOrderedArguments Args;
225 Args.Add(FText::FromString(Operator.Context.GetString()));
226 Args.Add(FText::FromString(R.Context.GetString()));
227 return MakeError(FText::Format(LOCTEXT(
"PreUnaryExecutionError",
"Pre-unary operator {0} cannot operate on {1}"), Args));
230template<
typename ContextType>
231FExpressionResult TOperatorJumpTable<ContextType>::ExecPostUnary(
const FExpressionToken& Operator,
const FExpressionToken& L,
const ContextType* Context)
const
233 FOperatorFunctionID ID = { Operator.Node.GetTypeId(), L.Node.GetTypeId(), FGuid() };
234 if (
const auto* Func = PostUnaryOps.Find(ID))
236 return (*Func)(L.Node, Context);
239 FFormatOrderedArguments Args;
240 Args.Add(FText::FromString(Operator.Context.GetString()));
241 Args.Add(FText::FromString(L.Context.GetString()));
242 return MakeError(FText::Format(LOCTEXT(
"PostUnaryExecutionError",
"Post-unary operator {0} cannot operate on {1}"), Args));
245template<
typename ContextType>
246template<
typename OperatorType,
typename FuncType>
247void TOperatorJumpTable<ContextType>::MapPreUnary(FuncType InFunc)
249 typedef typename TRemoveConst<
typename TRemoveReference<
typename Impl::TCallableInfo<FuncType>::Arg1>::Type>::Type OperandType;
251 FOperatorFunctionID ID = {
252 TGetExpressionNodeTypeId<OperatorType>::GetTypeId(),
254 TGetExpressionNodeTypeId<OperandType>::GetTypeId()
257 PreUnaryOps.Add(ID, Impl::WrapUnaryFunction<OperandType, ContextType>(InFunc));
260template<
typename ContextType>
261template<
typename OperatorType,
typename FuncType>
262void TOperatorJumpTable<ContextType>::MapPostUnary(FuncType InFunc)
264 typedef typename TRemoveConst<
typename TRemoveReference<
typename Impl::TCallableInfo<FuncType>::Arg1>::Type>::Type OperandType;
266 FOperatorFunctionID ID = {
267 TGetExpressionNodeTypeId<OperatorType>::GetTypeId(),
268 TGetExpressionNodeTypeId<OperandType>::GetTypeId(),
272 PostUnaryOps.Add(ID, Impl::WrapUnaryFunction<OperandType, ContextType>(InFunc));
275template<
typename ContextType>
276template<
typename OperatorType,
typename FuncType>
277void TOperatorJumpTable<ContextType>::MapBinary(FuncType InFunc)
279 typedef typename TRemoveConst<
typename TRemoveReference<
typename Impl::TCallableInfo<FuncType>::Arg1>::Type>::Type LeftOperandType;
280 typedef typename TRemoveConst<
typename TRemoveReference<
typename Impl::TCallableInfo<FuncType>::Arg2>::Type>::Type RightOperandType;
282 FOperatorFunctionID ID = {
283 TGetExpressionNodeTypeId<OperatorType>::GetTypeId(),
284 TGetExpressionNodeTypeId<LeftOperandType>::GetTypeId(),
285 TGetExpressionNodeTypeId<RightOperandType>::GetTypeId()
288 BinaryOps.Add(ID, Impl::WrapBinaryFunction<LeftOperandType, RightOperandType, ContextType>(InFunc));
291template<
typename ContextType>
292template<
typename OperatorType,
typename FuncType>
293void TOperatorJumpTable<ContextType>::MapShortCircuit(FuncType InFunc)
295 typedef typename TRemoveConst<
typename TRemoveReference<
typename Impl::TCallableInfo<FuncType>::Arg1>::Type>::Type OperandType;
297 FOperatorFunctionID ID = {
298 TGetExpressionNodeTypeId<OperatorType>::GetTypeId(),
299 TGetExpressionNodeTypeId<OperandType>::GetTypeId(),
303 BinaryShortCircuits.Add(ID, Impl::WrapShortCircuitFunction<OperandType, ContextType>(InFunc));
307typedef TOperatorEvaluationEnvironment<> FOperatorEvaluationEnvironment;
309#undef LOCTEXT_NAMESPACE
static FExpressionResult ForwardReturnType(FExpressionResult &&Result)
static TEnableIf< Impl::TCallableInfo< FuncType >::NumArgs==1, typenameTOperatorJumpTable< ContextType >::FUnaryFunction >::Type WrapUnaryFunction(FuncType In)
static TEnableIf< Impl::TCallableInfo< FuncType >::NumArgs==1, typenameTOperatorJumpTable< ContextType >::FShortCircuit >::Type WrapShortCircuitFunction(FuncType In)
static FExpressionResult ForwardReturnType(T &&Result)
static TEnableIf< Impl::TCallableInfo< FuncType >::NumArgs==2, typenameTOperatorJumpTable< ContextType >::FBinaryFunction >::Type WrapBinaryFunction(FuncType In)
virtual void MoveAssign(uint8 *Dst) override
virtual FExpressionNode Copy() const override
virtual void Reseat(uint8 *Dst) override
FHeapDataStorage(T InValue)
FHeapDataStorage(FHeapDataStorage &&In)
virtual void Reseat(uint8 *Dst) override
virtual FExpressionNode Copy() const override
FInlineDataStorage(T InValue)
virtual void MoveAssign(uint8 *Dst) override
virtual void Reseat(uint8 *Dst)=0
virtual ~IExpressionNodeStorage()
virtual void MoveAssign(uint8 *Dst)=0
virtual FExpressionNode Copy() const =0
decltype(&T::operator()) Type