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, 2010 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 bits/cpp_type_traits.h 00027 * This is an internal header file, included by other library headers. 00028 * Do not attempt to use it directly. @headername{ext/type_traits} 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 namespace __gnu_cxx _GLIBCXX_VISIBILITY(default) 00070 { 00071 _GLIBCXX_BEGIN_NAMESPACE_VERSION 00072 00073 template<typename _Iterator, typename _Container> 00074 class __normal_iterator; 00075 00076 _GLIBCXX_END_NAMESPACE_VERSION 00077 } // namespace 00078 00079 namespace std _GLIBCXX_VISIBILITY(default) 00080 { 00081 _GLIBCXX_BEGIN_NAMESPACE_VERSION 00082 00083 struct __true_type { }; 00084 struct __false_type { }; 00085 00086 template<bool> 00087 struct __truth_type 00088 { typedef __false_type __type; }; 00089 00090 template<> 00091 struct __truth_type<true> 00092 { typedef __true_type __type; }; 00093 00094 // N.B. The conversions to bool are needed due to the issue 00095 // explained in c++/19404. 00096 template<class _Sp, class _Tp> 00097 struct __traitor 00098 { 00099 enum { __value = bool(_Sp::__value) || bool(_Tp::__value) }; 00100 typedef typename __truth_type<__value>::__type __type; 00101 }; 00102 00103 // Compare for equality of types. 00104 template<typename, typename> 00105 struct __are_same 00106 { 00107 enum { __value = 0 }; 00108 typedef __false_type __type; 00109 }; 00110 00111 template<typename _Tp> 00112 struct __are_same<_Tp, _Tp> 00113 { 00114 enum { __value = 1 }; 00115 typedef __true_type __type; 00116 }; 00117 00118 // Holds if the template-argument is a void type. 00119 template<typename _Tp> 00120 struct __is_void 00121 { 00122 enum { __value = 0 }; 00123 typedef __false_type __type; 00124 }; 00125 00126 template<> 00127 struct __is_void<void> 00128 { 00129 enum { __value = 1 }; 00130 typedef __true_type __type; 00131 }; 00132 00133 // 00134 // Integer types 00135 // 00136 template<typename _Tp> 00137 struct __is_integer 00138 { 00139 enum { __value = 0 }; 00140 typedef __false_type __type; 00141 }; 00142 00143 // Thirteen specializations (yes there are eleven standard integer 00144 // types; <em>long long</em> and <em>unsigned long long</em> are 00145 // supported as extensions) 00146 template<> 00147 struct __is_integer<bool> 00148 { 00149 enum { __value = 1 }; 00150 typedef __true_type __type; 00151 }; 00152 00153 template<> 00154 struct __is_integer<char> 00155 { 00156 enum { __value = 1 }; 00157 typedef __true_type __type; 00158 }; 00159 00160 template<> 00161 struct __is_integer<signed char> 00162 { 00163 enum { __value = 1 }; 00164 typedef __true_type __type; 00165 }; 00166 00167 template<> 00168 struct __is_integer<unsigned char> 00169 { 00170 enum { __value = 1 }; 00171 typedef __true_type __type; 00172 }; 00173 00174 # ifdef _GLIBCXX_USE_WCHAR_T 00175 template<> 00176 struct __is_integer<wchar_t> 00177 { 00178 enum { __value = 1 }; 00179 typedef __true_type __type; 00180 }; 00181 # endif 00182 00183 #ifdef __GXX_EXPERIMENTAL_CXX0X__ 00184 template<> 00185 struct __is_integer<char16_t> 00186 { 00187 enum { __value = 1 }; 00188 typedef __true_type __type; 00189 }; 00190 00191 template<> 00192 struct __is_integer<char32_t> 00193 { 00194 enum { __value = 1 }; 00195 typedef __true_type __type; 00196 }; 00197 #endif 00198 00199 template<> 00200 struct __is_integer<short> 00201 { 00202 enum { __value = 1 }; 00203 typedef __true_type __type; 00204 }; 00205 00206 template<> 00207 struct __is_integer<unsigned short> 00208 { 00209 enum { __value = 1 }; 00210 typedef __true_type __type; 00211 }; 00212 00213 template<> 00214 struct __is_integer<int> 00215 { 00216 enum { __value = 1 }; 00217 typedef __true_type __type; 00218 }; 00219 00220 template<> 00221 struct __is_integer<unsigned int> 00222 { 00223 enum { __value = 1 }; 00224 typedef __true_type __type; 00225 }; 00226 00227 template<> 00228 struct __is_integer<long> 00229 { 00230 enum { __value = 1 }; 00231 typedef __true_type __type; 00232 }; 00233 00234 template<> 00235 struct __is_integer<unsigned long> 00236 { 00237 enum { __value = 1 }; 00238 typedef __true_type __type; 00239 }; 00240 00241 template<> 00242 struct __is_integer<long long> 00243 { 00244 enum { __value = 1 }; 00245 typedef __true_type __type; 00246 }; 00247 00248 template<> 00249 struct __is_integer<unsigned long long> 00250 { 00251 enum { __value = 1 }; 00252 typedef __true_type __type; 00253 }; 00254 00255 // 00256 // Floating point types 00257 // 00258 template<typename _Tp> 00259 struct __is_floating 00260 { 00261 enum { __value = 0 }; 00262 typedef __false_type __type; 00263 }; 00264 00265 // three specializations (float, double and 'long double') 00266 template<> 00267 struct __is_floating<float> 00268 { 00269 enum { __value = 1 }; 00270 typedef __true_type __type; 00271 }; 00272 00273 template<> 00274 struct __is_floating<double> 00275 { 00276 enum { __value = 1 }; 00277 typedef __true_type __type; 00278 }; 00279 00280 template<> 00281 struct __is_floating<long double> 00282 { 00283 enum { __value = 1 }; 00284 typedef __true_type __type; 00285 }; 00286 00287 // 00288 // Pointer types 00289 // 00290 template<typename _Tp> 00291 struct __is_pointer 00292 { 00293 enum { __value = 0 }; 00294 typedef __false_type __type; 00295 }; 00296 00297 template<typename _Tp> 00298 struct __is_pointer<_Tp*> 00299 { 00300 enum { __value = 1 }; 00301 typedef __true_type __type; 00302 }; 00303 00304 // 00305 // Normal iterator type 00306 // 00307 template<typename _Tp> 00308 struct __is_normal_iterator 00309 { 00310 enum { __value = 0 }; 00311 typedef __false_type __type; 00312 }; 00313 00314 template<typename _Iterator, typename _Container> 00315 struct __is_normal_iterator< __gnu_cxx::__normal_iterator<_Iterator, 00316 _Container> > 00317 { 00318 enum { __value = 1 }; 00319 typedef __true_type __type; 00320 }; 00321 00322 // 00323 // An arithmetic type is an integer type or a floating point type 00324 // 00325 template<typename _Tp> 00326 struct __is_arithmetic 00327 : public __traitor<__is_integer<_Tp>, __is_floating<_Tp> > 00328 { }; 00329 00330 // 00331 // A fundamental type is `void' or and arithmetic type 00332 // 00333 template<typename _Tp> 00334 struct __is_fundamental 00335 : public __traitor<__is_void<_Tp>, __is_arithmetic<_Tp> > 00336 { }; 00337 00338 // 00339 // A scalar type is an arithmetic type or a pointer type 00340 // 00341 template<typename _Tp> 00342 struct __is_scalar 00343 : public __traitor<__is_arithmetic<_Tp>, __is_pointer<_Tp> > 00344 { }; 00345 00346 // 00347 // For use in std::copy and std::find overloads for streambuf iterators. 00348 // 00349 template<typename _Tp> 00350 struct __is_char 00351 { 00352 enum { __value = 0 }; 00353 typedef __false_type __type; 00354 }; 00355 00356 template<> 00357 struct __is_char<char> 00358 { 00359 enum { __value = 1 }; 00360 typedef __true_type __type; 00361 }; 00362 00363 #ifdef _GLIBCXX_USE_WCHAR_T 00364 template<> 00365 struct __is_char<wchar_t> 00366 { 00367 enum { __value = 1 }; 00368 typedef __true_type __type; 00369 }; 00370 #endif 00371 00372 template<typename _Tp> 00373 struct __is_byte 00374 { 00375 enum { __value = 0 }; 00376 typedef __false_type __type; 00377 }; 00378 00379 template<> 00380 struct __is_byte<char> 00381 { 00382 enum { __value = 1 }; 00383 typedef __true_type __type; 00384 }; 00385 00386 template<> 00387 struct __is_byte<signed char> 00388 { 00389 enum { __value = 1 }; 00390 typedef __true_type __type; 00391 }; 00392 00393 template<> 00394 struct __is_byte<unsigned char> 00395 { 00396 enum { __value = 1 }; 00397 typedef __true_type __type; 00398 }; 00399 00400 // 00401 // Move iterator type 00402 // 00403 template<typename _Tp> 00404 struct __is_move_iterator 00405 { 00406 enum { __value = 0 }; 00407 typedef __false_type __type; 00408 }; 00409 00410 #ifdef __GXX_EXPERIMENTAL_CXX0X__ 00411 template<typename _Iterator> 00412 class move_iterator; 00413 00414 template<typename _Iterator> 00415 struct __is_move_iterator< move_iterator<_Iterator> > 00416 { 00417 enum { __value = 1 }; 00418 typedef __true_type __type; 00419 }; 00420 #endif 00421 00422 _GLIBCXX_END_NAMESPACE_VERSION 00423 } // namespace 00424 00425 #endif //_CPP_TYPE_TRAITS_H