#pragma once #include #include #include #include #include namespace c10 { namespace guts { /** * Access information about result type or arguments from a function type. * Example: * using A = function_traits::return_type // A == int * using A = function_traits::parameter_types::tuple_type // A == tuple */ template struct function_traits { static_assert(!std::is_same::value, "In function_traits, Func must be a plain function type."); }; template struct function_traits { using func_type = Result (Args...); using return_type = Result; using parameter_types = typelist::typelist; static constexpr auto number_of_parameters = sizeof...(Args); }; /** * infer_function_traits: creates a `function_traits` type for a simple * function (pointer) or functor (lambda/struct). Currently does not support * class methods. */ template struct infer_function_traits { using type = function_traits>; }; template struct infer_function_traits { using type = function_traits; }; template struct infer_function_traits { using type = function_traits; }; template using infer_function_traits_t = typename infer_function_traits::type; /** * Use extract_arg_by_filtered_index to return the i-th argument whose * type fulfills a given type trait. The argument itself is perfectly forwarded. * * Example: * std::string arg1 = "Hello"; * std::string arg2 = "World"; * std::string&& result = extract_arg_by_filtered_index(0, arg1, 2.0, std::move(arg2)); * * Warning: Taking the result by rvalue reference can cause segfaults because ownership will not be passed on * from the original reference. The original reference dies after the expression and the resulting */ namespace detail { template