Created
June 5, 2021 00:58
-
-
Save Dich0tomy/b882e882df7e9afa3d7bf4229102c15b to your computer and use it in GitHub Desktop.
Quickly implemented callable arguments counting (C++20).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <iostream> | |
#include <type_traits> | |
#include <iostream> | |
#include <cstddef> | |
#define MAKE_REMOVE_MEM_FN_CV_SPEC(...) \ | |
template <class_type Class, typename Ret, typename... Args> \ | |
struct remove_mem_fn_cv<auto (Class::*)(Args...) __VA_ARGS__ -> Ret> { \ | |
using type = auto (Class::*)(Args...) -> Ret; \ | |
}; | |
template <typename T> | |
concept member_function = std::is_member_function_pointer_v<T>; | |
template <typename T> | |
concept class_type = std::is_class_v<T>; | |
template <typename T> | |
concept functor = requires { | |
{ class_type<T> }; | |
{ &T::operator() }; | |
}; | |
template <typename> | |
struct remove_mem_fn_cv {}; | |
MAKE_REMOVE_MEM_FN_CV_SPEC() | |
MAKE_REMOVE_MEM_FN_CV_SPEC(const) | |
MAKE_REMOVE_MEM_FN_CV_SPEC(volatile) | |
MAKE_REMOVE_MEM_FN_CV_SPEC(const volatile) | |
MAKE_REMOVE_MEM_FN_CV_SPEC(const &) | |
MAKE_REMOVE_MEM_FN_CV_SPEC(volatile &) | |
MAKE_REMOVE_MEM_FN_CV_SPEC(const volatile &) | |
MAKE_REMOVE_MEM_FN_CV_SPEC(const &&) | |
MAKE_REMOVE_MEM_FN_CV_SPEC(volatile &&) | |
MAKE_REMOVE_MEM_FN_CV_SPEC(const volatile &&) | |
namespace detail { | |
template <typename Func, typename Ret, typename... Args> | |
constexpr auto mem_fn_argc(auto (Func::*)(Args...) -> Ret) noexcept -> std::size_t { | |
return sizeof...(Args); | |
} | |
} // namespace detail | |
constexpr auto argc(member_function auto mem_fn_ptr) noexcept -> std::size_t { | |
using stripped_mem_fn = remove_mem_fn_cv<decltype(mem_fn_ptr)>::type; | |
return detail::mem_fn_argc(stripped_mem_fn{}); | |
} | |
template <functor Functor> | |
constexpr auto argc(Functor) noexcept -> std::size_t { | |
return argc(&Functor::operator()); | |
} | |
template <typename R, typename... Ts> | |
constexpr auto argc(auto (*)(Ts...) -> R) noexcept -> std::size_t { | |
return sizeof...(Ts); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment