#pragma once #include #include #include #include #include namespace interrupt { template concept hal_interface = requires(T const &t, void (*isr)()) { { t.init() } -> stdx::same_as; { t.template irq_init() } -> stdx::same_as; { t.template run(irq_num_t{}, isr) } -> stdx::same_as; }; template struct null_hal { static auto init() -> void { undefined(); } template static auto irq_init() -> void { undefined(); } template static auto run(irq_num_t, stdx::invocable auto const &) -> void { undefined(); } private: static auto undefined() -> void { static_assert(stdx::always_false_v, "No interrupt HAL defined: inject one"); } }; static_assert(hal_interface>); template inline auto injected_hal = null_hal{}; struct hal { template requires(sizeof...(Ts) == 0) ALWAYS_INLINE static auto init() -> void { injected_hal.init(); } template requires(sizeof...(Ts) == 0) ALWAYS_INLINE static auto irq_init() -> void { injected_hal.template irq_init(); } template requires(sizeof...(Ts) == 0) ALWAYS_INLINE static auto run(irq_num_t irq, stdx::invocable auto const &isr) -> void { injected_hal.template run

(irq, isr); } }; static_assert(hal_interface); } // namespace interrupt