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