• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1  /*
2  * Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved.
3  * Copyright (C) 2009, 2010 Google Inc. All rights reserved.
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Library General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Library General Public License for more details.
14  *
15  * You should have received a copy of the GNU Library General Public License
16  * along with this library; see the file COPYING.LIB.  If not, write to
17  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18  * Boston, MA 02110-1301, USA.
19  *
20  */
21 
22 #ifndef TypeTraits_h
23 #define TypeTraits_h
24 
25 #include "Platform.h"
26 
27 #if (defined(__GLIBCXX__) && (__GLIBCXX__ >= 20070724) && defined(__GXX_EXPERIMENTAL_CXX0X__)) || (defined(_MSC_VER) && (_MSC_VER >= 1600))
28 #include <type_traits>
29 #endif
30 
31 namespace WTF {
32 
33     // The following are provided in this file:
34     //
35     //   IsInteger<T>::value
36     //   IsPod<T>::value, see the definition for a note about its limitations
37     //   IsConvertibleToInteger<T>::value
38     //
39     //   IsSameType<T, U>::value
40     //
41     //   RemovePointer<T>::Type
42     //   RemoveConst<T>::Type
43     //   RemoveVolatile<T>::Type
44     //   RemoveConstVolatile<T>::Type
45     //
46     //   COMPILE_ASSERT's in TypeTraits.cpp illustrate their usage and what they do.
47 
48     template<typename T> struct IsInteger           { static const bool value = false; };
49     template<> struct IsInteger<bool>               { static const bool value = true; };
50     template<> struct IsInteger<char>               { static const bool value = true; };
51     template<> struct IsInteger<signed char>        { static const bool value = true; };
52     template<> struct IsInteger<unsigned char>      { static const bool value = true; };
53     template<> struct IsInteger<short>              { static const bool value = true; };
54     template<> struct IsInteger<unsigned short>     { static const bool value = true; };
55     template<> struct IsInteger<int>                { static const bool value = true; };
56     template<> struct IsInteger<unsigned int>       { static const bool value = true; };
57     template<> struct IsInteger<long>               { static const bool value = true; };
58     template<> struct IsInteger<unsigned long>      { static const bool value = true; };
59     template<> struct IsInteger<long long>          { static const bool value = true; };
60     template<> struct IsInteger<unsigned long long> { static const bool value = true; };
61 #if !COMPILER(MSVC) || defined(_NATIVE_WCHAR_T_DEFINED)
62     template<> struct IsInteger<wchar_t>            { static const bool value = true; };
63 #endif
64 
65     // IsPod is misnamed as it doesn't cover all plain old data (pod) types.
66     // Specifically, it doesn't allow for enums or for structs.
67     template <typename T> struct IsPod           { static const bool value = IsInteger<T>::value; };
68     template <> struct IsPod<float>              { static const bool value = true; };
69     template <> struct IsPod<double>             { static const bool value = true; };
70     template <> struct IsPod<long double>        { static const bool value = true; };
71     template <typename P> struct IsPod<P*>       { static const bool value = true; };
72 
73     template<typename T> class IsConvertibleToInteger {
74         // Avoid "possible loss of data" warning when using Microsoft's C++ compiler
75         // by not converting int's to doubles.
76         template<bool performCheck, typename U> class IsConvertibleToDouble;
77         template<typename U> class IsConvertibleToDouble<false, U> {
78         public:
79             static const bool value = false;
80         };
81 
82         template<typename U> class IsConvertibleToDouble<true, U> {
83             typedef char YesType;
84             struct NoType {
85                 char padding[8];
86             };
87 
88             static YesType floatCheck(long double);
89             static NoType floatCheck(...);
90             static T& t;
91         public:
92             static const bool value = sizeof(floatCheck(t)) == sizeof(YesType);
93         };
94 
95     public:
96         static const bool value = IsInteger<T>::value || IsConvertibleToDouble<!IsInteger<T>::value, T>::value;
97     };
98 
99     template <typename T, typename U> struct IsSameType {
100         static const bool value = false;
101     };
102 
103     template <typename T> struct IsSameType<T, T> {
104         static const bool value = true;
105     };
106 
107     template <typename T, typename U> class IsSubclass {
108         typedef char YesType;
109         struct NoType {
110             char padding[8];
111         };
112 
113         static YesType subclassCheck(U*);
114         static NoType subclassCheck(...);
115         static T* t;
116     public:
117         static const bool value = sizeof(subclassCheck(t)) == sizeof(YesType);
118     };
119 
120     template <typename T, template<class V> class U> class IsSubclassOfTemplate {
121         typedef char YesType;
122         struct NoType {
123             char padding[8];
124         };
125 
126         template<typename W> static YesType subclassCheck(U<W>*);
127         static NoType subclassCheck(...);
128         static T* t;
129     public:
130         static const bool value = sizeof(subclassCheck(t)) == sizeof(YesType);
131     };
132 
133     template <typename T, template <class V> class OuterTemplate> struct RemoveTemplate {
134         typedef T Type;
135     };
136 
137     template <typename T, template <class V> class OuterTemplate> struct RemoveTemplate<OuterTemplate<T>, OuterTemplate> {
138         typedef T Type;
139     };
140 
141     template <typename T> struct RemoveConst {
142         typedef T Type;
143     };
144 
145     template <typename T> struct RemoveConst<const T> {
146         typedef T Type;
147     };
148 
149     template <typename T> struct RemoveVolatile {
150         typedef T Type;
151     };
152 
153     template <typename T> struct RemoveVolatile<volatile T> {
154         typedef T Type;
155     };
156 
157     template <typename T> struct RemoveConstVolatile {
158         typedef typename RemoveVolatile<typename RemoveConst<T>::Type>::Type Type;
159     };
160 
161     template <typename T> struct RemovePointer {
162         typedef T Type;
163     };
164 
165     template <typename T> struct RemovePointer<T*> {
166         typedef T Type;
167     };
168 
169 #if (defined(__GLIBCXX__) && (__GLIBCXX__ >= 20070724) && defined(__GXX_EXPERIMENTAL_CXX0X__)) || (defined(_MSC_VER) && (_MSC_VER >= 1600))
170 
171     // GCC's libstdc++ 20070724 and later supports C++ TR1 type_traits in the std namespace.
172     // VC10 (VS2010) and later support C++ TR1 type_traits in the std::tr1 namespace.
173     template<typename T> struct HasTrivialConstructor : public std::tr1::has_trivial_constructor<T> { };
174     template<typename T> struct HasTrivialDestructor : public std::tr1::has_trivial_destructor<T> { };
175 
176 #else
177 
178     // This compiler doesn't provide type traits, so we provide basic HasTrivialConstructor
179     // and HasTrivialDestructor definitions. The definitions here include most built-in
180     // scalar types but do not include POD structs and classes. For the intended purposes of
181     // type_traits this results correct but potentially less efficient code.
182     template <typename T, T v>
183     struct IntegralConstant {
184         static const T value = v;
185         typedef T value_type;
186         typedef IntegralConstant<T, v> type;
187     };
188 
189     typedef IntegralConstant<bool, true>  true_type;
190     typedef IntegralConstant<bool, false> false_type;
191 
192 #if defined(_MSC_VER) && (_MSC_VER >= 1400) && !defined(__INTEL_COMPILER)
193     // VC8 (VS2005) and later have built-in compiler support for HasTrivialConstructor / HasTrivialDestructor,
194     // but for some unexplained reason it doesn't work on built-in types.
195     template <typename T> struct HasTrivialConstructor : public IntegralConstant<bool, __has_trivial_constructor(T)>{ };
196     template <typename T> struct HasTrivialDestructor : public IntegralConstant<bool, __has_trivial_destructor(T)>{ };
197 #else
198     template <typename T> struct HasTrivialConstructor : public false_type{ };
199     template <typename T> struct HasTrivialDestructor : public false_type{ };
200 #endif
201 
202     template <typename T> struct HasTrivialConstructor<T*> : public true_type{ };
203     template <typename T> struct HasTrivialDestructor<T*> : public true_type{ };
204 
205     template <> struct HasTrivialConstructor<float> : public true_type{ };
206     template <> struct HasTrivialConstructor<const float> : public true_type{ };
207     template <> struct HasTrivialConstructor<volatile float> : public true_type{ };
208     template <> struct HasTrivialConstructor<const volatile float> : public true_type{ };
209 
210     template <> struct HasTrivialConstructor<double> : public true_type{ };
211     template <> struct HasTrivialConstructor<const double> : public true_type{ };
212     template <> struct HasTrivialConstructor<volatile double> : public true_type{ };
213     template <> struct HasTrivialConstructor<const volatile double> : public true_type{ };
214 
215     template <> struct HasTrivialConstructor<long double> : public true_type{ };
216     template <> struct HasTrivialConstructor<const long double> : public true_type{ };
217     template <> struct HasTrivialConstructor<volatile long double> : public true_type{ };
218     template <> struct HasTrivialConstructor<const volatile long double> : public true_type{ };
219 
220     template <> struct HasTrivialConstructor<unsigned char> : public true_type{ };
221     template <> struct HasTrivialConstructor<const unsigned char> : public true_type{ };
222     template <> struct HasTrivialConstructor<volatile unsigned char> : public true_type{ };
223     template <> struct HasTrivialConstructor<const volatile unsigned char> : public true_type{ };
224 
225     template <> struct HasTrivialConstructor<unsigned short> : public true_type{ };
226     template <> struct HasTrivialConstructor<const unsigned short> : public true_type{ };
227     template <> struct HasTrivialConstructor<volatile unsigned short> : public true_type{ };
228     template <> struct HasTrivialConstructor<const volatile unsigned short> : public true_type{ };
229 
230     template <> struct HasTrivialConstructor<unsigned int> : public true_type{ };
231     template <> struct HasTrivialConstructor<const unsigned int> : public true_type{ };
232     template <> struct HasTrivialConstructor<volatile unsigned int> : public true_type{ };
233     template <> struct HasTrivialConstructor<const volatile unsigned int> : public true_type{ };
234 
235     template <> struct HasTrivialConstructor<unsigned long> : public true_type{ };
236     template <> struct HasTrivialConstructor<const unsigned long> : public true_type{ };
237     template <> struct HasTrivialConstructor<volatile unsigned long> : public true_type{ };
238     template <> struct HasTrivialConstructor<const volatile unsigned long> : public true_type{ };
239 
240     template <> struct HasTrivialConstructor<unsigned long long> : public true_type{ };
241     template <> struct HasTrivialConstructor<const unsigned long long> : public true_type{ };
242     template <> struct HasTrivialConstructor<volatile unsigned long long> : public true_type{ };
243     template <> struct HasTrivialConstructor<const volatile unsigned long long> : public true_type{ };
244 
245     template <> struct HasTrivialConstructor<signed char> : public true_type{ };
246     template <> struct HasTrivialConstructor<const signed char> : public true_type{ };
247     template <> struct HasTrivialConstructor<volatile signed char> : public true_type{ };
248     template <> struct HasTrivialConstructor<const volatile signed char> : public true_type{ };
249 
250     template <> struct HasTrivialConstructor<signed short> : public true_type{ };
251     template <> struct HasTrivialConstructor<const signed short> : public true_type{ };
252     template <> struct HasTrivialConstructor<volatile signed short> : public true_type{ };
253     template <> struct HasTrivialConstructor<const volatile signed short> : public true_type{ };
254 
255     template <> struct HasTrivialConstructor<signed int> : public true_type{ };
256     template <> struct HasTrivialConstructor<const signed int> : public true_type{ };
257     template <> struct HasTrivialConstructor<volatile signed int> : public true_type{ };
258     template <> struct HasTrivialConstructor<const volatile signed int> : public true_type{ };
259 
260     template <> struct HasTrivialConstructor<signed long> : public true_type{ };
261     template <> struct HasTrivialConstructor<const signed long> : public true_type{ };
262     template <> struct HasTrivialConstructor<volatile signed long> : public true_type{ };
263     template <> struct HasTrivialConstructor<const volatile signed long> : public true_type{ };
264 
265     template <> struct HasTrivialConstructor<signed long long> : public true_type{ };
266     template <> struct HasTrivialConstructor<const signed long long> : public true_type{ };
267     template <> struct HasTrivialConstructor<volatile signed long long> : public true_type{ };
268     template <> struct HasTrivialConstructor<const volatile signed long long> : public true_type{ };
269 
270     template <> struct HasTrivialConstructor<bool> : public true_type{ };
271     template <> struct HasTrivialConstructor<const bool> : public true_type{ };
272     template <> struct HasTrivialConstructor<volatile bool> : public true_type{ };
273     template <> struct HasTrivialConstructor<const volatile bool> : public true_type{ };
274 
275     template <> struct HasTrivialConstructor<char> : public true_type{ };
276     template <> struct HasTrivialConstructor<const char> : public true_type{ };
277     template <> struct HasTrivialConstructor<volatile char> : public true_type{ };
278     template <> struct HasTrivialConstructor<const volatile char> : public true_type{ };
279 
280     #if !defined(_MSC_VER) || defined(_NATIVE_WCHAR_T_DEFINED)
281         template <> struct HasTrivialConstructor<wchar_t> : public true_type{ };
282         template <> struct HasTrivialConstructor<const wchar_t> : public true_type{ };
283         template <> struct HasTrivialConstructor<volatile wchar_t> : public true_type{ };
284         template <> struct HasTrivialConstructor<const volatile wchar_t> : public true_type{ };
285     #endif
286 
287     template <> struct HasTrivialDestructor<float> : public true_type{ };
288     template <> struct HasTrivialDestructor<const float> : public true_type{ };
289     template <> struct HasTrivialDestructor<volatile float> : public true_type{ };
290     template <> struct HasTrivialDestructor<const volatile float> : public true_type{ };
291 
292     template <> struct HasTrivialDestructor<double> : public true_type{ };
293     template <> struct HasTrivialDestructor<const double> : public true_type{ };
294     template <> struct HasTrivialDestructor<volatile double> : public true_type{ };
295     template <> struct HasTrivialDestructor<const volatile double> : public true_type{ };
296 
297     template <> struct HasTrivialDestructor<long double> : public true_type{ };
298     template <> struct HasTrivialDestructor<const long double> : public true_type{ };
299     template <> struct HasTrivialDestructor<volatile long double> : public true_type{ };
300     template <> struct HasTrivialDestructor<const volatile long double> : public true_type{ };
301 
302     template <> struct HasTrivialDestructor<unsigned char> : public true_type{ };
303     template <> struct HasTrivialDestructor<const unsigned char> : public true_type{ };
304     template <> struct HasTrivialDestructor<volatile unsigned char> : public true_type{ };
305     template <> struct HasTrivialDestructor<const volatile unsigned char> : public true_type{ };
306 
307     template <> struct HasTrivialDestructor<unsigned short> : public true_type{ };
308     template <> struct HasTrivialDestructor<const unsigned short> : public true_type{ };
309     template <> struct HasTrivialDestructor<volatile unsigned short> : public true_type{ };
310     template <> struct HasTrivialDestructor<const volatile unsigned short> : public true_type{ };
311 
312     template <> struct HasTrivialDestructor<unsigned int> : public true_type{ };
313     template <> struct HasTrivialDestructor<const unsigned int> : public true_type{ };
314     template <> struct HasTrivialDestructor<volatile unsigned int> : public true_type{ };
315     template <> struct HasTrivialDestructor<const volatile unsigned int> : public true_type{ };
316 
317     template <> struct HasTrivialDestructor<unsigned long> : public true_type{ };
318     template <> struct HasTrivialDestructor<const unsigned long> : public true_type{ };
319     template <> struct HasTrivialDestructor<volatile unsigned long> : public true_type{ };
320     template <> struct HasTrivialDestructor<const volatile unsigned long> : public true_type{ };
321 
322     template <> struct HasTrivialDestructor<unsigned long long> : public true_type{ };
323     template <> struct HasTrivialDestructor<const unsigned long long> : public true_type{ };
324     template <> struct HasTrivialDestructor<volatile unsigned long long> : public true_type{ };
325     template <> struct HasTrivialDestructor<const volatile unsigned long long> : public true_type{ };
326 
327     template <> struct HasTrivialDestructor<signed char> : public true_type{ };
328     template <> struct HasTrivialDestructor<const signed char> : public true_type{ };
329     template <> struct HasTrivialDestructor<volatile signed char> : public true_type{ };
330     template <> struct HasTrivialDestructor<const volatile signed char> : public true_type{ };
331 
332     template <> struct HasTrivialDestructor<signed short> : public true_type{ };
333     template <> struct HasTrivialDestructor<const signed short> : public true_type{ };
334     template <> struct HasTrivialDestructor<volatile signed short> : public true_type{ };
335     template <> struct HasTrivialDestructor<const volatile signed short> : public true_type{ };
336 
337     template <> struct HasTrivialDestructor<signed int> : public true_type{ };
338     template <> struct HasTrivialDestructor<const signed int> : public true_type{ };
339     template <> struct HasTrivialDestructor<volatile signed int> : public true_type{ };
340     template <> struct HasTrivialDestructor<const volatile signed int> : public true_type{ };
341 
342     template <> struct HasTrivialDestructor<signed long> : public true_type{ };
343     template <> struct HasTrivialDestructor<const signed long> : public true_type{ };
344     template <> struct HasTrivialDestructor<volatile signed long> : public true_type{ };
345     template <> struct HasTrivialDestructor<const volatile signed long> : public true_type{ };
346 
347     template <> struct HasTrivialDestructor<signed long long> : public true_type{ };
348     template <> struct HasTrivialDestructor<const signed long long> : public true_type{ };
349     template <> struct HasTrivialDestructor<volatile signed long long> : public true_type{ };
350     template <> struct HasTrivialDestructor<const volatile signed long long> : public true_type{ };
351 
352     template <> struct HasTrivialDestructor<bool> : public true_type{ };
353     template <> struct HasTrivialDestructor<const bool> : public true_type{ };
354     template <> struct HasTrivialDestructor<volatile bool> : public true_type{ };
355     template <> struct HasTrivialDestructor<const volatile bool> : public true_type{ };
356 
357     template <> struct HasTrivialDestructor<char> : public true_type{ };
358     template <> struct HasTrivialDestructor<const char> : public true_type{ };
359     template <> struct HasTrivialDestructor<volatile char> : public true_type{ };
360     template <> struct HasTrivialDestructor<const volatile char> : public true_type{ };
361 
362     #if !defined(_MSC_VER) || defined(_NATIVE_WCHAR_T_DEFINED)
363         template <> struct HasTrivialDestructor<wchar_t> : public true_type{ };
364         template <> struct HasTrivialDestructor<const wchar_t> : public true_type{ };
365         template <> struct HasTrivialDestructor<volatile wchar_t> : public true_type{ };
366         template <> struct HasTrivialDestructor<const volatile wchar_t> : public true_type{ };
367     #endif
368 
369 #endif  // __GLIBCXX__, etc.
370 
371 } // namespace WTF
372 
373 #endif // TypeTraits_h
374