1 #ifndef NTA_EVENT_H_INCLUDED
2 #define NTA_EVENT_H_INCLUDED
6 #include "nta/Option.h"
12 template<
typename RecipientEnum,
typename... FuncTypes>
14 static_assert(std::is_enum_v<RecipientEnum>,
15 "EventTemplate: RecipientEnum must be enum");
16 static_assert(std::size_t(RecipientEnum::COUNT) != 0,
17 "EventTemplate: RecipientEnum must declare COUNT as the last variant");
18 static_assert(
sizeof...(FuncTypes) == std::size_t(RecipientEnum::COUNT),
19 "EventTemplate: Every recipient must have a corresponding function signature");
20 static_assert((std::is_function_v<FuncTypes> && ...),
21 "EventTemplate: Every FuncType should be a function type");
23 template<std::size_t idx,
typename... Args>
24 void enact_helper(Args&&... args)
const {
25 if constexpr (std::is_invocable_v<decltype(std::get<idx>(m_actions).get()),
27 auto func = std::get<idx>(m_actions);
28 if (func) func.unwrap()(std::forward<Args>(args)...);
31 template<std::size_t i,
typename... Args>
32 void operator_helper(std::size_t e, Args&&... args)
const {
33 if (e == i) enact_helper<i>(std::forward<Args>(args)...);
34 else if constexpr (i > 0) operator_helper<i-1>(e,
35 std::forward<Args>(args)...);
37 template<std::size_t i,
typename... Args>
38 void operator2_helper(Args&&... args)
const {
39 enact_helper<i>(std::forward<Args>(args)...);
40 if constexpr (i > 0) operator2_helper<i-1>(std::forward<Args>(args)...);
43 std::tuple<utils::Option<std::function<FuncTypes>>...> m_actions;
45 template<RecipientEnum e,
typename Func>
46 void define_for(Func&& func) {
49 template<RecipientEnum e>
51 std::get<std::size_t(e)>(m_actions).destroy();
54 template<RecipientEnum e,
typename... Args>
55 void enact(Args&&... args)
const {
56 static_assert(std::is_invocable_v<decltype(std::get<std::size_t(e)>(m_actions).get()),
58 "EventTemplate: Tried calling enact with mismatched enum/args");
59 enact_helper<std::size_t(e)>(std::forward<Args>(args)...);
62 template<
typename... Args>
63 void operator()(RecipientEnum e, Args&&... args)
const {
64 operator_helper<
sizeof...(FuncTypes)-1>(std::size_t(e),
65 std::forward<Args>(args)...);
67 template<
typename... Args>
68 void operator()(Args&&... args)
const {
69 operator2_helper<
sizeof...(FuncTypes)-1>(std::forward<Args>(args)...);
72 using enum_type = RecipientEnum;
78 using enum_type = void;
82 #endif // NTA_EVENT_H_INCLUDED