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 "Platform.h" 26 27 #if (defined(__GLIBCXX__) && (__GLIBCXX__ >= 20070724) && defined(__GXX_EXPERIMENTAL_CXX0X__)) || (defined(_MSC_VER) && (_MSC_VER >= 1600)) 28 #include <type_traits> 29 #endif 30 31 namespace WTF { 32 33 // The following are provided in this file: 34 // 35 // IsInteger<T>::value 36 // IsPod<T>::value, see the definition for a note about its limitations 37 // IsConvertibleToInteger<T>::value 38 // 39 // IsSameType<T, U>::value 40 // 41 // RemovePointer<T>::Type 42 // RemoveReference<T>::Type 43 // RemoveConst<T>::Type 44 // RemoveVolatile<T>::Type 45 // RemoveConstVolatile<T>::Type 46 // 47 // COMPILE_ASSERT's in TypeTraits.cpp illustrate their usage and what they do. 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 T, typename U> struct IsSameType { 105 static const bool value = false; 106 }; 107 108 template <typename T> struct IsSameType<T, T> { 109 static const bool value = true; 110 }; 111 112 template <typename T, typename U> class IsSubclass { 113 typedef char YesType; 114 struct NoType { 115 char padding[8]; 116 }; 117 118 static YesType subclassCheck(U*); 119 static NoType subclassCheck(...); 120 static T* t; 121 public: 122 static const bool value = sizeof(subclassCheck(t)) == sizeof(YesType); 123 }; 124 125 template <typename T, template<class V> class U> class IsSubclassOfTemplate { 126 typedef char YesType; 127 struct NoType { 128 char padding[8]; 129 }; 130 131 template<typename W> static YesType subclassCheck(U<W>*); 132 static NoType subclassCheck(...); 133 static T* t; 134 public: 135 static const bool value = sizeof(subclassCheck(t)) == sizeof(YesType); 136 }; 137 138 template <typename T, template <class V> class OuterTemplate> struct RemoveTemplate { 139 typedef T Type; 140 }; 141 142 template <typename T, template <class V> class OuterTemplate> struct RemoveTemplate<OuterTemplate<T>, OuterTemplate> { 143 typedef T Type; 144 }; 145 146 template <typename T> struct RemoveConst { 147 typedef T Type; 148 }; 149 150 template <typename T> struct RemoveConst<const T> { 151 typedef T Type; 152 }; 153 154 template <typename T> struct RemoveVolatile { 155 typedef T Type; 156 }; 157 158 template <typename T> struct RemoveVolatile<volatile T> { 159 typedef T Type; 160 }; 161 162 template <typename T> struct RemoveConstVolatile { 163 typedef typename RemoveVolatile<typename RemoveConst<T>::Type>::Type Type; 164 }; 165 166 template <typename T> struct RemovePointer { 167 typedef T Type; 168 }; 169 170 template <typename T> struct RemovePointer<T*> { 171 typedef T Type; 172 }; 173 174 template <typename T> struct RemoveReference { 175 typedef T Type; 176 }; 177 178 template <typename T> struct RemoveReference<T&> { 179 typedef T Type; 180 }; 181 182 #if (defined(__GLIBCXX__) && (__GLIBCXX__ >= 20070724) && defined(__GXX_EXPERIMENTAL_CXX0X__)) || (defined(_MSC_VER) && (_MSC_VER >= 1600)) 183 184 // GCC's libstdc++ 20070724 and later supports C++ TR1 type_traits in the std namespace. 185 // VC10 (VS2010) and later support C++ TR1 type_traits in the std::tr1 namespace. 186 template<typename T> struct HasTrivialConstructor : public std::tr1::has_trivial_constructor<T> { }; 187 template<typename T> struct HasTrivialDestructor : public std::tr1::has_trivial_destructor<T> { }; 188 189 #else 190 191 // This compiler doesn't provide type traits, so we provide basic HasTrivialConstructor 192 // and HasTrivialDestructor definitions. The definitions here include most built-in 193 // scalar types but do not include POD structs and classes. For the intended purposes of 194 // type_traits this results correct but potentially less efficient code. 195 template <typename T, T v> 196 struct IntegralConstant { 197 static const T value = v; 198 typedef T value_type; 199 typedef IntegralConstant<T, v> type; 200 }; 201 202 typedef IntegralConstant<bool, true> true_type; 203 typedef IntegralConstant<bool, false> false_type; 204 205 #if defined(_MSC_VER) && (_MSC_VER >= 1400) && !defined(__INTEL_COMPILER) 206 // VC8 (VS2005) and later have built-in compiler support for HasTrivialConstructor / HasTrivialDestructor, 207 // but for some unexplained reason it doesn't work on built-in types. 208 template <typename T> struct HasTrivialConstructor : public IntegralConstant<bool, __has_trivial_constructor(T)>{ }; 209 template <typename T> struct HasTrivialDestructor : public IntegralConstant<bool, __has_trivial_destructor(T)>{ }; 210 #else 211 template <typename T> struct HasTrivialConstructor : public false_type{ }; 212 template <typename T> struct HasTrivialDestructor : public false_type{ }; 213 #endif 214 215 template <typename T> struct HasTrivialConstructor<T*> : public true_type{ }; 216 template <typename T> struct HasTrivialDestructor<T*> : public true_type{ }; 217 218 template <> struct HasTrivialConstructor<float> : public true_type{ }; 219 template <> struct HasTrivialConstructor<const float> : public true_type{ }; 220 template <> struct HasTrivialConstructor<volatile float> : public true_type{ }; 221 template <> struct HasTrivialConstructor<const volatile float> : public true_type{ }; 222 223 template <> struct HasTrivialConstructor<double> : public true_type{ }; 224 template <> struct HasTrivialConstructor<const double> : public true_type{ }; 225 template <> struct HasTrivialConstructor<volatile double> : public true_type{ }; 226 template <> struct HasTrivialConstructor<const volatile double> : public true_type{ }; 227 228 template <> struct HasTrivialConstructor<long double> : public true_type{ }; 229 template <> struct HasTrivialConstructor<const long double> : public true_type{ }; 230 template <> struct HasTrivialConstructor<volatile long double> : public true_type{ }; 231 template <> struct HasTrivialConstructor<const volatile long double> : public true_type{ }; 232 233 template <> struct HasTrivialConstructor<unsigned char> : public true_type{ }; 234 template <> struct HasTrivialConstructor<const unsigned char> : public true_type{ }; 235 template <> struct HasTrivialConstructor<volatile unsigned char> : public true_type{ }; 236 template <> struct HasTrivialConstructor<const volatile unsigned char> : public true_type{ }; 237 238 template <> struct HasTrivialConstructor<unsigned short> : public true_type{ }; 239 template <> struct HasTrivialConstructor<const unsigned short> : public true_type{ }; 240 template <> struct HasTrivialConstructor<volatile unsigned short> : public true_type{ }; 241 template <> struct HasTrivialConstructor<const volatile unsigned short> : public true_type{ }; 242 243 template <> struct HasTrivialConstructor<unsigned int> : public true_type{ }; 244 template <> struct HasTrivialConstructor<const unsigned int> : public true_type{ }; 245 template <> struct HasTrivialConstructor<volatile unsigned int> : public true_type{ }; 246 template <> struct HasTrivialConstructor<const volatile unsigned int> : public true_type{ }; 247 248 template <> struct HasTrivialConstructor<unsigned long> : public true_type{ }; 249 template <> struct HasTrivialConstructor<const unsigned long> : public true_type{ }; 250 template <> struct HasTrivialConstructor<volatile unsigned long> : public true_type{ }; 251 template <> struct HasTrivialConstructor<const volatile unsigned long> : public true_type{ }; 252 253 template <> struct HasTrivialConstructor<unsigned long long> : public true_type{ }; 254 template <> struct HasTrivialConstructor<const unsigned long long> : public true_type{ }; 255 template <> struct HasTrivialConstructor<volatile unsigned long long> : public true_type{ }; 256 template <> struct HasTrivialConstructor<const volatile unsigned long long> : public true_type{ }; 257 258 template <> struct HasTrivialConstructor<signed char> : public true_type{ }; 259 template <> struct HasTrivialConstructor<const signed char> : public true_type{ }; 260 template <> struct HasTrivialConstructor<volatile signed char> : public true_type{ }; 261 template <> struct HasTrivialConstructor<const volatile signed char> : public true_type{ }; 262 263 template <> struct HasTrivialConstructor<signed short> : public true_type{ }; 264 template <> struct HasTrivialConstructor<const signed short> : public true_type{ }; 265 template <> struct HasTrivialConstructor<volatile signed short> : public true_type{ }; 266 template <> struct HasTrivialConstructor<const volatile signed short> : public true_type{ }; 267 268 template <> struct HasTrivialConstructor<signed int> : public true_type{ }; 269 template <> struct HasTrivialConstructor<const signed int> : public true_type{ }; 270 template <> struct HasTrivialConstructor<volatile signed int> : public true_type{ }; 271 template <> struct HasTrivialConstructor<const volatile signed int> : public true_type{ }; 272 273 template <> struct HasTrivialConstructor<signed long> : public true_type{ }; 274 template <> struct HasTrivialConstructor<const signed long> : public true_type{ }; 275 template <> struct HasTrivialConstructor<volatile signed long> : public true_type{ }; 276 template <> struct HasTrivialConstructor<const volatile signed long> : public true_type{ }; 277 278 template <> struct HasTrivialConstructor<signed long long> : public true_type{ }; 279 template <> struct HasTrivialConstructor<const signed long long> : public true_type{ }; 280 template <> struct HasTrivialConstructor<volatile signed long long> : public true_type{ }; 281 template <> struct HasTrivialConstructor<const volatile signed long long> : public true_type{ }; 282 283 template <> struct HasTrivialConstructor<bool> : public true_type{ }; 284 template <> struct HasTrivialConstructor<const bool> : public true_type{ }; 285 template <> struct HasTrivialConstructor<volatile bool> : public true_type{ }; 286 template <> struct HasTrivialConstructor<const volatile bool> : public true_type{ }; 287 288 template <> struct HasTrivialConstructor<char> : public true_type{ }; 289 template <> struct HasTrivialConstructor<const char> : public true_type{ }; 290 template <> struct HasTrivialConstructor<volatile char> : public true_type{ }; 291 template <> struct HasTrivialConstructor<const volatile char> : public true_type{ }; 292 293 #if !defined(_MSC_VER) || defined(_NATIVE_WCHAR_T_DEFINED) 294 template <> struct HasTrivialConstructor<wchar_t> : public true_type{ }; 295 template <> struct HasTrivialConstructor<const wchar_t> : public true_type{ }; 296 template <> struct HasTrivialConstructor<volatile wchar_t> : public true_type{ }; 297 template <> struct HasTrivialConstructor<const volatile wchar_t> : public true_type{ }; 298 #endif 299 300 template <> struct HasTrivialDestructor<float> : public true_type{ }; 301 template <> struct HasTrivialDestructor<const float> : public true_type{ }; 302 template <> struct HasTrivialDestructor<volatile float> : public true_type{ }; 303 template <> struct HasTrivialDestructor<const volatile float> : public true_type{ }; 304 305 template <> struct HasTrivialDestructor<double> : public true_type{ }; 306 template <> struct HasTrivialDestructor<const double> : public true_type{ }; 307 template <> struct HasTrivialDestructor<volatile double> : public true_type{ }; 308 template <> struct HasTrivialDestructor<const volatile double> : public true_type{ }; 309 310 template <> struct HasTrivialDestructor<long double> : public true_type{ }; 311 template <> struct HasTrivialDestructor<const long double> : public true_type{ }; 312 template <> struct HasTrivialDestructor<volatile long double> : public true_type{ }; 313 template <> struct HasTrivialDestructor<const volatile long double> : public true_type{ }; 314 315 template <> struct HasTrivialDestructor<unsigned char> : public true_type{ }; 316 template <> struct HasTrivialDestructor<const unsigned char> : public true_type{ }; 317 template <> struct HasTrivialDestructor<volatile unsigned char> : public true_type{ }; 318 template <> struct HasTrivialDestructor<const volatile unsigned char> : public true_type{ }; 319 320 template <> struct HasTrivialDestructor<unsigned short> : public true_type{ }; 321 template <> struct HasTrivialDestructor<const unsigned short> : public true_type{ }; 322 template <> struct HasTrivialDestructor<volatile unsigned short> : public true_type{ }; 323 template <> struct HasTrivialDestructor<const volatile unsigned short> : public true_type{ }; 324 325 template <> struct HasTrivialDestructor<unsigned int> : public true_type{ }; 326 template <> struct HasTrivialDestructor<const unsigned int> : public true_type{ }; 327 template <> struct HasTrivialDestructor<volatile unsigned int> : public true_type{ }; 328 template <> struct HasTrivialDestructor<const volatile unsigned int> : public true_type{ }; 329 330 template <> struct HasTrivialDestructor<unsigned long> : public true_type{ }; 331 template <> struct HasTrivialDestructor<const unsigned long> : public true_type{ }; 332 template <> struct HasTrivialDestructor<volatile unsigned long> : public true_type{ }; 333 template <> struct HasTrivialDestructor<const volatile unsigned long> : public true_type{ }; 334 335 template <> struct HasTrivialDestructor<unsigned long long> : public true_type{ }; 336 template <> struct HasTrivialDestructor<const unsigned long long> : public true_type{ }; 337 template <> struct HasTrivialDestructor<volatile unsigned long long> : public true_type{ }; 338 template <> struct HasTrivialDestructor<const volatile unsigned long long> : public true_type{ }; 339 340 template <> struct HasTrivialDestructor<signed char> : public true_type{ }; 341 template <> struct HasTrivialDestructor<const signed char> : public true_type{ }; 342 template <> struct HasTrivialDestructor<volatile signed char> : public true_type{ }; 343 template <> struct HasTrivialDestructor<const volatile signed char> : public true_type{ }; 344 345 template <> struct HasTrivialDestructor<signed short> : public true_type{ }; 346 template <> struct HasTrivialDestructor<const signed short> : public true_type{ }; 347 template <> struct HasTrivialDestructor<volatile signed short> : public true_type{ }; 348 template <> struct HasTrivialDestructor<const volatile signed short> : public true_type{ }; 349 350 template <> struct HasTrivialDestructor<signed int> : public true_type{ }; 351 template <> struct HasTrivialDestructor<const signed int> : public true_type{ }; 352 template <> struct HasTrivialDestructor<volatile signed int> : public true_type{ }; 353 template <> struct HasTrivialDestructor<const volatile signed int> : public true_type{ }; 354 355 template <> struct HasTrivialDestructor<signed long> : public true_type{ }; 356 template <> struct HasTrivialDestructor<const signed long> : public true_type{ }; 357 template <> struct HasTrivialDestructor<volatile signed long> : public true_type{ }; 358 template <> struct HasTrivialDestructor<const volatile signed long> : public true_type{ }; 359 360 template <> struct HasTrivialDestructor<signed long long> : public true_type{ }; 361 template <> struct HasTrivialDestructor<const signed long long> : public true_type{ }; 362 template <> struct HasTrivialDestructor<volatile signed long long> : public true_type{ }; 363 template <> struct HasTrivialDestructor<const volatile signed long long> : public true_type{ }; 364 365 template <> struct HasTrivialDestructor<bool> : public true_type{ }; 366 template <> struct HasTrivialDestructor<const bool> : public true_type{ }; 367 template <> struct HasTrivialDestructor<volatile bool> : public true_type{ }; 368 template <> struct HasTrivialDestructor<const volatile bool> : public true_type{ }; 369 370 template <> struct HasTrivialDestructor<char> : public true_type{ }; 371 template <> struct HasTrivialDestructor<const char> : public true_type{ }; 372 template <> struct HasTrivialDestructor<volatile char> : public true_type{ }; 373 template <> struct HasTrivialDestructor<const volatile char> : public true_type{ }; 374 375 #if !defined(_MSC_VER) || defined(_NATIVE_WCHAR_T_DEFINED) 376 template <> struct HasTrivialDestructor<wchar_t> : public true_type{ }; 377 template <> struct HasTrivialDestructor<const wchar_t> : public true_type{ }; 378 template <> struct HasTrivialDestructor<volatile wchar_t> : public true_type{ }; 379 template <> struct HasTrivialDestructor<const volatile wchar_t> : public true_type{ }; 380 #endif 381 382 #endif // __GLIBCXX__, etc. 383 384 } // namespace WTF 385 386 #endif // TypeTraits_h 387