Bläddra i källkod

type_traits: nth_argument utility (with tests)

Michele Caini 3 år sedan
förälder
incheckning
619f51518a
2 ändrade filer med 54 tillägg och 12 borttagningar
  1. 32 0
      src/entt/core/type_traits.hpp
  2. 22 12
      test/entt/core/type_traits.cpp

+ 32 - 0
src/entt/core/type_traits.hpp

@@ -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

+ 22 - 12
test/entt/core/type_traits.cpp

@@ -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"));