// Copyright Advanced Micro Devices, Inc., or its affiliates. // SPDX-License-Identifier: MIT #pragma once #include #include namespace rocRoller { namespace Scheduling { namespace Detail { template TupType ConstructMapping(ContextPtr ctx, std::index_sequence) { auto tup = TupType(); auto mapping = [&ctx](T head, auto... tail) { return T(ctx); }; return {mapping(std::get(tup))...}; } } template MetaObserver::MetaObserver() = default; template MetaObserver::MetaObserver(ContextPtr ctx) : m_tuple(Detail::ConstructMapping(ctx, std::make_index_sequence{})) { } template MetaObserver::MetaObserver(Tup const& tup) : m_tuple(tup) { } template MetaObserver::~MetaObserver() = default; namespace Detail { template InstructionStatus Peek(Instruction const& inst, T const& obs, Rest const&... rest) { auto rv = obs.peek(inst); if constexpr(sizeof...(rest) > 0) { rv.combine(Peek(inst, rest...)); } return rv; } } template <> inline InstructionStatus MetaObserver<>::peek(Instruction const& inst) const { return {}; } template InstructionStatus MetaObserver::peek(Instruction const& inst) const { return std::apply([&inst](auto&&... args) { return Detail::Peek(inst, args...); }, m_tuple); } namespace Detail { template void Modify(Instruction& inst, T const& obs, Rest const&... rest) { obs.modify(inst); if constexpr(sizeof...(rest) > 0) { Modify(inst, rest...); } } } template <> inline void MetaObserver<>::modify(Instruction& inst) const { return; } template void MetaObserver::modify(Instruction& inst) const { std::apply([&inst](auto&&... args) { return Detail::Modify(inst, args...); }, m_tuple); } namespace Detail { template void Observe(Instruction const& inst, T& obs, Rest&... rest) { obs.observe(inst); if constexpr(sizeof...(rest) > 0) { Observe(inst, rest...); } } } template <> inline void MetaObserver<>::observe(Instruction const& inst) { } template void MetaObserver::observe(Instruction const& inst) { std::apply([&inst](auto&&... args) { Detail::Observe(inst, args...); }, m_tuple); } } }