1// Copyright (c) 2006-2009 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5// This code is compiled directly on many platforms, including client 6// platforms like Windows, Mac, and embedded systems. Before making 7// any changes here, make sure that you're not breaking any platforms. 8// 9// 10// Define a small subset of tr1 type traits. The traits we define are: 11// is_integral 12// is_floating_point 13// is_pointer 14// is_reference 15// is_pod 16// has_trivial_constructor 17// has_trivial_copy 18// has_trivial_assign 19// has_trivial_destructor 20// remove_const 21// remove_volatile 22// remove_cv 23// remove_reference 24// remove_pointer 25// is_convertible 26// We can add more type traits as required. 27 28#ifndef BASE_TYPE_TRAITS_H_ 29#define BASE_TYPE_TRAITS_H_ 30 31#include "base/template_util.h" // For true_type and false_type 32#include <utility> // For pair 33 34namespace base { 35 36// is_integral is false except for the built-in integer types. 37template <class T> struct is_integral : false_type { }; 38template<> struct is_integral<bool> : true_type { }; 39template<> struct is_integral<char> : true_type { }; 40template<> struct is_integral<unsigned char> : true_type { }; 41template<> struct is_integral<signed char> : true_type { }; 42#if defined(_MSC_VER) 43// wchar_t is not by default a distinct type from unsigned short in 44// Microsoft C. 45// See http://msdn2.microsoft.com/en-us/library/dh8che7s(VS.80).aspx 46template<> struct is_integral<__wchar_t> : true_type { }; 47#else 48template<> struct is_integral<wchar_t> : true_type { }; 49#endif 50template<> struct is_integral<short> : true_type { }; 51template<> struct is_integral<unsigned short> : true_type { }; 52template<> struct is_integral<int> : true_type { }; 53template<> struct is_integral<unsigned int> : true_type { }; 54template<> struct is_integral<long> : true_type { }; 55template<> struct is_integral<unsigned long> : true_type { }; 56template<> struct is_integral<long long> : true_type { }; 57template<> struct is_integral<unsigned long long> : true_type { }; 58 59 60// is_floating_point is false except for the built-in floating-point types. 61template <class T> struct is_floating_point : false_type { }; 62template<> struct is_floating_point<float> : true_type { }; 63template<> struct is_floating_point<double> : true_type { }; 64template<> struct is_floating_point<long double> : true_type { }; 65 66 67// is_pointer is false except for pointer types. 68template <class T> struct is_pointer : false_type { }; 69template <class T> struct is_pointer<T*> : true_type { }; 70 71 72// is_reference is false except for reference types. 73template<typename T> struct is_reference : false_type {}; 74template<typename T> struct is_reference<T&> : true_type {}; 75 76 77// We can't get is_pod right without compiler help, so fail conservatively. 78// We will assume it's false except for arithmetic types and pointers, 79// and const versions thereof. Note that std::pair is not a POD. 80template <class T> struct is_pod 81 : integral_constant<bool, (is_integral<T>::value || 82 is_floating_point<T>::value || 83 is_pointer<T>::value)> { }; 84template <class T> struct is_pod<const T> : is_pod<T> { }; 85 86 87// We can't get has_trivial_constructor right without compiler help, so 88// fail conservatively. We will assume it's false except for: (1) types 89// for which is_pod is true. (2) std::pair of types with trivial 90// constructors. (3) array of a type with a trivial constructor. 91// (4) const versions thereof. 92template <class T> struct has_trivial_constructor : is_pod<T> { }; 93template <class T, class U> struct has_trivial_constructor<std::pair<T, U> > 94 : integral_constant<bool, 95 (has_trivial_constructor<T>::value && 96 has_trivial_constructor<U>::value)> { }; 97template <class A, int N> struct has_trivial_constructor<A[N]> 98 : has_trivial_constructor<A> { }; 99template <class T> struct has_trivial_constructor<const T> 100 : has_trivial_constructor<T> { }; 101 102// We can't get has_trivial_copy right without compiler help, so fail 103// conservatively. We will assume it's false except for: (1) types 104// for which is_pod is true. (2) std::pair of types with trivial copy 105// constructors. (3) array of a type with a trivial copy constructor. 106// (4) const versions thereof. 107template <class T> struct has_trivial_copy : is_pod<T> { }; 108template <class T, class U> struct has_trivial_copy<std::pair<T, U> > 109 : integral_constant<bool, 110 (has_trivial_copy<T>::value && 111 has_trivial_copy<U>::value)> { }; 112template <class A, int N> struct has_trivial_copy<A[N]> 113 : has_trivial_copy<A> { }; 114template <class T> struct has_trivial_copy<const T> : has_trivial_copy<T> { }; 115 116// We can't get has_trivial_assign right without compiler help, so fail 117// conservatively. We will assume it's false except for: (1) types 118// for which is_pod is true. (2) std::pair of types with trivial copy 119// constructors. (3) array of a type with a trivial assign constructor. 120template <class T> struct has_trivial_assign : is_pod<T> { }; 121template <class T, class U> struct has_trivial_assign<std::pair<T, U> > 122 : integral_constant<bool, 123 (has_trivial_assign<T>::value && 124 has_trivial_assign<U>::value)> { }; 125template <class A, int N> struct has_trivial_assign<A[N]> 126 : has_trivial_assign<A> { }; 127 128// We can't get has_trivial_destructor right without compiler help, so 129// fail conservatively. We will assume it's false except for: (1) types 130// for which is_pod is true. (2) std::pair of types with trivial 131// destructors. (3) array of a type with a trivial destructor. 132// (4) const versions thereof. 133template <class T> struct has_trivial_destructor : is_pod<T> { }; 134template <class T, class U> struct has_trivial_destructor<std::pair<T, U> > 135 : integral_constant<bool, 136 (has_trivial_destructor<T>::value && 137 has_trivial_destructor<U>::value)> { }; 138template <class A, int N> struct has_trivial_destructor<A[N]> 139 : has_trivial_destructor<A> { }; 140template <class T> struct has_trivial_destructor<const T> 141 : has_trivial_destructor<T> { }; 142 143// Specified by TR1 [4.7.1] 144template<typename T> struct remove_const { typedef T type; }; 145template<typename T> struct remove_const<T const> { typedef T type; }; 146template<typename T> struct remove_volatile { typedef T type; }; 147template<typename T> struct remove_volatile<T volatile> { typedef T type; }; 148template<typename T> struct remove_cv { 149 typedef typename remove_const<typename remove_volatile<T>::type>::type type; 150}; 151 152 153// Specified by TR1 [4.7.2] 154template<typename T> struct remove_reference { typedef T type; }; 155template<typename T> struct remove_reference<T&> { typedef T type; }; 156 157// Specified by TR1 [4.7.4] Pointer modifications. 158template<typename T> struct remove_pointer { typedef T type; }; 159template<typename T> struct remove_pointer<T*> { typedef T type; }; 160template<typename T> struct remove_pointer<T* const> { typedef T type; }; 161template<typename T> struct remove_pointer<T* volatile> { typedef T type; }; 162template<typename T> struct remove_pointer<T* const volatile> { 163 typedef T type; }; 164 165// Specified by TR1 [4.6] Relationships between types 166#ifndef _MSC_VER 167namespace internal { 168 169// This class is an implementation detail for is_convertible, and you 170// don't need to know how it works to use is_convertible. For those 171// who care: we declare two different functions, one whose argument is 172// of type To and one with a variadic argument list. We give them 173// return types of different size, so we can use sizeof to trick the 174// compiler into telling us which function it would have chosen if we 175// had called it with an argument of type From. See Alexandrescu's 176// _Modern C++ Design_ for more details on this sort of trick. 177 178template <typename From, typename To> 179struct ConvertHelper { 180 static small_ Test(To); 181 static big_ Test(...); 182 static From Create(); 183}; 184} // namespace internal 185 186// Inherits from true_type if From is convertible to To, false_type otherwise. 187template <typename From, typename To> 188struct is_convertible 189 : integral_constant<bool, 190 sizeof(internal::ConvertHelper<From, To>::Test( 191 internal::ConvertHelper<From, To>::Create())) 192 == sizeof(small_)> { 193}; 194#endif 195 196} // Close namespace base 197 198#endif // BASE_TYPE_TRAITS_H_ 199