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    //   RemoveReference<T>::Type
43    //   RemoveConst<T>::Type
44    //   RemoveVolatile<T>::Type
45    //   RemoveConstVolatile<T>::Type
46    //
47    //   COMPILE_ASSERT's in TypeTraits.cpp illustrate their usage and what they do.
48
49    template<typename T> struct IsInteger           { static const bool value = false; };
50    template<> struct IsInteger<bool>               { static const bool value = true; };
51    template<> struct IsInteger<char>               { static const bool value = true; };
52    template<> struct IsInteger<signed char>        { static const bool value = true; };
53    template<> struct IsInteger<unsigned char>      { static const bool value = true; };
54    template<> struct IsInteger<short>              { static const bool value = true; };
55    template<> struct IsInteger<unsigned short>     { static const bool value = true; };
56    template<> struct IsInteger<int>                { static const bool value = true; };
57    template<> struct IsInteger<unsigned int>       { static const bool value = true; };
58    template<> struct IsInteger<long>               { static const bool value = true; };
59    template<> struct IsInteger<unsigned long>      { static const bool value = true; };
60    template<> struct IsInteger<long long>          { static const bool value = true; };
61    template<> struct IsInteger<unsigned long long> { static const bool value = true; };
62#if !COMPILER(MSVC) || defined(_NATIVE_WCHAR_T_DEFINED)
63    template<> struct IsInteger<wchar_t>            { static const bool value = true; };
64#endif
65
66    template<typename T> struct IsFloatingPoint     { static const bool value = false; };
67    template<> struct IsFloatingPoint<float>        { static const bool value = true; };
68    template<> struct IsFloatingPoint<double>       { static const bool value = true; };
69    template<> struct IsFloatingPoint<long double>  { static const bool value = true; };
70
71    template<typename T> struct IsArithmetic     { static const bool value = IsInteger<T>::value || IsFloatingPoint<T>::value; };
72
73    // IsPod is misnamed as it doesn't cover all plain old data (pod) types.
74    // Specifically, it doesn't allow for enums or for structs.
75    template <typename T> struct IsPod           { static const bool value = IsArithmetic<T>::value; };
76    template <typename P> struct IsPod<P*>       { static const bool value = true; };
77
78    template<typename T> class IsConvertibleToInteger {
79        // Avoid "possible loss of data" warning when using Microsoft's C++ compiler
80        // by not converting int's to doubles.
81        template<bool performCheck, typename U> class IsConvertibleToDouble;
82        template<typename U> class IsConvertibleToDouble<false, U> {
83        public:
84            static const bool value = false;
85        };
86
87        template<typename U> class IsConvertibleToDouble<true, U> {
88            typedef char YesType;
89            struct NoType {
90                char padding[8];
91            };
92
93            static YesType floatCheck(long double);
94            static NoType floatCheck(...);
95            static T& t;
96        public:
97            static const bool value = sizeof(floatCheck(t)) == sizeof(YesType);
98        };
99
100    public:
101        static const bool value = IsInteger<T>::value || IsConvertibleToDouble<!IsInteger<T>::value, T>::value;
102    };
103
104    template <typename T, typename U> struct IsSameType {
105        static const bool value = false;
106    };
107
108    template <typename T> struct IsSameType<T, T> {
109        static const bool value = true;
110    };
111
112    template <typename T, typename U> class IsSubclass {
113        typedef char YesType;
114        struct NoType {
115            char padding[8];
116        };
117
118        static YesType subclassCheck(U*);
119        static NoType subclassCheck(...);
120        static T* t;
121    public:
122        static const bool value = sizeof(subclassCheck(t)) == sizeof(YesType);
123    };
124
125    template <typename T, template<class V> class U> class IsSubclassOfTemplate {
126        typedef char YesType;
127        struct NoType {
128            char padding[8];
129        };
130
131        template<typename W> static YesType subclassCheck(U<W>*);
132        static NoType subclassCheck(...);
133        static T* t;
134    public:
135        static const bool value = sizeof(subclassCheck(t)) == sizeof(YesType);
136    };
137
138    template <typename T, template <class V> class OuterTemplate> struct RemoveTemplate {
139        typedef T Type;
140    };
141
142    template <typename T, template <class V> class OuterTemplate> struct RemoveTemplate<OuterTemplate<T>, OuterTemplate> {
143        typedef T Type;
144    };
145
146    template <typename T> struct RemoveConst {
147        typedef T Type;
148    };
149
150    template <typename T> struct RemoveConst<const T> {
151        typedef T Type;
152    };
153
154    template <typename T> struct RemoveVolatile {
155        typedef T Type;
156    };
157
158    template <typename T> struct RemoveVolatile<volatile T> {
159        typedef T Type;
160    };
161
162    template <typename T> struct RemoveConstVolatile {
163        typedef typename RemoveVolatile<typename RemoveConst<T>::Type>::Type Type;
164    };
165
166    template <typename T> struct RemovePointer {
167        typedef T Type;
168    };
169
170    template <typename T> struct RemovePointer<T*> {
171        typedef T Type;
172    };
173
174    template <typename T> struct RemoveReference {
175        typedef T Type;
176    };
177
178    template <typename T> struct RemoveReference<T&> {
179        typedef T Type;
180    };
181
182#if (defined(__GLIBCXX__) && (__GLIBCXX__ >= 20070724) && defined(__GXX_EXPERIMENTAL_CXX0X__)) || (defined(_MSC_VER) && (_MSC_VER >= 1600))
183
184    // GCC's libstdc++ 20070724 and later supports C++ TR1 type_traits in the std namespace.
185    // VC10 (VS2010) and later support C++ TR1 type_traits in the std::tr1 namespace.
186    template<typename T> struct HasTrivialConstructor : public std::tr1::has_trivial_constructor<T> { };
187    template<typename T> struct HasTrivialDestructor : public std::tr1::has_trivial_destructor<T> { };
188
189#else
190
191    // This compiler doesn't provide type traits, so we provide basic HasTrivialConstructor
192    // and HasTrivialDestructor definitions. The definitions here include most built-in
193    // scalar types but do not include POD structs and classes. For the intended purposes of
194    // type_traits this results correct but potentially less efficient code.
195    template <typename T, T v>
196    struct IntegralConstant {
197        static const T value = v;
198        typedef T value_type;
199        typedef IntegralConstant<T, v> type;
200    };
201
202    typedef IntegralConstant<bool, true>  true_type;
203    typedef IntegralConstant<bool, false> false_type;
204
205#if defined(_MSC_VER) && (_MSC_VER >= 1400) && !defined(__INTEL_COMPILER)
206    // VC8 (VS2005) and later have built-in compiler support for HasTrivialConstructor / HasTrivialDestructor,
207    // but for some unexplained reason it doesn't work on built-in types.
208    template <typename T> struct HasTrivialConstructor : public IntegralConstant<bool, __has_trivial_constructor(T)>{ };
209    template <typename T> struct HasTrivialDestructor : public IntegralConstant<bool, __has_trivial_destructor(T)>{ };
210#else
211    template <typename T> struct HasTrivialConstructor : public false_type{ };
212    template <typename T> struct HasTrivialDestructor : public false_type{ };
213#endif
214
215    template <typename T> struct HasTrivialConstructor<T*> : public true_type{ };
216    template <typename T> struct HasTrivialDestructor<T*> : public true_type{ };
217
218    template <> struct HasTrivialConstructor<float> : public true_type{ };
219    template <> struct HasTrivialConstructor<const float> : public true_type{ };
220    template <> struct HasTrivialConstructor<volatile float> : public true_type{ };
221    template <> struct HasTrivialConstructor<const volatile float> : public true_type{ };
222
223    template <> struct HasTrivialConstructor<double> : public true_type{ };
224    template <> struct HasTrivialConstructor<const double> : public true_type{ };
225    template <> struct HasTrivialConstructor<volatile double> : public true_type{ };
226    template <> struct HasTrivialConstructor<const volatile double> : public true_type{ };
227
228    template <> struct HasTrivialConstructor<long double> : public true_type{ };
229    template <> struct HasTrivialConstructor<const long double> : public true_type{ };
230    template <> struct HasTrivialConstructor<volatile long double> : public true_type{ };
231    template <> struct HasTrivialConstructor<const volatile long double> : public true_type{ };
232
233    template <> struct HasTrivialConstructor<unsigned char> : public true_type{ };
234    template <> struct HasTrivialConstructor<const unsigned char> : public true_type{ };
235    template <> struct HasTrivialConstructor<volatile unsigned char> : public true_type{ };
236    template <> struct HasTrivialConstructor<const volatile unsigned char> : public true_type{ };
237
238    template <> struct HasTrivialConstructor<unsigned short> : public true_type{ };
239    template <> struct HasTrivialConstructor<const unsigned short> : public true_type{ };
240    template <> struct HasTrivialConstructor<volatile unsigned short> : public true_type{ };
241    template <> struct HasTrivialConstructor<const volatile unsigned short> : public true_type{ };
242
243    template <> struct HasTrivialConstructor<unsigned int> : public true_type{ };
244    template <> struct HasTrivialConstructor<const unsigned int> : public true_type{ };
245    template <> struct HasTrivialConstructor<volatile unsigned int> : public true_type{ };
246    template <> struct HasTrivialConstructor<const volatile unsigned int> : public true_type{ };
247
248    template <> struct HasTrivialConstructor<unsigned long> : public true_type{ };
249    template <> struct HasTrivialConstructor<const unsigned long> : public true_type{ };
250    template <> struct HasTrivialConstructor<volatile unsigned long> : public true_type{ };
251    template <> struct HasTrivialConstructor<const volatile unsigned long> : public true_type{ };
252
253    template <> struct HasTrivialConstructor<unsigned long long> : public true_type{ };
254    template <> struct HasTrivialConstructor<const unsigned long long> : public true_type{ };
255    template <> struct HasTrivialConstructor<volatile unsigned long long> : public true_type{ };
256    template <> struct HasTrivialConstructor<const volatile unsigned long long> : public true_type{ };
257
258    template <> struct HasTrivialConstructor<signed char> : public true_type{ };
259    template <> struct HasTrivialConstructor<const signed char> : public true_type{ };
260    template <> struct HasTrivialConstructor<volatile signed char> : public true_type{ };
261    template <> struct HasTrivialConstructor<const volatile signed char> : public true_type{ };
262
263    template <> struct HasTrivialConstructor<signed short> : public true_type{ };
264    template <> struct HasTrivialConstructor<const signed short> : public true_type{ };
265    template <> struct HasTrivialConstructor<volatile signed short> : public true_type{ };
266    template <> struct HasTrivialConstructor<const volatile signed short> : public true_type{ };
267
268    template <> struct HasTrivialConstructor<signed int> : public true_type{ };
269    template <> struct HasTrivialConstructor<const signed int> : public true_type{ };
270    template <> struct HasTrivialConstructor<volatile signed int> : public true_type{ };
271    template <> struct HasTrivialConstructor<const volatile signed int> : public true_type{ };
272
273    template <> struct HasTrivialConstructor<signed long> : public true_type{ };
274    template <> struct HasTrivialConstructor<const signed long> : public true_type{ };
275    template <> struct HasTrivialConstructor<volatile signed long> : public true_type{ };
276    template <> struct HasTrivialConstructor<const volatile signed long> : public true_type{ };
277
278    template <> struct HasTrivialConstructor<signed long long> : public true_type{ };
279    template <> struct HasTrivialConstructor<const signed long long> : public true_type{ };
280    template <> struct HasTrivialConstructor<volatile signed long long> : public true_type{ };
281    template <> struct HasTrivialConstructor<const volatile signed long long> : public true_type{ };
282
283    template <> struct HasTrivialConstructor<bool> : public true_type{ };
284    template <> struct HasTrivialConstructor<const bool> : public true_type{ };
285    template <> struct HasTrivialConstructor<volatile bool> : public true_type{ };
286    template <> struct HasTrivialConstructor<const volatile bool> : public true_type{ };
287
288    template <> struct HasTrivialConstructor<char> : public true_type{ };
289    template <> struct HasTrivialConstructor<const char> : public true_type{ };
290    template <> struct HasTrivialConstructor<volatile char> : public true_type{ };
291    template <> struct HasTrivialConstructor<const volatile char> : public true_type{ };
292
293    #if !defined(_MSC_VER) || defined(_NATIVE_WCHAR_T_DEFINED)
294        template <> struct HasTrivialConstructor<wchar_t> : public true_type{ };
295        template <> struct HasTrivialConstructor<const wchar_t> : public true_type{ };
296        template <> struct HasTrivialConstructor<volatile wchar_t> : public true_type{ };
297        template <> struct HasTrivialConstructor<const volatile wchar_t> : public true_type{ };
298    #endif
299
300    template <> struct HasTrivialDestructor<float> : public true_type{ };
301    template <> struct HasTrivialDestructor<const float> : public true_type{ };
302    template <> struct HasTrivialDestructor<volatile float> : public true_type{ };
303    template <> struct HasTrivialDestructor<const volatile float> : public true_type{ };
304
305    template <> struct HasTrivialDestructor<double> : public true_type{ };
306    template <> struct HasTrivialDestructor<const double> : public true_type{ };
307    template <> struct HasTrivialDestructor<volatile double> : public true_type{ };
308    template <> struct HasTrivialDestructor<const volatile double> : public true_type{ };
309
310    template <> struct HasTrivialDestructor<long double> : public true_type{ };
311    template <> struct HasTrivialDestructor<const long double> : public true_type{ };
312    template <> struct HasTrivialDestructor<volatile long double> : public true_type{ };
313    template <> struct HasTrivialDestructor<const volatile long double> : public true_type{ };
314
315    template <> struct HasTrivialDestructor<unsigned char> : public true_type{ };
316    template <> struct HasTrivialDestructor<const unsigned char> : public true_type{ };
317    template <> struct HasTrivialDestructor<volatile unsigned char> : public true_type{ };
318    template <> struct HasTrivialDestructor<const volatile unsigned char> : public true_type{ };
319
320    template <> struct HasTrivialDestructor<unsigned short> : public true_type{ };
321    template <> struct HasTrivialDestructor<const unsigned short> : public true_type{ };
322    template <> struct HasTrivialDestructor<volatile unsigned short> : public true_type{ };
323    template <> struct HasTrivialDestructor<const volatile unsigned short> : public true_type{ };
324
325    template <> struct HasTrivialDestructor<unsigned int> : public true_type{ };
326    template <> struct HasTrivialDestructor<const unsigned int> : public true_type{ };
327    template <> struct HasTrivialDestructor<volatile unsigned int> : public true_type{ };
328    template <> struct HasTrivialDestructor<const volatile unsigned int> : public true_type{ };
329
330    template <> struct HasTrivialDestructor<unsigned long> : public true_type{ };
331    template <> struct HasTrivialDestructor<const unsigned long> : public true_type{ };
332    template <> struct HasTrivialDestructor<volatile unsigned long> : public true_type{ };
333    template <> struct HasTrivialDestructor<const volatile unsigned long> : public true_type{ };
334
335    template <> struct HasTrivialDestructor<unsigned long long> : public true_type{ };
336    template <> struct HasTrivialDestructor<const unsigned long long> : public true_type{ };
337    template <> struct HasTrivialDestructor<volatile unsigned long long> : public true_type{ };
338    template <> struct HasTrivialDestructor<const volatile unsigned long long> : public true_type{ };
339
340    template <> struct HasTrivialDestructor<signed char> : public true_type{ };
341    template <> struct HasTrivialDestructor<const signed char> : public true_type{ };
342    template <> struct HasTrivialDestructor<volatile signed char> : public true_type{ };
343    template <> struct HasTrivialDestructor<const volatile signed char> : public true_type{ };
344
345    template <> struct HasTrivialDestructor<signed short> : public true_type{ };
346    template <> struct HasTrivialDestructor<const signed short> : public true_type{ };
347    template <> struct HasTrivialDestructor<volatile signed short> : public true_type{ };
348    template <> struct HasTrivialDestructor<const volatile signed short> : public true_type{ };
349
350    template <> struct HasTrivialDestructor<signed int> : public true_type{ };
351    template <> struct HasTrivialDestructor<const signed int> : public true_type{ };
352    template <> struct HasTrivialDestructor<volatile signed int> : public true_type{ };
353    template <> struct HasTrivialDestructor<const volatile signed int> : public true_type{ };
354
355    template <> struct HasTrivialDestructor<signed long> : public true_type{ };
356    template <> struct HasTrivialDestructor<const signed long> : public true_type{ };
357    template <> struct HasTrivialDestructor<volatile signed long> : public true_type{ };
358    template <> struct HasTrivialDestructor<const volatile signed long> : public true_type{ };
359
360    template <> struct HasTrivialDestructor<signed long long> : public true_type{ };
361    template <> struct HasTrivialDestructor<const signed long long> : public true_type{ };
362    template <> struct HasTrivialDestructor<volatile signed long long> : public true_type{ };
363    template <> struct HasTrivialDestructor<const volatile signed long long> : public true_type{ };
364
365    template <> struct HasTrivialDestructor<bool> : public true_type{ };
366    template <> struct HasTrivialDestructor<const bool> : public true_type{ };
367    template <> struct HasTrivialDestructor<volatile bool> : public true_type{ };
368    template <> struct HasTrivialDestructor<const volatile bool> : public true_type{ };
369
370    template <> struct HasTrivialDestructor<char> : public true_type{ };
371    template <> struct HasTrivialDestructor<const char> : public true_type{ };
372    template <> struct HasTrivialDestructor<volatile char> : public true_type{ };
373    template <> struct HasTrivialDestructor<const volatile char> : public true_type{ };
374
375    #if !defined(_MSC_VER) || defined(_NATIVE_WCHAR_T_DEFINED)
376        template <> struct HasTrivialDestructor<wchar_t> : public true_type{ };
377        template <> struct HasTrivialDestructor<const wchar_t> : public true_type{ };
378        template <> struct HasTrivialDestructor<volatile wchar_t> : public true_type{ };
379        template <> struct HasTrivialDestructor<const volatile wchar_t> : public true_type{ };
380    #endif
381
382#endif  // __GLIBCXX__, etc.
383
384} // namespace WTF
385
386#endif // TypeTraits_h
387