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