util
type_traits.h
00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051 #ifndef BASE_TYPE_TRAITS_H_
00052 #define BASE_TYPE_TRAITS_H_
00053
00054 #if defined(Q_OS_WIN)
00055 #include "sparsehash/sparseconfig_windows.h"
00056 #else
00057 #include "sparsehash/sparseconfig.h"
00058 #endif
00059 #include <utility>
00060
00061 _START_GOOGLE_NAMESPACE_
00062
00063
00064
00065
00066
00067
00068 template<class T, T v>
00069 struct integral_constant {
00070 static const T value = v;
00071 typedef T value_type;
00072 typedef integral_constant<T, v> type;
00073 };
00074
00075 template <class T, T v> const T integral_constant<T, v>::value;
00076
00077
00078
00079 typedef integral_constant<bool, true> true_type;
00080 typedef integral_constant<bool, false> false_type;
00081
00082
00083
00084 typedef char small_;
00085
00086 struct big_ {
00087 char dummy[2];
00088 };
00089
00090
00091 template <class T> struct is_integral : false_type { };
00092 template<> struct is_integral<bool> : true_type { };
00093 template<> struct is_integral<char> : true_type { };
00094 template<> struct is_integral<unsigned char> : true_type { };
00095 template<> struct is_integral<signed char> : true_type { };
00096 #if defined(_MSC_VER)
00097
00098
00099
00100 template<> struct is_integral<__wchar_t> : true_type { };
00101 #else
00102 template<> struct is_integral<wchar_t> : true_type { };
00103 #endif
00104 template<> struct is_integral<short> : true_type { };
00105 template<> struct is_integral<unsigned short> : true_type { };
00106 template<> struct is_integral<int> : true_type { };
00107 template<> struct is_integral<unsigned int> : true_type { };
00108 template<> struct is_integral<long> : true_type { };
00109 template<> struct is_integral<unsigned long> : true_type { };
00110 #ifdef HAVE_LONG_LONG
00111 template<> struct is_integral<long long> : true_type { };
00112 template<> struct is_integral<unsigned long long> : true_type { };
00113 #endif
00114
00115
00116
00117 template <class T> struct is_floating_point : false_type { };
00118 template<> struct is_floating_point<float> : true_type { };
00119 template<> struct is_floating_point<double> : true_type { };
00120 template<> struct is_floating_point<long double> : true_type { };
00121
00122
00123
00124 template <class T> struct is_pointer : false_type { };
00125 template <class T> struct is_pointer<T*> : true_type { };
00126
00127
00128
00129 template<typename T> struct is_reference : false_type {};
00130 template<typename T> struct is_reference<T&> : true_type {};
00131
00132
00133
00134
00135
00136 template <class T> struct is_pod
00137 : integral_constant<bool, (is_integral<T>::value ||
00138 is_floating_point<T>::value ||
00139 is_pointer<T>::value)> { };
00140 template <class T> struct is_pod<const T> : is_pod<T> { };
00141
00142
00143
00144
00145
00146
00147
00148 template <class T> struct has_trivial_constructor : is_pod<T> { };
00149 template <class T, class U> struct has_trivial_constructor<std::pair<T, U> >
00150 : integral_constant<bool,
00151 (has_trivial_constructor<T>::value &&
00152 has_trivial_constructor<U>::value)> { };
00153 template <class A, int N> struct has_trivial_constructor<A[N]>
00154 : has_trivial_constructor<A> { };
00155 template <class T> struct has_trivial_constructor<const T>
00156 : has_trivial_constructor<T> { };
00157
00158
00159
00160
00161
00162
00163 template <class T> struct has_trivial_copy : is_pod<T> { };
00164 template <class T, class U> struct has_trivial_copy<std::pair<T, U> >
00165 : integral_constant<bool,
00166 (has_trivial_copy<T>::value &&
00167 has_trivial_copy<U>::value)> { };
00168 template <class A, int N> struct has_trivial_copy<A[N]>
00169 : has_trivial_copy<A> { };
00170 template <class T> struct has_trivial_copy<const T> : has_trivial_copy<T> { };
00171
00172
00173
00174
00175
00176 template <class T> struct has_trivial_assign : is_pod<T> { };
00177 template <class T, class U> struct has_trivial_assign<std::pair<T, U> >
00178 : integral_constant<bool,
00179 (has_trivial_assign<T>::value &&
00180 has_trivial_assign<U>::value)> { };
00181 template <class A, int N> struct has_trivial_assign<A[N]>
00182 : has_trivial_assign<A> { };
00183
00184
00185
00186
00187
00188
00189 template <class T> struct has_trivial_destructor : is_pod<T> { };
00190 template <class T, class U> struct has_trivial_destructor<std::pair<T, U> >
00191 : integral_constant<bool,
00192 (has_trivial_destructor<T>::value &&
00193 has_trivial_destructor<U>::value)> { };
00194 template <class A, int N> struct has_trivial_destructor<A[N]>
00195 : has_trivial_destructor<A> { };
00196 template <class T> struct has_trivial_destructor<const T>
00197 : has_trivial_destructor<T> { };
00198
00199
00200 template<typename T> struct remove_const { typedef T type; };
00201 template<typename T> struct remove_const<T const> { typedef T type; };
00202 template<typename T> struct remove_volatile { typedef T type; };
00203 template<typename T> struct remove_volatile<T volatile> { typedef T type; };
00204 template<typename T> struct remove_cv {
00205 typedef typename remove_const<typename remove_volatile<T>::type>::type type;
00206 };
00207
00208
00209
00210 template<typename T> struct remove_reference { typedef T type; };
00211 template<typename T> struct remove_reference<T&> { typedef T type; };
00212
00213
00214 template<typename T> struct remove_pointer { typedef T type; };
00215 template<typename T> struct remove_pointer<T*> { typedef T type; };
00216 template<typename T> struct remove_pointer<T* const> { typedef T type; };
00217 template<typename T> struct remove_pointer<T* volatile> { typedef T type; };
00218 template<typename T> struct remove_pointer<T* const volatile> {
00219 typedef T type; };
00220
00221
00222 #ifndef _MSC_VER
00223 namespace internal {
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234 template <typename From, typename To>
00235 struct ConvertHelper {
00236 static small_ Test(To);
00237 static big_ Test(...);
00238 static From Create();
00239 };
00240 }
00241
00242
00243 template <typename From, typename To>
00244 struct is_convertible
00245 : integral_constant<bool,
00246 sizeof(internal::ConvertHelper<From, To>::Test(
00247 internal::ConvertHelper<From, To>::Create()))
00248 == sizeof(small_)> {
00249 };
00250 #endif
00251
00252 _END_GOOGLE_NAMESPACE_
00253
00254 #endif // BASE_TYPE_TRAITS_H_