add function signature traits
This commit is contained in:
@@ -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
|
||||
|
||||
84
include/snipplib/concepts/snplib_traits.h
Normal file
84
include/snipplib/concepts/snplib_traits.h
Normal file
@@ -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 <typename... Ts>
|
||||
struct snplib_func_traits_helper_t;
|
||||
|
||||
template <typename R>
|
||||
struct snplib_func_traits_helper_t<R> {
|
||||
using ret_t = R;
|
||||
using args_t = std::tuple<>;
|
||||
using arg1_t = void;
|
||||
static constexpr size_t arity = 0;
|
||||
};
|
||||
|
||||
template <typename R, typename Arg, typename... Args>
|
||||
struct snplib_func_traits_helper_t<R, Arg, Args...> {
|
||||
using ret_t = R;
|
||||
using args_t = std::tuple<Arg, Args...>;
|
||||
using arg1_t = Arg;
|
||||
static constexpr size_t arity = sizeof...(Args) + 1;
|
||||
};
|
||||
|
||||
|
||||
template <typename F>
|
||||
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<std::nullptr_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 <typename R, typename... Args>
|
||||
struct snplib_func_traits_t<R (*)(Args...)> : snplib_func_traits_helper_t<R, Args...> {
|
||||
};
|
||||
|
||||
template <typename R, typename... Args>
|
||||
struct snplib_func_traits_t<R(Args...)> : snplib_func_traits_helper_t<R, Args...> {
|
||||
};
|
||||
|
||||
template <typename C, typename R, typename... Args>
|
||||
struct snplib_func_traits_t<R (C::*)(Args...)> : snplib_func_traits_helper_t<R, Args...> {
|
||||
};
|
||||
|
||||
template <typename C, typename R, typename... Args>
|
||||
struct snplib_func_traits_t<R (C::*)(Args...) const> : snplib_func_traits_helper_t<R, Args...> {
|
||||
};
|
||||
|
||||
template <typename F>
|
||||
requires snplib_callable_c<F>
|
||||
struct snplib_func_traits_t<F> : snplib_func_traits_t<decltype(&F::operator())> {
|
||||
};
|
||||
|
||||
template <typename F>
|
||||
struct snplib_func_traits_t<F&> : snplib_func_traits_t<F> {
|
||||
};
|
||||
|
||||
template <typename F>
|
||||
struct snplib_func_traits_t<const F&> : snplib_func_traits_t<F> {
|
||||
};
|
||||
|
||||
template <typename F>
|
||||
struct snplib_func_traits_t<F&&> : snplib_func_traits_t<F> {
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
using snplib_func_arg1_t = typename snplib_func_traits_t<T>::arg1_t;
|
||||
|
||||
} // namespace snplib
|
||||
Reference in New Issue
Block a user