Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / Source / 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 <utility>
26
27 namespace WTF {
28
29     // The following are provided in this file:
30     //
31     //   IsInteger<T>::value
32     //   IsPod<T>::value, see the definition for a note about its limitations
33     //   IsConvertibleToInteger<T>::value
34     //
35     //   IsArray<T>::value
36     //
37     //   IsSameType<T, U>::value
38     //
39     //   RemovePointer<T>::Type
40     //   RemoveReference<T>::Type
41     //   RemoveConst<T>::Type
42     //   RemoveVolatile<T>::Type
43     //   RemoveConstVolatile<T>::Type
44     //   RemoveExtent<T>::Type
45     //
46     //   COMPILE_ASSERT's in TypeTraits.cpp illustrate their usage and what they do.
47
48     template<bool Predicate, class T = void> struct EnableIf;
49     template<class T> struct EnableIf<true, T> { typedef T Type; };
50
51     template<typename T> struct IsInteger           { static const bool value = false; };
52     template<> struct IsInteger<bool>               { static const bool value = true; };
53     template<> struct IsInteger<char>               { static const bool value = true; };
54     template<> struct IsInteger<signed char>        { static const bool value = true; };
55     template<> struct IsInteger<unsigned char>      { static const bool value = true; };
56     template<> struct IsInteger<short>              { static const bool value = true; };
57     template<> struct IsInteger<unsigned short>     { static const bool value = true; };
58     template<> struct IsInteger<int>                { static const bool value = true; };
59     template<> struct IsInteger<unsigned int>       { static const bool value = true; };
60     template<> struct IsInteger<long>               { static const bool value = true; };
61     template<> struct IsInteger<unsigned long>      { static const bool value = true; };
62     template<> struct IsInteger<long long>          { static const bool value = true; };
63     template<> struct IsInteger<unsigned long long> { static const bool value = true; };
64 #if !COMPILER(MSVC) || defined(_NATIVE_WCHAR_T_DEFINED)
65     template<> struct IsInteger<wchar_t>            { static const bool value = true; };
66 #endif
67
68     template<typename T> struct IsFloatingPoint     { static const bool value = false; };
69     template<> struct IsFloatingPoint<float>        { static const bool value = true; };
70     template<> struct IsFloatingPoint<double>       { static const bool value = true; };
71     template<> struct IsFloatingPoint<long double>  { static const bool value = true; };
72
73     template<typename T> struct IsArithmetic        { static const bool value = IsInteger<T>::value || IsFloatingPoint<T>::value; };
74
75     template<typename T> struct IsWeak              { static const bool value = false; };
76
77     enum WeakHandlingFlag {
78         NoWeakHandlingInCollections,
79         WeakHandlingInCollections
80     };
81
82     // IsPod is misnamed as it doesn't cover all plain old data (pod) types.
83     // Specifically, it doesn't allow for enums or for structs.
84     template <typename T> struct IsPod              { static const bool value = IsArithmetic<T>::value; };
85     template <typename P> struct IsPod<P*>          { static const bool value = true; };
86
87     template<typename T> class IsConvertibleToInteger {
88         // Avoid "possible loss of data" warning when using Microsoft's C++ compiler
89         // by not converting int's to doubles.
90         template<bool performCheck, typename U> class IsConvertibleToDouble;
91         template<typename U> class IsConvertibleToDouble<false, U> {
92         public:
93             static const bool value = false;
94         };
95
96         template<typename U> class IsConvertibleToDouble<true, U> {
97             typedef char YesType;
98             struct NoType {
99                 char padding[8];
100             };
101
102             static YesType floatCheck(long double);
103             static NoType floatCheck(...);
104             static T& t;
105         public:
106             static const bool value = sizeof(floatCheck(t)) == sizeof(YesType);
107         };
108
109     public:
110         static const bool value = IsInteger<T>::value || IsConvertibleToDouble<!IsInteger<T>::value, T>::value;
111     };
112
113     template<typename From, typename To> class IsPointerConvertible {
114         typedef char YesType;
115         struct NoType {
116             char padding[8];
117         };
118
119         static YesType convertCheck(To* x);
120         static NoType convertCheck(...);
121     public:
122         enum {
123             Value = (sizeof(YesType) == sizeof(convertCheck(static_cast<From*>(0))))
124         };
125     };
126
127     template <class T> struct IsArray {
128         static const bool value = false;
129     };
130
131     template <class T> struct IsArray<T[]> {
132         static const bool value = true;
133     };
134
135     template <class T, size_t N> struct IsArray<T[N]> {
136         static const bool value = true;
137     };
138
139
140     template <typename T, typename U> struct IsSameType {
141         static const bool value = false;
142     };
143
144     template <typename T> struct IsSameType<T, T> {
145         static const bool value = true;
146     };
147
148     template <typename T, typename U> class IsSubclass {
149         typedef char YesType;
150         struct NoType {
151             char padding[8];
152         };
153
154         static YesType subclassCheck(U*);
155         static NoType subclassCheck(...);
156         static T* t;
157     public:
158         static const bool value = sizeof(subclassCheck(t)) == sizeof(YesType);
159     };
160
161     template <typename T, template<class V> class U> class IsSubclassOfTemplate {
162         typedef char YesType;
163         struct NoType {
164             char padding[8];
165         };
166
167         template<typename W> static YesType subclassCheck(U<W>*);
168         static NoType subclassCheck(...);
169         static T* t;
170     public:
171         static const bool value = sizeof(subclassCheck(t)) == sizeof(YesType);
172     };
173
174     template <typename T, template<typename V, size_t W> class U> class IsSubclassOfTemplateTypenameSize {
175         typedef char YesType;
176         struct NoType {
177             char padding[8];
178         };
179
180         template<typename X, size_t Y> static YesType subclassCheck(U<X, Y>*);
181         static NoType subclassCheck(...);
182         static T* t;
183     public:
184         static const bool value = sizeof(subclassCheck(t)) == sizeof(YesType);
185     };
186
187     template <typename T, template<typename V, size_t W, typename X> class U> class IsSubclassOfTemplateTypenameSizeTypename {
188         typedef char YesType;
189         struct NoType {
190             char padding[8];
191         };
192
193         template<typename Y, size_t Z, typename A> static YesType subclassCheck(U<Y, Z, A>*);
194         static NoType subclassCheck(...);
195         static T* t;
196     public:
197         static const bool value = sizeof(subclassCheck(t)) == sizeof(YesType);
198     };
199
200     template <typename T, template<class A, class B, class C> class U> class IsSubclassOfTemplate3 {
201         typedef char YesType;
202         struct NoType {
203             char padding[8];
204         };
205
206         template<typename D, typename E, typename F> static YesType subclassCheck(U<D, E, F>*);
207         static NoType subclassCheck(...);
208         static T* t;
209     public:
210         static const bool value = sizeof(subclassCheck(t)) == sizeof(YesType);
211     };
212
213     template <typename T, template<class A, class B, class C, class D, class E> class U> class IsSubclassOfTemplate5 {
214         typedef char YesType;
215         struct NoType {
216             char padding[8];
217         };
218
219         template<typename F, typename G, typename H, typename I, typename J> static YesType subclassCheck(U<F, G, H, I, J>*);
220         static NoType subclassCheck(...);
221         static T* t;
222     public:
223         static const bool value = sizeof(subclassCheck(t)) == sizeof(YesType);
224     };
225
226     template <typename T, template <class V> class OuterTemplate> struct RemoveTemplate {
227         typedef T Type;
228     };
229
230     template <typename T, template <class V> class OuterTemplate> struct RemoveTemplate<OuterTemplate<T>, OuterTemplate> {
231         typedef T Type;
232     };
233
234     template <typename T> struct RemoveConst {
235         typedef T Type;
236     };
237
238     template <typename T> struct RemoveConst<const T> {
239         typedef T Type;
240     };
241
242     template <typename T> struct RemoveVolatile {
243         typedef T Type;
244     };
245
246     template <typename T> struct RemoveVolatile<volatile T> {
247         typedef T Type;
248     };
249
250     template <typename T> struct RemoveConstVolatile {
251         typedef typename RemoveVolatile<typename RemoveConst<T>::Type>::Type Type;
252     };
253
254     template <typename T> struct RemovePointer {
255         typedef T Type;
256     };
257
258     template <typename T> struct RemovePointer<T*> {
259         typedef T Type;
260     };
261
262     template <typename T> struct RemoveReference {
263         typedef T Type;
264     };
265
266     template <typename T> struct RemoveReference<T&> {
267         typedef T Type;
268     };
269
270     template <typename T> struct RemoveExtent {
271         typedef T Type;
272     };
273
274     template <typename T> struct RemoveExtent<T[]> {
275         typedef T Type;
276     };
277
278     template <typename T, size_t N> struct RemoveExtent<T[N]> {
279         typedef T Type;
280     };
281
282     // Determines whether this type has a vtable.
283     template <typename T> struct IsPolymorphic {
284         static const bool value = __is_polymorphic(T);
285     };
286
287 #define EnsurePtrConvertibleArgDecl(From, To) \
288     typename WTF::EnableIf<WTF::IsPointerConvertible<From, To>::Value, bool>::Type = true
289 #define EnsurePtrConvertibleArgDefn(From, To) \
290     typename WTF::EnableIf<WTF::IsPointerConvertible<From, To>::Value, bool>::Type
291
292 } // namespace WTF
293
294 namespace blink {
295
296 class JSONValue;
297
298 } // namespace blink
299
300 namespace WTF {
301
302     // FIXME: Disable pointer conversion checking against JSONValue.
303     // The current CodeGeneratorInspector.py generates code which upcasts to JSONValue from undefined types.
304     template<typename From> class IsPointerConvertible<From, blink::JSONValue> {
305     public:
306         enum {
307             Value = true
308         };
309     };
310
311 template<typename T>
312 class NeedsTracing {
313     typedef char YesType;
314     typedef struct NoType {
315         char padding[8];
316     } NoType;
317 #if COMPILER(MSVC)
318     template<typename V> static YesType checkHasTraceMethod(char[&V::trace != 0]);
319 #else
320     template<size_t> struct HasMethod;
321     template<typename V> static YesType checkHasTraceMethod(HasMethod<sizeof(&V::trace)>*);
322 #endif // COMPILER(MSVC)
323     template<typename V> static NoType checkHasTraceMethod(...);
324 public:
325     // We add sizeof(T) to both sides here, because we want it to fail for
326     // incomplete types. Otherwise it just assumes that incomplete types do not
327     // have a trace method, which may not be true.
328     static const bool value = sizeof(YesType) + sizeof(T) == sizeof(checkHasTraceMethod<T>(0)) + sizeof(T);
329 };
330
331 // Convenience template wrapping the NeedsTracingLazily template in
332 // Collection Traits. It helps make the code more readable.
333 template<typename Traits>
334 class ShouldBeTraced {
335 public:
336     static const bool value = Traits::template NeedsTracingLazily<>::value;
337 };
338
339 template<typename T, typename U>
340 struct NeedsTracing<std::pair<T, U> > {
341     static const bool value = NeedsTracing<T>::value || NeedsTracing<U>::value || IsWeak<T>::value || IsWeak<U>::value;
342 };
343
344 } // namespace WTF
345
346 #endif // TypeTraits_h