libstdc++
|
00001 // The -*- C++ -*- type traits classes for internal use in libstdc++ 00002 00003 // Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2009 00004 // Free Software Foundation, Inc. 00005 // 00006 // This file is part of the GNU ISO C++ Library. This library is free 00007 // software; you can redistribute it and/or modify it under the 00008 // terms of the GNU General Public License as published by the 00009 // Free Software Foundation; either version 3, or (at your option) 00010 // any later version. 00011 00012 // This library is distributed in the hope that it will be useful, 00013 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00015 // GNU General Public License for more details. 00016 00017 // Under Section 7 of GPL version 3, you are granted additional 00018 // permissions described in the GCC Runtime Library Exception, version 00019 // 3.1, as published by the Free Software Foundation. 00020 00021 // You should have received a copy of the GNU General Public License and 00022 // a copy of the GCC Runtime Library Exception along with this program; 00023 // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 00024 // <http://www.gnu.org/licenses/>. 00025 00026 /** @file cpp_type_traits.h 00027 * This is an internal header file, included by other library headers. 00028 * You should not attempt to use it directly. 00029 */ 00030 00031 // Written by Gabriel Dos Reis <dosreis@cmla.ens-cachan.fr> 00032 00033 #ifndef _CPP_TYPE_TRAITS_H 00034 #define _CPP_TYPE_TRAITS_H 1 00035 00036 #pragma GCC system_header 00037 00038 #include <bits/c++config.h> 00039 00040 // 00041 // This file provides some compile-time information about various types. 00042 // These representations were designed, on purpose, to be constant-expressions 00043 // and not types as found in <bits/type_traits.h>. In particular, they 00044 // can be used in control structures and the optimizer hopefully will do 00045 // the obvious thing. 00046 // 00047 // Why integral expressions, and not functions nor types? 00048 // Firstly, these compile-time entities are used as template-arguments 00049 // so function return values won't work: We need compile-time entities. 00050 // We're left with types and constant integral expressions. 00051 // Secondly, from the point of view of ease of use, type-based compile-time 00052 // information is -not- *that* convenient. On has to write lots of 00053 // overloaded functions and to hope that the compiler will select the right 00054 // one. As a net effect, the overall structure isn't very clear at first 00055 // glance. 00056 // Thirdly, partial ordering and overload resolution (of function templates) 00057 // is highly costly in terms of compiler-resource. It is a Good Thing to 00058 // keep these resource consumption as least as possible. 00059 // 00060 // See valarray_array.h for a case use. 00061 // 00062 // -- Gaby (dosreis@cmla.ens-cachan.fr) 2000-03-06. 00063 // 00064 // Update 2005: types are also provided and <bits/type_traits.h> has been 00065 // removed. 00066 // 00067 00068 // Forward declaration hack, should really include this from somewhere. 00069 _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) 00070 00071 template<typename _Iterator, typename _Container> 00072 class __normal_iterator; 00073 00074 _GLIBCXX_END_NAMESPACE 00075 00076 _GLIBCXX_BEGIN_NAMESPACE(std) 00077 00078 struct __true_type { }; 00079 struct __false_type { }; 00080 00081 template<bool> 00082 struct __truth_type 00083 { typedef __false_type __type; }; 00084 00085 template<> 00086 struct __truth_type<true> 00087 { typedef __true_type __type; }; 00088 00089 // N.B. The conversions to bool are needed due to the issue 00090 // explained in c++/19404. 00091 template<class _Sp, class _Tp> 00092 struct __traitor 00093 { 00094 enum { __value = bool(_Sp::__value) || bool(_Tp::__value) }; 00095 typedef typename __truth_type<__value>::__type __type; 00096 }; 00097 00098 // Compare for equality of types. 00099 template<typename, typename> 00100 struct __are_same 00101 { 00102 enum { __value = 0 }; 00103 typedef __false_type __type; 00104 }; 00105 00106 template<typename _Tp> 00107 struct __are_same<_Tp, _Tp> 00108 { 00109 enum { __value = 1 }; 00110 typedef __true_type __type; 00111 }; 00112 00113 // Holds if the template-argument is a void type. 00114 template<typename _Tp> 00115 struct __is_void 00116 { 00117 enum { __value = 0 }; 00118 typedef __false_type __type; 00119 }; 00120 00121 template<> 00122 struct __is_void<void> 00123 { 00124 enum { __value = 1 }; 00125 typedef __true_type __type; 00126 }; 00127 00128 // 00129 // Integer types 00130 // 00131 template<typename _Tp> 00132 struct __is_integer 00133 { 00134 enum { __value = 0 }; 00135 typedef __false_type __type; 00136 }; 00137 00138 // Thirteen specializations (yes there are eleven standard integer 00139 // types; 'long long' and 'unsigned long long' are supported as 00140 // extensions) 00141 template<> 00142 struct __is_integer<bool> 00143 { 00144 enum { __value = 1 }; 00145 typedef __true_type __type; 00146 }; 00147 00148 template<> 00149 struct __is_integer<char> 00150 { 00151 enum { __value = 1 }; 00152 typedef __true_type __type; 00153 }; 00154 00155 template<> 00156 struct __is_integer<signed char> 00157 { 00158 enum { __value = 1 }; 00159 typedef __true_type __type; 00160 }; 00161 00162 template<> 00163 struct __is_integer<unsigned char> 00164 { 00165 enum { __value = 1 }; 00166 typedef __true_type __type; 00167 }; 00168 00169 # ifdef _GLIBCXX_USE_WCHAR_T 00170 template<> 00171 struct __is_integer<wchar_t> 00172 { 00173 enum { __value = 1 }; 00174 typedef __true_type __type; 00175 }; 00176 # endif 00177 00178 #ifdef __GXX_EXPERIMENTAL_CXX0X__ 00179 template<> 00180 struct __is_integer<char16_t> 00181 { 00182 enum { __value = 1 }; 00183 typedef __true_type __type; 00184 }; 00185 00186 template<> 00187 struct __is_integer<char32_t> 00188 { 00189 enum { __value = 1 }; 00190 typedef __true_type __type; 00191 }; 00192 #endif 00193 00194 template<> 00195 struct __is_integer<short> 00196 { 00197 enum { __value = 1 }; 00198 typedef __true_type __type; 00199 }; 00200 00201 template<> 00202 struct __is_integer<unsigned short> 00203 { 00204 enum { __value = 1 }; 00205 typedef __true_type __type; 00206 }; 00207 00208 template<> 00209 struct __is_integer<int> 00210 { 00211 enum { __value = 1 }; 00212 typedef __true_type __type; 00213 }; 00214 00215 template<> 00216 struct __is_integer<unsigned int> 00217 { 00218 enum { __value = 1 }; 00219 typedef __true_type __type; 00220 }; 00221 00222 template<> 00223 struct __is_integer<long> 00224 { 00225 enum { __value = 1 }; 00226 typedef __true_type __type; 00227 }; 00228 00229 template<> 00230 struct __is_integer<unsigned long> 00231 { 00232 enum { __value = 1 }; 00233 typedef __true_type __type; 00234 }; 00235 00236 template<> 00237 struct __is_integer<long long> 00238 { 00239 enum { __value = 1 }; 00240 typedef __true_type __type; 00241 }; 00242 00243 template<> 00244 struct __is_integer<unsigned long long> 00245 { 00246 enum { __value = 1 }; 00247 typedef __true_type __type; 00248 }; 00249 00250 // 00251 // Floating point types 00252 // 00253 template<typename _Tp> 00254 struct __is_floating 00255 { 00256 enum { __value = 0 }; 00257 typedef __false_type __type; 00258 }; 00259 00260 // three specializations (float, double and 'long double') 00261 template<> 00262 struct __is_floating<float> 00263 { 00264 enum { __value = 1 }; 00265 typedef __true_type __type; 00266 }; 00267 00268 template<> 00269 struct __is_floating<double> 00270 { 00271 enum { __value = 1 }; 00272 typedef __true_type __type; 00273 }; 00274 00275 template<> 00276 struct __is_floating<long double> 00277 { 00278 enum { __value = 1 }; 00279 typedef __true_type __type; 00280 }; 00281 00282 // 00283 // Pointer types 00284 // 00285 template<typename _Tp> 00286 struct __is_pointer 00287 { 00288 enum { __value = 0 }; 00289 typedef __false_type __type; 00290 }; 00291 00292 template<typename _Tp> 00293 struct __is_pointer<_Tp*> 00294 { 00295 enum { __value = 1 }; 00296 typedef __true_type __type; 00297 }; 00298 00299 // 00300 // Normal iterator type 00301 // 00302 template<typename _Tp> 00303 struct __is_normal_iterator 00304 { 00305 enum { __value = 0 }; 00306 typedef __false_type __type; 00307 }; 00308 00309 template<typename _Iterator, typename _Container> 00310 struct __is_normal_iterator< __gnu_cxx::__normal_iterator<_Iterator, 00311 _Container> > 00312 { 00313 enum { __value = 1 }; 00314 typedef __true_type __type; 00315 }; 00316 00317 // 00318 // An arithmetic type is an integer type or a floating point type 00319 // 00320 template<typename _Tp> 00321 struct __is_arithmetic 00322 : public __traitor<__is_integer<_Tp>, __is_floating<_Tp> > 00323 { }; 00324 00325 // 00326 // A fundamental type is `void' or and arithmetic type 00327 // 00328 template<typename _Tp> 00329 struct __is_fundamental 00330 : public __traitor<__is_void<_Tp>, __is_arithmetic<_Tp> > 00331 { }; 00332 00333 // 00334 // A scalar type is an arithmetic type or a pointer type 00335 // 00336 template<typename _Tp> 00337 struct __is_scalar 00338 : public __traitor<__is_arithmetic<_Tp>, __is_pointer<_Tp> > 00339 { }; 00340 00341 // 00342 // For use in std::copy and std::find overloads for streambuf iterators. 00343 // 00344 template<typename _Tp> 00345 struct __is_char 00346 { 00347 enum { __value = 0 }; 00348 typedef __false_type __type; 00349 }; 00350 00351 template<> 00352 struct __is_char<char> 00353 { 00354 enum { __value = 1 }; 00355 typedef __true_type __type; 00356 }; 00357 00358 #ifdef _GLIBCXX_USE_WCHAR_T 00359 template<> 00360 struct __is_char<wchar_t> 00361 { 00362 enum { __value = 1 }; 00363 typedef __true_type __type; 00364 }; 00365 #endif 00366 00367 template<typename _Tp> 00368 struct __is_byte 00369 { 00370 enum { __value = 0 }; 00371 typedef __false_type __type; 00372 }; 00373 00374 template<> 00375 struct __is_byte<char> 00376 { 00377 enum { __value = 1 }; 00378 typedef __true_type __type; 00379 }; 00380 00381 template<> 00382 struct __is_byte<signed char> 00383 { 00384 enum { __value = 1 }; 00385 typedef __true_type __type; 00386 }; 00387 00388 template<> 00389 struct __is_byte<unsigned char> 00390 { 00391 enum { __value = 1 }; 00392 typedef __true_type __type; 00393 }; 00394 00395 // 00396 // Move iterator type 00397 // 00398 template<typename _Tp> 00399 struct __is_move_iterator 00400 { 00401 enum { __value = 0 }; 00402 typedef __false_type __type; 00403 }; 00404 00405 #ifdef __GXX_EXPERIMENTAL_CXX0X__ 00406 template<typename _Iterator> 00407 class move_iterator; 00408 00409 template<typename _Iterator> 00410 struct __is_move_iterator< move_iterator<_Iterator> > 00411 { 00412 enum { __value = 1 }; 00413 typedef __true_type __type; 00414 }; 00415 #endif 00416 00417 _GLIBCXX_END_NAMESPACE 00418 00419 #endif //_CPP_TYPE_TRAITS_H