#pragma once #include namespace core { template concept callable = requires { &T::operator(); }; template struct function_traits { using return_type = void; using first_argument_type = void; }; template requires callable struct function_traits { using return_type = typename function_traits::return_type; using first_argument_type = typename function_traits::first_argument_type; }; template struct function_traits { using return_type = typename Ret; using first_argument_type = typename Arg0; }; template struct function_traits { using return_type = typename Ret; using first_argument_type = typename Arg0; }; template struct function_traits { using return_type = typename Ret; using first_argument_type = typename Arg0; }; template struct function_traits { using return_type = typename Ret; using first_argument_type = typename Arg0; }; template using return_type_t = typename function_traits::return_type; template using first_argument_type_t = typename function_traits::first_argument_type; template concept callable_with_converted_argument = requires(T&& callable, Arg&& arg) { callable(typename traits::first_argument_type_t{arg}); }; }