Plasma Engine  2.0
Loading...
Searching...
No Matches
TypeTraits.h
1#pragma once
2
3#ifndef PL_INCLUDING_BASICS_H
4# error "Please don't include TypeTraits.h directly, but instead include Foundation/Basics.h"
5#endif
6
8
10template <int v>
12{
13 static constexpr int value = v;
14};
15
19
20using plCompileTimeTrueType = char;
21using plCompileTimeFalseType = int;
22
24template <bool cond>
26{
27 using type = plCompileTimeFalseType;
28};
29
30template <>
32{
33 using type = plCompileTimeTrueType;
34};
35
37template <typename T>
38plCompileTimeFalseType operator%(const T&, const plTypeIsPod&);
39
41template <typename T>
42struct plIsPodType : public plTraitInt<(sizeof(*((T*)0) % *((const plTypeIsPod*)0)) == sizeof(plCompileTimeTrueType)) ? 1 : 0>
43{
44};
45
47template <typename T>
48struct plIsPodType<T*> : public plTypeIsPod
49{
50};
51
53template <typename T, int N>
54struct plIsPodType<T[N]> : public plTypeIsPod
55{
56};
57
59template <typename T>
60plCompileTimeFalseType operator%(const T&, const plTypeIsMemRelocatable&);
61
64template <typename T>
66 : public plTraitInt<(sizeof(*((T*)0) % *((const plTypeIsMemRelocatable*)0)) == sizeof(plCompileTimeTrueType)) ? 2 : plIsPodType<T>::value>
67{
68};
69
71template <typename From, typename To>
73{
74 static plCompileTimeTrueType Test(const To&);
75 static plCompileTimeFalseType Test(...);
76 static From MakeFrom();
77
78 enum
79 {
80 exists = sizeof(Test(MakeFrom())) == sizeof(plCompileTimeTrueType),
81 sameType = 0
82 };
83};
84
86template <typename T>
87struct plConversionTest<T, T>
88{
89 enum
90 {
91 exists = 1,
92 sameType = 1
93 };
94};
95
96// remapping of the 0 (not special) type to 3
97template <typename T1, typename T2>
98struct plGetStrongestTypeClass : public plTraitInt<(T1::value == 0 || T2::value == 0) ? 0 : PL_COMPILE_TIME_MAX(T1::value, T2::value)>
99{
100};
101
102
103#ifdef __INTELLISENSE__
104
107# define PL_DECLARE_POD_TYPE()
108
114# define PL_DECLARE_MEM_RELOCATABLE_TYPE()
115
117# define PL_DECLARE_MEM_RELOCATABLE_TYPE_CONDITIONAL(T)
118
119// \brief embed this into a class to automatically detect which type class it belongs to
120// This macro is only guaranteed to work for classes / structs which don't have any constructor / destructor / assignment operator!
121// As arguments you have to list the types of all the members of the class / struct.
122# define PL_DETECT_TYPE_CLASS(...)
123
124#else
125
128# define PL_DECLARE_POD_TYPE() \
129 plCompileTimeTrueType operator%(const plTypeIsPod&) const \
130 { \
131 return {}; \
132 }
133
139# define PL_DECLARE_MEM_RELOCATABLE_TYPE() \
140 plCompileTimeTrueType operator%(const plTypeIsMemRelocatable&) const \
141 { \
142 return {}; \
143 }
144
146# define PL_DECLARE_MEM_RELOCATABLE_TYPE_CONDITIONAL(T) \
147 typename plConditionToCompileTimeBool<plGetTypeClass<T>::value == plTypeIsMemRelocatable::value || plIsPodType<T>::value>::type operator%( \
148 const plTypeIsMemRelocatable&) const \
149 { \
150 return {}; \
151 }
152
153# define PL_DETECT_TYPE_CLASS_1(T1) plGetTypeClass<T1>
154# define PL_DETECT_TYPE_CLASS_2(T1, T2) plGetStrongestTypeClass<PL_DETECT_TYPE_CLASS_1(T1), PL_DETECT_TYPE_CLASS_1(T2)>
155# define PL_DETECT_TYPE_CLASS_3(T1, T2, T3) plGetStrongestTypeClass<PL_DETECT_TYPE_CLASS_2(T1, T2), PL_DETECT_TYPE_CLASS_1(T3)>
156# define PL_DETECT_TYPE_CLASS_4(T1, T2, T3, T4) plGetStrongestTypeClass<PL_DETECT_TYPE_CLASS_2(T1, T2), PL_DETECT_TYPE_CLASS_2(T3, T4)>
157# define PL_DETECT_TYPE_CLASS_5(T1, T2, T3, T4, T5) plGetStrongestTypeClass<PL_DETECT_TYPE_CLASS_4(T1, T2, T3, T4), PL_DETECT_TYPE_CLASS_1(T5)>
158# define PL_DETECT_TYPE_CLASS_6(T1, T2, T3, T4, T5, T6) \
159 plGetStrongestTypeClass<PL_DETECT_TYPE_CLASS_4(T1, T2, T3, T4), PL_DETECT_TYPE_CLASS_2(T5, T6)>
160
161// \brief embed this into a class to automatically detect which type class it belongs to
162// This macro is only guaranteed to work for classes / structs which don't have any constructor / destructor / assignment operator!
163// As arguments you have to list the types of all the members of the class / struct.
164# define PL_DETECT_TYPE_CLASS(...) \
165 plCompileTimeTrueType operator%( \
166 const plTraitInt<PL_CALL_MACRO(PL_PP_CONCAT(PL_DETECT_TYPE_CLASS_, PL_VA_NUM_ARGS(__VA_ARGS__)), (__VA_ARGS__))::value>&) const \
167 { \
168 return {}; \
169 }
170#endif
171
174#define PL_DEFINE_AS_POD_TYPE(T) \
175 template <> \
176 struct plIsPodType<T> : public plTypeIsPod \
177 { \
178 }
179
180PL_DEFINE_AS_POD_TYPE(bool);
181PL_DEFINE_AS_POD_TYPE(float);
182PL_DEFINE_AS_POD_TYPE(double);
183
184PL_DEFINE_AS_POD_TYPE(char);
185PL_DEFINE_AS_POD_TYPE(plInt8);
186PL_DEFINE_AS_POD_TYPE(plInt16);
187PL_DEFINE_AS_POD_TYPE(plInt32);
188PL_DEFINE_AS_POD_TYPE(plInt64);
189PL_DEFINE_AS_POD_TYPE(plUInt8);
190PL_DEFINE_AS_POD_TYPE(plUInt16);
191PL_DEFINE_AS_POD_TYPE(plUInt32);
192PL_DEFINE_AS_POD_TYPE(plUInt64);
193PL_DEFINE_AS_POD_TYPE(wchar_t);
194PL_DEFINE_AS_POD_TYPE(unsigned long);
195PL_DEFINE_AS_POD_TYPE(long);
196PL_DEFINE_AS_POD_TYPE(std::byte);
197
199#define PL_IS_DERIVED_FROM_STATIC(BaseClass, DerivedClass) \
200 (plConversionTest<const DerivedClass*, const BaseClass*>::exists && !plConversionTest<const BaseClass*, const void*>::sameType)
201
203#define PL_IS_SAME_TYPE(TypeA, TypeB) plConversionTest<TypeA, TypeB>::sameType
204
205template <typename T>
207{
209 using NonConstType = typename std::remove_const<T>::type;
210
212 using NonReferenceType = typename std::remove_reference<T>::type;
213
215 using NonPointerType = typename std::remove_pointer<T>::type;
216
218 using NonConstReferenceType = typename std::remove_const<typename std::remove_reference<T>::type>::type;
219
221 using NonReferencePointerType = typename std::remove_pointer<typename std::remove_reference<T>::type>::type;
222
225 using NonConstReferencePointerType = typename std::remove_const<typename std::remove_reference<typename std::remove_pointer<T>::type>::type>::type;
226};
227
230#define PL_MAKE_MEMBERFUNCTION_CHECKER(functionName, checkerName) \
231 template <typename T, typename Signature> \
232 struct checkerName \
233 { \
234 template <typename U, U> \
235 struct type_check; \
236 template <typename O> \
237 static plCompileTimeTrueType& chk(type_check<Signature, &O::functionName>*); \
238 template <typename> \
239 static plCompileTimeFalseType& chk(...); \
240 enum \
241 { \
242 value = (sizeof(chk<T>(0)) == sizeof(plCompileTimeTrueType)) ? 1 : 0 \
243 }; \
244 }
Converts a bool condition to CompileTimeTrue/FalseType.
Definition TypeTraits.h:26
Static Conversion Test.
Definition TypeTraits.h:73
Definition TypeTraits.h:99
If there is an % operator which takes a plTypeIsMemRelocatable and returns a CompileTimeTrueType T is...
Definition TypeTraits.h:67
If there is an % operator which takes a TypeIsPod and returns a CompileTimeTrueType T is Pod....
Definition TypeTraits.h:43
Type traits.
Definition TypeTraits.h:12
Definition TypeTraits.h:207
typename std::remove_const< typename std::remove_reference< T >::type >::type NonConstReferenceType
removes reference and const qualifier
Definition TypeTraits.h:218
typename std::remove_const< typename std::remove_reference< typename std::remove_pointer< T >::type >::type >::type NonConstReferencePointerType
removes reference, const and pointer qualifier Note that this removes the const and reference of the ...
Definition TypeTraits.h:225
typename std::remove_const< T >::type NonConstType
removes const qualifier
Definition TypeTraits.h:209
typename std::remove_pointer< T >::type NonPointerType
removes pointer
Definition TypeTraits.h:215
typename std::remove_pointer< typename std::remove_reference< T >::type >::type NonReferencePointerType
removes reference and pointer qualifier
Definition TypeTraits.h:221
typename std::remove_reference< T >::type NonReferenceType
removes reference
Definition TypeTraits.h:212