1 #ifndef AI_TOOLBOX_IMPL_FUNCTION_MATCHIN_HEADER_FILE
2 #define AI_TOOLBOX_IMPL_FUNCTION_MATCHIN_HEADER_FILE
41 template <
typename R,
typename... Args>
43 using args = std::tuple<Args...>;
47 template <
typename R,
typename C,
typename... Args>
49 using args = std::tuple<Args...>;
53 template <
typename R,
typename C,
typename... Args>
59 template <
size_t... IDs>
struct IdPack {};
75 template <
size_t N,
typename T,
typename U,
size_t... IDs>
77 static constexpr
bool match =
false;
81 template <
size_t N,
typename... B,
size_t... IDs>
82 struct Matcher<N, std::tuple<>, std::tuple<B...>, IDs...> {
83 static constexpr
bool match =
true;
87 template <
size_t N,
typename F,
typename... A,
typename... B,
size_t... IDs>
88 struct Matcher<N, std::tuple<F, A...>, std::tuple<F, B...>, IDs...> {
89 using M =
Matcher<N+1, std::tuple<A...>, std::tuple<B...>, IDs..., N>;
94 template <
size_t N,
typename FA,
typename... A,
typename FB,
typename... B,
size_t... IDs>
95 struct Matcher<N, std::tuple<FA, A...>, std::tuple<FB, B...>, IDs...> {
96 using M = std::conditional_t<
97 std::is_constructible_v<FA, FB> &&
98 std::is_same_v<std::remove_cvref_t<FA>, std::remove_cvref_t<FB>>,
99 Matcher<N+1, std::tuple<A...>, std::tuple<B...>, IDs..., N>,
100 Matcher<N+1, std::tuple<FA, A...>, std::tuple<B...>, IDs...>
116 template <
typename T,
typename F>
118 static constexpr
bool value =
false;
121 template <
typename R,
typename... Args,
typename R2,
typename... Args2>
123 static constexpr
bool value = std::is_same<R, R2>::value &&
127 template <
typename R,
typename C,
typename... Args,
typename R2,
typename... Args2>
130 template <
typename R,
typename C,
typename... Args,
typename R2,
typename... Args2>
141 template <
typename F,
typename... Args,
size_t... IDs>
143 f(std::forward<std::tuple_element_t<IDs, std::tuple<Args...>>>(std::get<IDs>(args))...);
146 template <
typename C,
typename F,
typename... Args,
size_t... IDs>
148 (c.*f)(std::forward<std::tuple_element_t<IDs, std::tuple<Args...>>>(std::get<IDs>(args))...);
162 template <
typename F,
typename... Args>
165 using IdList =
typename Matcher<0, FArgs, std::tuple<Args...>>::type;
167 caller(f, std::forward_as_tuple(args...), IdList());
182 template <
typename C,
typename F,
typename... Args>
185 using IdList =
typename Matcher<0, FArgs, std::tuple<Args...>>::type;
186 static_assert(
Matcher<0, FArgs, std::tuple<Args...>>::
match);
188 caller(c, f, std::forward_as_tuple(args...), IdList());