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());