#pragma once #include #include #include #include #include namespace interrupt { template concept policy = requires { typename T::policy_type; }; template concept status_policy = policy and requires(void (*f)()) { { T::run(f, f) } -> stdx::same_as; }; struct status_clear_policy; struct clear_status_first { using policy_type = status_clear_policy; static void run(stdx::invocable auto const &clear_status, stdx::invocable auto const &run) { clear_status(); run(); } static_assert(status_policy); }; struct clear_status_last { using policy_type = status_clear_policy; static void run(stdx::invocable auto const &clear_status, stdx::invocable auto const &run) { run(); clear_status(); } static_assert(status_policy); }; struct dont_clear_status { using policy_type = status_clear_policy; static void run(stdx::invocable auto const &, stdx::invocable auto const &run) { run(); } static_assert(status_policy); }; struct required_resources_policy; template struct resource_list {}; template concept resources_policy = policy and stdx::is_specialization_of_v; template struct required_resources { using policy_type = required_resources_policy; using resources = resource_list; }; template struct policies { template constexpr static auto get() { using M = stdx::type_map< stdx::tt_pair...>; return stdx::type_lookup_t{}; } template using type = decltype(get()); }; } // namespace interrupt