1 #ifndef TYPETRAITS_INC_
2 #define TYPETRAITS_INC_
3
4 #include "Typelist.h"
5
6 namespace Loki
7 {
8 ////////////////////////////////////////////////////////////////////////////////
9 // class template IsCustomUnsignedInt
10 // Offers a means to integrate nonstandard built-in unsigned integral types
11 // (such as unsigned __int64 or unsigned long long int) with the TypeTraits
12 // class template defined below.
13 // Invocation: IsCustomUnsignedInt<T> where T is any type
14 // Defines 'value', an enum that is 1 iff T is a custom built-in unsigned
15 // integral type
16 // Specialize this class template for nonstandard unsigned integral types
17 // and define value = 1 in those specializations
18 ////////////////////////////////////////////////////////////////////////////////
19
20 template <typename T>
21 struct IsCustomUnsignedInt
22 {
23 enum { value = 0 };
24 };
25
26 ////////////////////////////////////////////////////////////////////////////////
27 // class template IsCustomSignedInt
28 // Offers a means to integrate nonstandard built-in unsigned integral types
29 // (such as unsigned __int64 or unsigned long long int) with the TypeTraits
30 // class template defined below.
31 // Invocation: IsCustomSignedInt<T> where T is any type
32 // Defines 'value', an enum that is 1 iff T is a custom built-in signed
33 // integral type
34 // Specialize this class template for nonstandard unsigned integral types
35 // and define value = 1 in those specializations
36 ////////////////////////////////////////////////////////////////////////////////
37
38 template <typename T>
39 struct IsCustomSignedInt
40 {
41 enum { value = 0 };
42 };
43
44 ////////////////////////////////////////////////////////////////////////////////
45 // class template IsCustomFloat
46 // Offers a means to integrate nonstandard floating point types with the
47 // TypeTraits class template defined below.
48 // Invocation: IsCustomFloat<T> where T is any type
49 // Defines 'value', an enum that is 1 iff T is a custom built-in
50 // floating point type
51 // Specialize this class template for nonstandard unsigned integral types
52 // and define value = 1 in those specializations
53 ////////////////////////////////////////////////////////////////////////////////
54
55 template <typename T>
56 struct IsCustomFloat
57 {
58 enum { value = 0 };
59 };
60
61 ////////////////////////////////////////////////////////////////////////////////
62 // Helper types for class template TypeTraits defined below
63 ////////////////////////////////////////////////////////////////////////////////
64
65 namespace Private
66 {
67 typedef TYPELIST_4(unsigned char, unsigned short int,
68 unsigned int, unsigned long int) StdUnsignedInts;
69 typedef TYPELIST_4(signed char, short int,
70 int, long int) StdSignedInts;
71 typedef TYPELIST_3(bool, char, wchar_t) StdOtherInts;
72 typedef TYPELIST_3(float, double, long double) StdFloats;
73 }
74
75 ////////////////////////////////////////////////////////////////////////////////
76 // class template TypeTraits
77 // Figures out various properties of any given type
78 // Invocations (T is a type):
79 // a) TypeTraits<T>::isPointer
80 // returns (at compile time) true if T is a pointer type
81 // b) TypeTraits<T>::PointeeType
82 // returns the type to which T points is T is a pointer type, NullType otherwise
83 // a) TypeTraits<T>::isReference
84 // returns (at compile time) true if T is a reference type
85 // b) TypeTraits<T>::ReferredType
86 // returns the type to which T refers is T is a reference type, NullType
87 // otherwise
88 // c) TypeTraits<T>::isMemberPointer
89 // returns (at compile time) true if T is a pointer to member type
90 // d) TypeTraits<T>::isStdUnsignedInt
91 // returns (at compile time) true if T is a standard unsigned integral type
92 // e) TypeTraits<T>::isStdSignedInt
93 // returns (at compile time) true if T is a standard signed integral type
94 // f) TypeTraits<T>::isStdIntegral
95 // returns (at compile time) true if T is a standard integral type
96 // g) TypeTraits<T>::isStdFloat
97 // returns (at compile time) true if T is a standard floating-point type
98 // h) TypeTraits<T>::isStdArith
99 // returns (at compile time) true if T is a standard arithmetic type
100 // i) TypeTraits<T>::isStdFundamental
101 // returns (at compile time) true if T is a standard fundamental type
102 // j) TypeTraits<T>::isUnsignedInt
103 // returns (at compile time) true if T is a unsigned integral type
104 // k) TypeTraits<T>::isSignedInt
105 // returns (at compile time) true if T is a signed integral type
106 // l) TypeTraits<T>::isIntegral
107 // returns (at compile time) true if T is a integral type
108 // m) TypeTraits<T>::isFloat
109 // returns (at compile time) true if T is a floating-point type
110 // n) TypeTraits<T>::isArith
111 // returns (at compile time) true if T is a arithmetic type
112 // o) TypeTraits<T>::isFundamental
113 // returns (at compile time) true if T is a fundamental type
114 // p) TypeTraits<T>::ParameterType
115 // returns the optimal type to be used as a parameter for functions that take Ts
116 // q) TypeTraits<T>::isConst
117 // returns (at compile time) true if T is a const-qualified type
118 // r) TypeTraits<T>::NonConstType
119 // removes the 'const' qualifier from T, if any
120 // s) TypeTraits<T>::isVolatile
121 // returns (at compile time) true if T is a volatile-qualified type
122 // t) TypeTraits<T>::NonVolatileType
123 // removes the 'volatile' qualifier from T, if any
124 // u) TypeTraits<T>::UnqualifiedType
125 // removes both the 'const' and 'volatile' qualifiers from T, if any
126 ////////////////////////////////////////////////////////////////////////////////
127
128 template <typename T>
129 class TypeTraits
130 {
131 private:
132 template <class U> struct PointerTraits
133 {
134 enum { result = false };
135 typedef NullType PointeeType;
136 };
137
138 template <class U> struct PointerTraits<U*>
139 {
140 enum { result = true };
141 typedef U PointeeType;
142 };
143
144 template <class U> struct ReferenceTraits
145 {
146 enum { result = false };
147 typedef U ReferredType;
148 };
149
150 template <class U> struct ReferenceTraits<U&>
151 {
152 enum { result = true };
153 typedef U ReferredType;
154 };
155
156 template <class U> struct PToMTraits
157 {
158 enum { result = false };
159 };
160
161 template <class U, class V>
162 struct PToMTraits<U V::*>
163 {
164 enum { result = true };
165 };
166
167 template <class U> struct UnConst
168 {
169 typedef U Result;
170 enum { isConst = 0 };
171 };
172
173 template <class U> struct UnConst<const U>
174 {
175 typedef U Result;
176 enum { isConst = 1 };
177 };
178
179 template <class U> struct UnVolatile
180 {
181 typedef U Result;
182 enum { isVolatile = 0 };
183 };
184
185 template <class U> struct UnVolatile<volatile U>
186 {
187 typedef U Result;
188 enum { isVolatile = 1 };
189 };
190
191 public:
192 enum { isPointer = PointerTraits<T>::result };
193 typedef typename PointerTraits<T>::PointeeType PointeeType;
194
195 enum { isReference = ReferenceTraits<T>::result };
196 typedef typename ReferenceTraits<T>::ReferredType ReferredType;
197
198 enum { isMemberPointer = PToMTraits<T>::result };
199
200 enum { isStdUnsignedInt =
201 TL::IndexOf<Private::StdUnsignedInts, T>::value >= 0 };
202 enum { isStdSignedInt =
203 TL::IndexOf<Private::StdSignedInts, T>::value >= 0 };
204 enum { isStdIntegral = isStdUnsignedInt || isStdSignedInt ||
205 TL::IndexOf<Private::StdOtherInts, T>::value >= 0 };
206 enum { isStdFloat = TL::IndexOf<Private::StdFloats, T>::value >= 0 };
207 enum { isStdArith = isStdIntegral || isStdFloat };
208 enum { isStdFundamental = isStdArith || isStdFloat ||
209 Conversion<T, void>::sameType };
210
211 enum { isUnsignedInt = isStdUnsignedInt || IsCustomUnsignedInt<T>::value };
212 enum { isSignedInt = isStdSignedInt || IsCustomSignedInt<T>::value };
213 enum { isIntegral = isStdIntegral || isUnsignedInt || isSignedInt };
214 enum { isFloat = isStdFloat || IsCustomFloat<T>::value };
215 enum { isArith = isIntegral || isFloat };
216 enum { isFundamental = isStdFundamental || isArith || isFloat };
217
218 typedef typename Select<isStdArith || isPointer || isMemberPointer,
219 T, ReferredType&>::Result
220 ParameterType;
221
222 enum { isConst = UnConst<T>::isConst };
223 typedef typename UnConst<T>::Result NonConstType;
224 enum { isVolatile = UnVolatile<T>::isVolatile };
225 typedef typename UnVolatile<T>::Result NonVolatileType;
226 typedef typename UnVolatile<typename UnConst<T>::Result>::Result
227 UnqualifiedType;
228 };
229 }
230
231 ////////////////////////////////////////////////////////////////////////////////
232 // Change log:
233 // June 20, 2001: ported by Nick Thurn to gcc 2.95.3. Kudos, Nick!!!
234 ////////////////////////////////////////////////////////////////////////////////
235
236 #endif // TYPETRAITS_INC_