type_traits: nth_argument utility (with tests)

This commit is contained in:
Michele Caini
2022-05-23 11:46:50 +02:00
parent b26330adab
commit 619f51518a
2 changed files with 54 additions and 12 deletions

View File

@@ -698,6 +698,38 @@ public:
template<typename Member>
using member_class_t = typename member_class<Member>::type;
/**
* @brief Extracts the n-th argument of a given function or member function.
* @tparam Index The index of the argument to extract.
* @tparam Candidate A valid function, member function or data member.
*/
template<std::size_t Index, auto Candidate>
class nth_argument {
template<typename Ret, typename... Args>
static constexpr type_list<Args...> pick_up(Ret (*)(Args...));
template<typename Ret, typename Class, typename... Args>
static constexpr type_list<Args...> pick_up(Ret (Class ::*)(Args...));
template<typename Ret, typename Class, typename... Args>
static constexpr type_list<Args...> pick_up(Ret (Class ::*)(Args...) const);
template<typename Type, typename Class>
static constexpr type_list<Type> pick_up(Type Class ::*);
public:
/*! @brief N-th argument of the given function or member function. */
using type = type_list_element_t<Index, decltype(pick_up(Candidate))>;
};
/**
* @brief Helper type.
* @tparam Index The index of the argument to extract.
* @tparam Candidate A valid function, member function or data member.
*/
template<std::size_t Index, auto Candidate>
using nth_argument_t = typename nth_argument<Index, Candidate>::type;
} // namespace entt
#endif

View File

@@ -20,6 +20,20 @@ struct nlohmann_json_like final {
}
};
struct clazz {
char foo(int) {
return {};
}
int bar(double, float) const {
return {};
}
bool quux;
};
void free_function(int, const double &) {}
TEST(SizeOf, Functionalities) {
static_assert(entt::size_of_v<void> == 0u);
static_assert(entt::size_of_v<char> == sizeof(char));
@@ -177,23 +191,19 @@ TEST(ConstnessAs, Functionalities) {
}
TEST(MemberClass, Functionalities) {
struct clazz {
char foo(int) {
return {};
}
int bar(double, float) const {
return {};
}
bool quux;
};
static_assert(std::is_same_v<clazz, entt::member_class_t<decltype(&clazz::foo)>>);
static_assert(std::is_same_v<clazz, entt::member_class_t<decltype(&clazz::bar)>>);
static_assert(std::is_same_v<clazz, entt::member_class_t<decltype(&clazz::quux)>>);
}
TEST(NthArgument, Functionalities) {
static_assert(std::is_same_v<entt::nth_argument_t<0u, free_function>, int>);
static_assert(std::is_same_v<entt::nth_argument_t<1u, free_function>, const double &>);
static_assert(std::is_same_v<entt::nth_argument_t<0u, &clazz::bar>, double>);
static_assert(std::is_same_v<entt::nth_argument_t<1u, &clazz::bar>, float>);
static_assert(std::is_same_v<entt::nth_argument_t<0u, &clazz::quux>, bool>);
}
TEST(Tag, Functionalities) {
using namespace entt::literals;
static_assert(entt::tag<"foobar"_hs>::value == entt::hashed_string::value("foobar"));