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 namespace WTF { 26 27 // The following are provided in this file: 28 // 29 // IsInteger<T>::value 30 // IsPod<T>::value, see the definition for a note about its limitations 31 // IsConvertibleToInteger<T>::value 32 // 33 // IsArray<T>::value 34 // 35 // IsSameType<T, U>::value 36 // 37 // RemovePointer<T>::Type 38 // RemoveReference<T>::Type 39 // RemoveConst<T>::Type 40 // RemoveVolatile<T>::Type 41 // RemoveConstVolatile<T>::Type 42 // RemoveExtent<T>::Type 43 // 44 // COMPILE_ASSERT's in TypeTraits.cpp illustrate their usage and what they do. 45 46 template<bool Predicate, class T = void> struct EnableIf; 47 template<class T> struct EnableIf<true, T> { typedef T Type; }; 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 From, typename To> class IsPointerConvertible { 105 typedef char YesType; 106 struct NoType { 107 char padding[8]; 108 }; 109 110 static YesType convertCheck(To* x); 111 static NoType convertCheck(...); 112 public: 113 enum { 114 Value = (sizeof(YesType) == sizeof(convertCheck(static_cast<From*>(0)))) 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 #define EnsurePtrConvertibleArgDecl(From, To) \ 222 typename WTF::EnableIf<WTF::IsPointerConvertible<From, To>::Value, bool>::Type = true 223 #define EnsurePtrConvertibleArgDefn(From, To) \ 224 typename WTF::EnableIf<WTF::IsPointerConvertible<From, To>::Value, bool>::Type 225 226 } // namespace WTF 227 228 namespace WebCore { 229 230 class JSONValue; 231 232 } // namespace WebCore 233 234 namespace WTF { 235 236 // FIXME: Disable pointer conversion checking against JSONValue. 237 // The current CodeGeneratorInspector.py generates code which upcasts to JSONValue from undefined types. 238 template<typename From> class IsPointerConvertible<From, WebCore::JSONValue> { 239 public: 240 enum { 241 Value = true 242 }; 243 }; 244 245 } // namespace WTF 246 247 248 #endif // TypeTraits_h 249