/******************************************************************************* * * MIT License * * Copyright 2021-2025 AMD ROCm(TM) Software * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * *******************************************************************************/ #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!"); } } } #include