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