Browse Source

type traits: added member_class and member_class_t

Michele Caini 6 years ago
parent
commit
09f36e32f7
2 changed files with 44 additions and 0 deletions
  1. 32 0
      src/entt/core/type_traits.hpp
  2. 12 0
      test/entt/core/type_traits.cpp

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

@@ -3,6 +3,7 @@
 
 
 
 
 #include <cstddef>
 #include <cstddef>
+#include <utility>
 #include <type_traits>
 #include <type_traits>
 #include "../config/config.h"
 #include "../config/config.h"
 #include "../core/hashed_string.hpp"
 #include "../core/hashed_string.hpp"
@@ -169,6 +170,37 @@ template<class Type>
 constexpr auto is_equality_comparable_v = is_equality_comparable<Type>::value;
 constexpr auto is_equality_comparable_v = is_equality_comparable<Type>::value;
 
 
 
 
+/**
+ * @brief Extracts the class of a non-static member object or function.
+ * @tparam Member A pointer to a non-static member object or function.
+ */
+template<typename Member>
+class member_class {
+    static_assert(std::is_member_pointer_v<Member>);
+
+    template<typename Class, typename Ret, typename... Args>
+    static Class * clazz(Ret(Class:: *)(Args...));
+
+    template<typename Class, typename Ret, typename... Args>
+    static Class * clazz(Ret(Class:: *)(Args...) const);
+
+    template<typename Class, typename Type>
+    static Class * clazz(Type Class:: *);
+
+public:
+    /*! @brief The class of the given non-static member object or function. */
+    using type = std::remove_pointer_t<decltype(clazz(std::declval<Member>()))>;
+};
+
+
+/**
+ * @brief Helper type.
+ * @tparam Member A pointer to a non-static member object or function.
+ */
+template<typename Member>
+using member_class_t = typename member_class<Member>::type;
+
+
 }
 }
 
 
 
 

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

@@ -22,3 +22,15 @@ TEST(IsEqualityComparable, Functionalities) {
     ASSERT_TRUE(entt::is_equality_comparable_v<int>);
     ASSERT_TRUE(entt::is_equality_comparable_v<int>);
     ASSERT_FALSE(entt::is_equality_comparable_v<void>);
     ASSERT_FALSE(entt::is_equality_comparable_v<void>);
 }
 }
+
+TEST(MemberClass, Functionalities) {
+    struct clazz {
+        char foo(int) { return {}; }
+        int bar(double, float) const { return {}; }
+        bool quux;
+    };
+
+    ASSERT_TRUE((std::is_same_v<clazz, entt::member_class_t<decltype(&clazz::foo)>>));
+    ASSERT_TRUE((std::is_same_v<clazz, entt::member_class_t<decltype(&clazz::bar)>>));
+    ASSERT_TRUE((std::is_same_v<clazz, entt::member_class_t<decltype(&clazz::quux)>>));
+}