summaryrefslogtreecommitdiff
path: root/src/3rdparty/javascriptcore/JavaScriptCore/wtf/TypeTraits.h
blob: 92e9c3b0b66db13d9eefa28b47ad596135a4e21e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
 /*
 * Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved.
 * Copyright (C) 2009, 2010 Google Inc. All rights reserved.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public License
 * along with this library; see the file COPYING.LIB.  If not, write to
 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 *
 */

#ifndef TypeTraits_h
#define TypeTraits_h

#include "Platform.h"

#if (defined(__GLIBCXX__) && (__GLIBCXX__ >= 20070724) && defined(__GXX_EXPERIMENTAL_CXX0X__)) || (defined(_MSC_VER) && (_MSC_VER >= 1600))
#include <type_traits>
#if defined(__GLIBCXX__) && (__GLIBCXX__ >= 20070724) && defined(__GXX_EXPERIMENTAL_CXX0X__)
#include <tr1/memory>
#endif
#endif

namespace WTF {

    // The following are provided in this file:
    //
    //   IsInteger<T>::value
    //   IsPod<T>::value, see the definition for a note about its limitations
    //   IsConvertibleToInteger<T>::value
    //
    //   IsSameType<T, U>::value
    //
    //   RemovePointer<T>::Type
    //   RemoveConst<T>::Type
    //   RemoveVolatile<T>::Type
    //   RemoveConstVolatile<T>::Type
    //
    //   COMPILE_ASSERT's in TypeTraits.cpp illustrate their usage and what they do.

    template<typename T> struct IsInteger           { static const bool value = false; };
    template<> struct IsInteger<bool>               { static const bool value = true; };
    template<> struct IsInteger<char>               { static const bool value = true; };
    template<> struct IsInteger<signed char>        { static const bool value = true; };
    template<> struct IsInteger<unsigned char>      { static const bool value = true; };
    template<> struct IsInteger<short>              { static const bool value = true; };
    template<> struct IsInteger<unsigned short>     { static const bool value = true; };
    template<> struct IsInteger<int>                { static const bool value = true; };
    template<> struct IsInteger<unsigned int>       { static const bool value = true; };
    template<> struct IsInteger<long>               { static const bool value = true; };
    template<> struct IsInteger<unsigned long>      { static const bool value = true; };
    template<> struct IsInteger<long long>          { static const bool value = true; };
    template<> struct IsInteger<unsigned long long> { static const bool value = true; };
#if !COMPILER(MSVC) || defined(_NATIVE_WCHAR_T_DEFINED)
    template<> struct IsInteger<wchar_t>            { static const bool value = true; };
#endif

    // IsPod is misnamed as it doesn't cover all plain old data (pod) types.
    // Specifically, it doesn't allow for enums or for structs.
    template <typename T> struct IsPod           { static const bool value = IsInteger<T>::value; };
    template <> struct IsPod<float>              { static const bool value = true; };
    template <> struct IsPod<double>             { static const bool value = true; };
    template <> struct IsPod<long double>        { static const bool value = true; };
    template <typename P> struct IsPod<P*>       { static const bool value = true; };

    // Avoid "possible loss of data" warning when using Microsoft's C++ compiler
    // by not converting int's to doubles.
    template<bool performCheck, typename U> class CheckedIsConvertibleToDouble;
    template<typename U> class CheckedIsConvertibleToDouble<false, U> {
    public:
        static const bool value = false;
    };

    template<typename U> class CheckedIsConvertibleToDouble<true, U> {
        typedef char YesType;
        struct NoType {
            char padding[8];
        };

        static YesType floatCheck(long double);
        static NoType floatCheck(...);
        static U& t;
    public:
        static const bool value = sizeof(floatCheck(t)) == sizeof(YesType);
    };

    template<typename T> class IsConvertibleToInteger {
    public:
        static const bool value = IsInteger<T>::value || CheckedIsConvertibleToDouble<!IsInteger<T>::value, T>::value;
    };

    template <typename T, typename U> struct IsSameType {
        static const bool value = false;
    };

    template <typename T> struct IsSameType<T, T> {
        static const bool value = true;
    };

    template <typename T, typename U> class IsSubclass {
        typedef char YesType;
        struct NoType {
            char padding[8];
        };

        static YesType subclassCheck(U*);
        static NoType subclassCheck(...);
        static T* t;
    public:
        static const bool value = sizeof(subclassCheck(t)) == sizeof(YesType);
    };

    template <typename T, template<class V> class U> class IsSubclassOfTemplate {
        typedef char YesType;
        struct NoType {
            char padding[8];
        };

        template<typename W> static YesType subclassCheck(U<W>*);
        static NoType subclassCheck(...);
        static T* t;
    public:
        static const bool value = sizeof(subclassCheck(t)) == sizeof(YesType);
    };

    template <typename T, template <class V> class OuterTemplate> struct RemoveTemplate {
        typedef T Type;
    };

    template <typename T, template <class V> class OuterTemplate> struct RemoveTemplate<OuterTemplate<T>, OuterTemplate> {
        typedef T Type;
    };

    template <typename T> struct RemoveConst {
        typedef T Type;
    };

    template <typename T> struct RemoveConst<const T> {
        typedef T Type;
    };

    template <typename T> struct RemoveVolatile {
        typedef T Type;
    };

    template <typename T> struct RemoveVolatile<volatile T> {
        typedef T Type;
    };

    template <typename T> struct RemoveConstVolatile {
        typedef typename RemoveVolatile<typename RemoveConst<T>::Type>::Type Type;
    };

    template <typename T> struct RemovePointer {
        typedef T Type;
    };

    template <typename T> struct RemovePointer<T*> {
        typedef T Type;
    };

#if COMPILER(CLANG) || GCC_VERSION_AT_LEAST(4, 6, 0) || (defined(_MSC_VER) && (_MSC_VER >= 1400) && (_MSC_VER < 1600) && !defined(__INTEL_COMPILER))
    // VC8 (VS2005) and later has __has_trivial_constructor and __has_trivial_destructor,
    // but the implementation returns false for built-in types. We add the extra IsPod condition to
    // work around this.
    template <typename T> struct HasTrivialConstructor {
        static const bool value = __has_trivial_constructor(T) || IsPod<RemoveConstVolatile<T> >::value;
    };
    template <typename T> struct HasTrivialDestructor {
        static const bool value = __has_trivial_destructor(T) || IsPod<RemoveConstVolatile<T> >::value;
    };
#elif (defined(__GLIBCXX__) && (__GLIBCXX__ >= 20070724) && defined(__GXX_EXPERIMENTAL_CXX0X__)) || (defined(_MSC_VER) && (_MSC_VER >= 1600 && _MSC_VER < 1900))
    // GCC's libstdc++ 20070724 and later supports C++ TR1 type_traits in the std namespace.
    // VC10 (VS2010) and later support C++ TR1 type_traits in the std::tr1 namespace.
    template<typename T> struct HasTrivialConstructor : public std::tr1::has_trivial_constructor<T> { };
    template<typename T> struct HasTrivialDestructor : public std::tr1::has_trivial_destructor<T> { };
#else

    // This compiler doesn't provide type traits, so we provide basic HasTrivialConstructor
    // and HasTrivialDestructor definitions. The definitions here include most built-in
    // scalar types but do not include POD structs and classes. For the intended purposes of
    // type_traits this results correct but potentially less efficient code.
    template <typename T, T v>
    struct IntegralConstant {
        static const T value = v;
        typedef T value_type;
        typedef IntegralConstant<T, v> type;
    };

    typedef IntegralConstant<bool, true>  true_type;
    typedef IntegralConstant<bool, false> false_type;

    template <typename T> struct HasTrivialConstructor : public false_type{ };
    template <typename T> struct HasTrivialDestructor : public false_type{ };

    template <typename T> struct HasTrivialConstructor<T*> : public true_type{ };
    template <typename T> struct HasTrivialDestructor<T*> : public true_type{ };

    template <> struct HasTrivialConstructor<float> : public true_type{ };
    template <> struct HasTrivialConstructor<const float> : public true_type{ };
    template <> struct HasTrivialConstructor<volatile float> : public true_type{ };
    template <> struct HasTrivialConstructor<const volatile float> : public true_type{ };

    template <> struct HasTrivialConstructor<double> : public true_type{ };
    template <> struct HasTrivialConstructor<const double> : public true_type{ };
    template <> struct HasTrivialConstructor<volatile double> : public true_type{ };
    template <> struct HasTrivialConstructor<const volatile double> : public true_type{ };

    template <> struct HasTrivialConstructor<long double> : public true_type{ };
    template <> struct HasTrivialConstructor<const long double> : public true_type{ };
    template <> struct HasTrivialConstructor<volatile long double> : public true_type{ };
    template <> struct HasTrivialConstructor<const volatile long double> : public true_type{ };

    template <> struct HasTrivialConstructor<unsigned char> : public true_type{ };
    template <> struct HasTrivialConstructor<const unsigned char> : public true_type{ };
    template <> struct HasTrivialConstructor<volatile unsigned char> : public true_type{ };
    template <> struct HasTrivialConstructor<const volatile unsigned char> : public true_type{ };

    template <> struct HasTrivialConstructor<unsigned short> : public true_type{ };
    template <> struct HasTrivialConstructor<const unsigned short> : public true_type{ };
    template <> struct HasTrivialConstructor<volatile unsigned short> : public true_type{ };
    template <> struct HasTrivialConstructor<const volatile unsigned short> : public true_type{ };

    template <> struct HasTrivialConstructor<unsigned int> : public true_type{ };
    template <> struct HasTrivialConstructor<const unsigned int> : public true_type{ };
    template <> struct HasTrivialConstructor<volatile unsigned int> : public true_type{ };
    template <> struct HasTrivialConstructor<const volatile unsigned int> : public true_type{ };

    template <> struct HasTrivialConstructor<unsigned long> : public true_type{ };
    template <> struct HasTrivialConstructor<const unsigned long> : public true_type{ };
    template <> struct HasTrivialConstructor<volatile unsigned long> : public true_type{ };
    template <> struct HasTrivialConstructor<const volatile unsigned long> : public true_type{ };

    template <> struct HasTrivialConstructor<unsigned long long> : public true_type{ };
    template <> struct HasTrivialConstructor<const unsigned long long> : public true_type{ };
    template <> struct HasTrivialConstructor<volatile unsigned long long> : public true_type{ };
    template <> struct HasTrivialConstructor<const volatile unsigned long long> : public true_type{ };

    template <> struct HasTrivialConstructor<signed char> : public true_type{ };
    template <> struct HasTrivialConstructor<const signed char> : public true_type{ };
    template <> struct HasTrivialConstructor<volatile signed char> : public true_type{ };
    template <> struct HasTrivialConstructor<const volatile signed char> : public true_type{ };

    template <> struct HasTrivialConstructor<signed short> : public true_type{ };
    template <> struct HasTrivialConstructor<const signed short> : public true_type{ };
    template <> struct HasTrivialConstructor<volatile signed short> : public true_type{ };
    template <> struct HasTrivialConstructor<const volatile signed short> : public true_type{ };

    template <> struct HasTrivialConstructor<signed int> : public true_type{ };
    template <> struct HasTrivialConstructor<const signed int> : public true_type{ };
    template <> struct HasTrivialConstructor<volatile signed int> : public true_type{ };
    template <> struct HasTrivialConstructor<const volatile signed int> : public true_type{ };

    template <> struct HasTrivialConstructor<signed long> : public true_type{ };
    template <> struct HasTrivialConstructor<const signed long> : public true_type{ };
    template <> struct HasTrivialConstructor<volatile signed long> : public true_type{ };
    template <> struct HasTrivialConstructor<const volatile signed long> : public true_type{ };

    template <> struct HasTrivialConstructor<signed long long> : public true_type{ };
    template <> struct HasTrivialConstructor<const signed long long> : public true_type{ };
    template <> struct HasTrivialConstructor<volatile signed long long> : public true_type{ };
    template <> struct HasTrivialConstructor<const volatile signed long long> : public true_type{ };

    template <> struct HasTrivialConstructor<bool> : public true_type{ };
    template <> struct HasTrivialConstructor<const bool> : public true_type{ };
    template <> struct HasTrivialConstructor<volatile bool> : public true_type{ };
    template <> struct HasTrivialConstructor<const volatile bool> : public true_type{ };

    template <> struct HasTrivialConstructor<char> : public true_type{ };
    template <> struct HasTrivialConstructor<const char> : public true_type{ };
    template <> struct HasTrivialConstructor<volatile char> : public true_type{ };
    template <> struct HasTrivialConstructor<const volatile char> : public true_type{ };

    #if !defined(_MSC_VER) || defined(_NATIVE_WCHAR_T_DEFINED)
        template <> struct HasTrivialConstructor<wchar_t> : public true_type{ };
        template <> struct HasTrivialConstructor<const wchar_t> : public true_type{ };
        template <> struct HasTrivialConstructor<volatile wchar_t> : public true_type{ };
        template <> struct HasTrivialConstructor<const volatile wchar_t> : public true_type{ };
    #endif

    template <> struct HasTrivialDestructor<float> : public true_type{ };
    template <> struct HasTrivialDestructor<const float> : public true_type{ };
    template <> struct HasTrivialDestructor<volatile float> : public true_type{ };
    template <> struct HasTrivialDestructor<const volatile float> : public true_type{ };

    template <> struct HasTrivialDestructor<double> : public true_type{ };
    template <> struct HasTrivialDestructor<const double> : public true_type{ };
    template <> struct HasTrivialDestructor<volatile double> : public true_type{ };
    template <> struct HasTrivialDestructor<const volatile double> : public true_type{ };

    template <> struct HasTrivialDestructor<long double> : public true_type{ };
    template <> struct HasTrivialDestructor<const long double> : public true_type{ };
    template <> struct HasTrivialDestructor<volatile long double> : public true_type{ };
    template <> struct HasTrivialDestructor<const volatile long double> : public true_type{ };

    template <> struct HasTrivialDestructor<unsigned char> : public true_type{ };
    template <> struct HasTrivialDestructor<const unsigned char> : public true_type{ };
    template <> struct HasTrivialDestructor<volatile unsigned char> : public true_type{ };
    template <> struct HasTrivialDestructor<const volatile unsigned char> : public true_type{ };

    template <> struct HasTrivialDestructor<unsigned short> : public true_type{ };
    template <> struct HasTrivialDestructor<const unsigned short> : public true_type{ };
    template <> struct HasTrivialDestructor<volatile unsigned short> : public true_type{ };
    template <> struct HasTrivialDestructor<const volatile unsigned short> : public true_type{ };

    template <> struct HasTrivialDestructor<unsigned int> : public true_type{ };
    template <> struct HasTrivialDestructor<const unsigned int> : public true_type{ };
    template <> struct HasTrivialDestructor<volatile unsigned int> : public true_type{ };
    template <> struct HasTrivialDestructor<const volatile unsigned int> : public true_type{ };

    template <> struct HasTrivialDestructor<unsigned long> : public true_type{ };
    template <> struct HasTrivialDestructor<const unsigned long> : public true_type{ };
    template <> struct HasTrivialDestructor<volatile unsigned long> : public true_type{ };
    template <> struct HasTrivialDestructor<const volatile unsigned long> : public true_type{ };

    template <> struct HasTrivialDestructor<unsigned long long> : public true_type{ };
    template <> struct HasTrivialDestructor<const unsigned long long> : public true_type{ };
    template <> struct HasTrivialDestructor<volatile unsigned long long> : public true_type{ };
    template <> struct HasTrivialDestructor<const volatile unsigned long long> : public true_type{ };

    template <> struct HasTrivialDestructor<signed char> : public true_type{ };
    template <> struct HasTrivialDestructor<const signed char> : public true_type{ };
    template <> struct HasTrivialDestructor<volatile signed char> : public true_type{ };
    template <> struct HasTrivialDestructor<const volatile signed char> : public true_type{ };

    template <> struct HasTrivialDestructor<signed short> : public true_type{ };
    template <> struct HasTrivialDestructor<const signed short> : public true_type{ };
    template <> struct HasTrivialDestructor<volatile signed short> : public true_type{ };
    template <> struct HasTrivialDestructor<const volatile signed short> : public true_type{ };

    template <> struct HasTrivialDestructor<signed int> : public true_type{ };
    template <> struct HasTrivialDestructor<const signed int> : public true_type{ };
    template <> struct HasTrivialDestructor<volatile signed int> : public true_type{ };
    template <> struct HasTrivialDestructor<const volatile signed int> : public true_type{ };

    template <> struct HasTrivialDestructor<signed long> : public true_type{ };
    template <> struct HasTrivialDestructor<const signed long> : public true_type{ };
    template <> struct HasTrivialDestructor<volatile signed long> : public true_type{ };
    template <> struct HasTrivialDestructor<const volatile signed long> : public true_type{ };

    template <> struct HasTrivialDestructor<signed long long> : public true_type{ };
    template <> struct HasTrivialDestructor<const signed long long> : public true_type{ };
    template <> struct HasTrivialDestructor<volatile signed long long> : public true_type{ };
    template <> struct HasTrivialDestructor<const volatile signed long long> : public true_type{ };

    template <> struct HasTrivialDestructor<bool> : public true_type{ };
    template <> struct HasTrivialDestructor<const bool> : public true_type{ };
    template <> struct HasTrivialDestructor<volatile bool> : public true_type{ };
    template <> struct HasTrivialDestructor<const volatile bool> : public true_type{ };

    template <> struct HasTrivialDestructor<char> : public true_type{ };
    template <> struct HasTrivialDestructor<const char> : public true_type{ };
    template <> struct HasTrivialDestructor<volatile char> : public true_type{ };
    template <> struct HasTrivialDestructor<const volatile char> : public true_type{ };

    #if !defined(_MSC_VER) || defined(_NATIVE_WCHAR_T_DEFINED)
        template <> struct HasTrivialDestructor<wchar_t> : public true_type{ };
        template <> struct HasTrivialDestructor<const wchar_t> : public true_type{ };
        template <> struct HasTrivialDestructor<volatile wchar_t> : public true_type{ };
        template <> struct HasTrivialDestructor<const volatile wchar_t> : public true_type{ };
    #endif

#endif  // __GLIBCXX__, etc.

} // namespace WTF

#endif // TypeTraits_h