summaryrefslogtreecommitdiffstats
path: root/ComLightLib/utils/typeTraits.hpp
diff options
context:
space:
mode:
authorKonstantin <const@const.me>2023-01-16 14:52:43 +0100
committerKonstantin <const@const.me>2023-01-16 14:52:43 +0100
commit8c4603c73675958efc960fbd4bb599a2909d106a (patch)
tree714dc6fc9a1672d5fd7f89676b97e10959662abc /ComLightLib/utils/typeTraits.hpp
parent990a8d0dbaefc996244097397259e92758b15cce (diff)
Source codes
Diffstat (limited to 'ComLightLib/utils/typeTraits.hpp')
-rw-r--r--ComLightLib/utils/typeTraits.hpp43
1 files changed, 43 insertions, 0 deletions
diff --git a/ComLightLib/utils/typeTraits.hpp b/ComLightLib/utils/typeTraits.hpp
new file mode 100644
index 0000000..c5ddb84
--- /dev/null
+++ b/ComLightLib/utils/typeTraits.hpp
@@ -0,0 +1,43 @@
+#pragma once
+#include <type_traits>
+
+namespace ComLight
+{
+ namespace details
+ {
+ template<class TResult, class TValue>
+ constexpr bool pointersAssignable()
+ {
+ // See this for why `&` is required: https://stackoverflow.com/a/52429468/126995
+ return std::is_assignable<TResult*&, TValue*>::value;
+ }
+ }
+}
+
+// https://en.wikibooks.org/wiki/More_C++_Idioms/Member_Detector
+#define GENERATE_HAS_MEMBER(member) \
+ \
+template < class T > \
+class HasMember_##member \
+{ \
+private: \
+ using Yes = char[2]; \
+ using No = char[1]; \
+ \
+ struct Fallback { int member; }; \
+ struct Derived : T, Fallback { }; \
+ \
+ template < class U > \
+ static No& test ( decltype(U::member)* ); \
+ template < typename U > \
+ static Yes& test ( U* ); \
+ \
+public: \
+ static constexpr bool RESULT = sizeof(test<Derived>(nullptr)) == sizeof(Yes); \
+}; \
+ \
+template < class T > \
+struct has_member_##member \
+: public std::integral_constant<bool, HasMember_##member<T>::RESULT> \
+{ \
+};