#ifndef seafire__common__traits_hxx_ #define seafire__common__traits_hxx_ #include #include #include namespace seafire::common::traits { // is_optional // template struct is_optional : std::false_type {}; template struct is_optional> : std::true_type {}; template constexpr bool is_optional_v{is_optional::value}; // remove_optional // template struct remove_optional { using type = T; }; template struct remove_optional> { using type = T; }; template using remove_optional_t = remove_optional::type; // add_optional // template std::optional> add_optional(remove_optional&& non_optional) { return std::optional>{non_optional}; } // function_traits // template struct function_traits; template struct function_traits { static constexpr std::size_t arity = sizeof...(Args); using return_type = std::decay_t; using argument_tuple = std::tuple...>; }; template struct function_traits { static constexpr std::size_t arity = sizeof...(Args); using return_type = std::decay_t; using class_type = Class; using argument_tuple = std::tuple...>; }; template struct function_traits { static constexpr std::size_t arity = sizeof...(Args); using return_type = std::decay_t; using class_type = Class; using argument_tuple = std::tuple...>; }; template struct function_traits { static constexpr std::size_t arity = sizeof...(Args); using return_type = std::decay_t; using argument_tuple = std::tuple...>; }; // return_type_t // template using return_type_t = typename function_traits::return_type; // first_arg // template struct first_arg { using function_traits = traits::function_traits; using type = std::tuple_element_t<0, typename function_traits::argument_tuple>; }; template using first_arg_t = first_arg::type; // function_arg_n // template< typename F, std::size_t arg, std::size_t arity = function_traits::arity > struct function_arg_n; template< typename F, std::size_t arg > struct function_arg_n { using function_traits = traits::function_traits; using type = void; }; template< typename F, std::size_t arg > struct function_arg_n { using function_traits = traits::function_traits; using type = std::tuple_element_t; }; template< typename F, std::size_t arg > struct function_arg_n { using function_traits = traits::function_traits; using type = std::tuple_element_t; }; template< typename F, std::size_t arg > using function_arg_n_t = function_arg_n::type; } // namespace seafire::common::traits #endif