2 * Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved.
3 * Copyright (C) 2009, 2010 Google Inc. All rights reserved.
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.
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.
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.
29 // The following are provided in this file:
31 // IsInteger<T>::value
32 // IsPod<T>::value, see the definition for a note about its limitations
33 // IsConvertibleToInteger<T>::value
37 // IsSameType<T, U>::value
39 // RemovePointer<T>::Type
40 // RemoveReference<T>::Type
41 // RemoveConst<T>::Type
42 // RemoveVolatile<T>::Type
43 // RemoveConstVolatile<T>::Type
44 // RemoveExtent<T>::Type
46 // COMPILE_ASSERT's in TypeTraits.cpp illustrate their usage and what they do.
48 template<bool Predicate, class T = void> struct EnableIf;
49 template<class T> struct EnableIf<true, T> { typedef T Type; };
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; };
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; };
73 template<typename T> struct IsArithmetic { static const bool value = IsInteger<T>::value || IsFloatingPoint<T>::value; };
75 template<typename T> struct IsWeak { static const bool value = false; };
77 enum WeakHandlingFlag {
78 NoWeakHandlingInCollections,
79 WeakHandlingInCollections
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; };
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> {
93 static const bool value = false;
96 template<typename U> class IsConvertibleToDouble<true, U> {
102 static YesType floatCheck(long double);
103 static NoType floatCheck(...);
106 static const bool value = sizeof(floatCheck(t)) == sizeof(YesType);
110 static const bool value = IsInteger<T>::value || IsConvertibleToDouble<!IsInteger<T>::value, T>::value;
113 template<typename From, typename To> class IsPointerConvertible {
114 typedef char YesType;
119 static YesType convertCheck(To* x);
120 static NoType convertCheck(...);
123 Value = (sizeof(YesType) == sizeof(convertCheck(static_cast<From*>(0))))
127 template <class T> struct IsArray {
128 static const bool value = false;
131 template <class T> struct IsArray<T[]> {
132 static const bool value = true;
135 template <class T, size_t N> struct IsArray<T[N]> {
136 static const bool value = true;
140 template <typename T, typename U> struct IsSameType {
141 static const bool value = false;
144 template <typename T> struct IsSameType<T, T> {
145 static const bool value = true;
148 template <typename T, typename U> class IsSubclass {
149 typedef char YesType;
154 static YesType subclassCheck(U*);
155 static NoType subclassCheck(...);
158 static const bool value = sizeof(subclassCheck(t)) == sizeof(YesType);
161 template <typename T, template<class V> class U> class IsSubclassOfTemplate {
162 typedef char YesType;
167 template<typename W> static YesType subclassCheck(U<W>*);
168 static NoType subclassCheck(...);
171 static const bool value = sizeof(subclassCheck(t)) == sizeof(YesType);
174 template <typename T, template<typename V, size_t W> class U> class IsSubclassOfTemplateTypenameSize {
175 typedef char YesType;
180 template<typename X, size_t Y> static YesType subclassCheck(U<X, Y>*);
181 static NoType subclassCheck(...);
184 static const bool value = sizeof(subclassCheck(t)) == sizeof(YesType);
187 template <typename T, template<typename V, size_t W, typename X> class U> class IsSubclassOfTemplateTypenameSizeTypename {
188 typedef char YesType;
193 template<typename Y, size_t Z, typename A> static YesType subclassCheck(U<Y, Z, A>*);
194 static NoType subclassCheck(...);
197 static const bool value = sizeof(subclassCheck(t)) == sizeof(YesType);
200 template <typename T, template<class A, class B, class C> class U> class IsSubclassOfTemplate3 {
201 typedef char YesType;
206 template<typename D, typename E, typename F> static YesType subclassCheck(U<D, E, F>*);
207 static NoType subclassCheck(...);
210 static const bool value = sizeof(subclassCheck(t)) == sizeof(YesType);
213 template <typename T, template<class A, class B, class C, class D, class E> class U> class IsSubclassOfTemplate5 {
214 typedef char YesType;
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(...);
223 static const bool value = sizeof(subclassCheck(t)) == sizeof(YesType);
226 template <typename T, template <class V> class OuterTemplate> struct RemoveTemplate {
230 template <typename T, template <class V> class OuterTemplate> struct RemoveTemplate<OuterTemplate<T>, OuterTemplate> {
234 template <typename T> struct RemoveConst {
238 template <typename T> struct RemoveConst<const T> {
242 template <typename T> struct RemoveVolatile {
246 template <typename T> struct RemoveVolatile<volatile T> {
250 template <typename T> struct RemoveConstVolatile {
251 typedef typename RemoveVolatile<typename RemoveConst<T>::Type>::Type Type;
254 template <typename T> struct RemovePointer {
258 template <typename T> struct RemovePointer<T*> {
262 template <typename T> struct RemoveReference {
266 template <typename T> struct RemoveReference<T&> {
270 template <typename T> struct RemoveExtent {
274 template <typename T> struct RemoveExtent<T[]> {
278 template <typename T, size_t N> struct RemoveExtent<T[N]> {
282 // Determines whether this type has a vtable.
283 template <typename T> struct IsPolymorphic {
284 static const bool value = __is_polymorphic(T);
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
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> {
313 typedef char YesType;
314 typedef struct NoType {
318 template<typename V> static YesType checkHasTraceMethod(char[&V::trace != 0]);
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(...);
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);
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 {
336 static const bool value = Traits::template NeedsTracingLazily<>::value;
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;
346 #endif // TypeTraits_h