diff --git a/CMakeLists.txt b/CMakeLists.txt index f8d8d9f..50ccb2e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -5,6 +5,7 @@ option(BUILD_EXAMPLES "Build examples" ON) set(LIB_HEADERS include/snipplib/concepts/snplib_concepts.h + include/snipplib/concepts/snplib_traits.h include/snipplib/utils/snplib_hash.h include/snipplib/utils/snplib_string.h include/snipplib/utils/snplib_utils.h diff --git a/include/snipplib/concepts/snplib_traits.h b/include/snipplib/concepts/snplib_traits.h new file mode 100644 index 0000000..2e38103 --- /dev/null +++ b/include/snipplib/concepts/snplib_traits.h @@ -0,0 +1,84 @@ +#pragma once + + +#include "snplib_concepts.h" + +namespace snplib +{ + +/* deduce callable's signature */ + +// WARNING: it does not work for generic lambdas! + +// helper classes +template +struct snplib_func_traits_helper_t; + +template +struct snplib_func_traits_helper_t { + using ret_t = R; + using args_t = std::tuple<>; + using arg1_t = void; + static constexpr size_t arity = 0; +}; + +template +struct snplib_func_traits_helper_t { + using ret_t = R; + using args_t = std::tuple; + using arg1_t = Arg; + static constexpr size_t arity = sizeof...(Args) + 1; +}; + + +template +struct snplib_func_traits_t { + // use of an empty struct here to match std::invoke_result behaivior (at least of GCC) +}; + +// special case +template <> +struct snplib_func_traits_t { + using ret_t = std::nullptr_t; + using args_t = std::tuple<>; + using arg1_t = std::nullptr_t; + static constexpr size_t arity = 0; +}; + +template +struct snplib_func_traits_t : snplib_func_traits_helper_t { +}; + +template +struct snplib_func_traits_t : snplib_func_traits_helper_t { +}; + +template +struct snplib_func_traits_t : snplib_func_traits_helper_t { +}; + +template +struct snplib_func_traits_t : snplib_func_traits_helper_t { +}; + +template + requires snplib_callable_c +struct snplib_func_traits_t : snplib_func_traits_t { +}; + +template +struct snplib_func_traits_t : snplib_func_traits_t { +}; + +template +struct snplib_func_traits_t : snplib_func_traits_t { +}; + +template +struct snplib_func_traits_t : snplib_func_traits_t { +}; + +template +using snplib_func_arg1_t = typename snplib_func_traits_t::arg1_t; + +} // namespace snplib \ No newline at end of file