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
31namespace 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