// Copyright Advanced Micro Devices, Inc., or its affiliates. // SPDX-License-Identifier: MIT #pragma once #include #include namespace rocRoller::Expression::EvaluateDetail { template concept CIntegral = std::integral && !std::same_as; template concept isFP32 = std::same_as; /** * Visitor for a specific Operation expression. Performs that * specific Operation (Add, subtract, etc). Does not walk the * expression tree. */ template struct OperationEvaluatorVisitor { }; /** * Visitor for an Expression. Walks the expression tree, * calling the OperationEvaluatorVisitor to perform actual * operations. */ struct EvaluateVisitor; /** * Is satisfied if the unary operation associated with TheEvaluator can be * applied to ARG. * e.g. TheEvaluator == OperationEvaluatorVisitor, Arg -> bool * * * @tparam TheEvaluator Specialization of OperationEvaluatorVisitor class * for a specific operation * @tparam ARG */ template concept CCanEvaluateUnary = requires(TheEvaluator ev, ARG arg) { requires CCommandArgumentValue; { ev.evaluate(arg) } -> CCommandArgumentValue; }; /** * Is satisfied if the binary operation associated with TheEvaluator can be * applied to LHS and RHS. * e.g. TheEvaluator == OperationEvaluatorVisitor, LHS -> int, RHS -> int * * Note that this depends on evaluate() not being defined for invalid pairs of * types, thus the use of e.g. `CCanAdd` below. * * @tparam TheEvaluator Specialization of OperationEvaluatorVisitor class * for a specific operation * @tparam LHS * @tparam RHS */ template concept CCanEvaluateBinary = requires(TheEvaluator ev, LHS lhs, RHS rhs) { requires CCommandArgumentValue; requires CCommandArgumentValue; { ev.evaluate(lhs, rhs) } -> CCommandArgumentValue; }; template concept CCanEvaluateTernary = requires(TheEvaluator ev, LHS lhs, R1HS r1hs, R2HS r2hs) { requires CCommandArgumentValue; requires CCommandArgumentValue; requires CCommandArgumentValue; { ev.evaluate(lhs, r1hs, r2hs) } -> CCommandArgumentValue; }; template CommandArgumentValue evaluateOp(T const& op, CommandArgumentValue const& arg); template CommandArgumentValue evaluateOp(T const& op, CommandArgumentValue const& lhs, CommandArgumentValue const& rhs); template CommandArgumentValue evaluateOp(T const& op, CommandArgumentValue const& lhs, CommandArgumentValue const& r1hs, CommandArgumentValue const& r2hs); template void assertNonNullPointer(T const& val) { if constexpr(std::is_pointer::value) { AssertFatal(val, "Can't offset from nullptr!"); } } CommandArgumentValue reinterpretTruncateValue(CommandArgumentValue const& value, DataType targetDataType, std::endian endianness); } #include