libstdc++
|
00001 // The -*- C++ -*- type traits classes for internal use in libstdc++ 00002 00003 // Copyright (C) 2000-2019 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. One 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 extern "C++" { 00068 00069 namespace std _GLIBCXX_VISIBILITY(default) 00070 { 00071 _GLIBCXX_BEGIN_NAMESPACE_VERSION 00072 00073 struct __true_type { }; 00074 struct __false_type { }; 00075 00076 template<bool> 00077 struct __truth_type 00078 { typedef __false_type __type; }; 00079 00080 template<> 00081 struct __truth_type<true> 00082 { typedef __true_type __type; }; 00083 00084 // N.B. The conversions to bool are needed due to the issue 00085 // explained in c++/19404. 00086 template<class _Sp, class _Tp> 00087 struct __traitor 00088 { 00089 enum { __value = bool(_Sp::__value) || bool(_Tp::__value) }; 00090 typedef typename __truth_type<__value>::__type __type; 00091 }; 00092 00093 // Compare for equality of types. 00094 template<typename, typename> 00095 struct __are_same 00096 { 00097 enum { __value = 0 }; 00098 typedef __false_type __type; 00099 }; 00100 00101 template<typename _Tp> 00102 struct __are_same<_Tp, _Tp> 00103 { 00104 enum { __value = 1 }; 00105 typedef __true_type __type; 00106 }; 00107 00108 // Holds if the template-argument is a void type. 00109 template<typename _Tp> 00110 struct __is_void 00111 { 00112 enum { __value = 0 }; 00113 typedef __false_type __type; 00114 }; 00115 00116 template<> 00117 struct __is_void<void> 00118 { 00119 enum { __value = 1 }; 00120 typedef __true_type __type; 00121 }; 00122 00123 // 00124 // Integer types 00125 // 00126 template<typename _Tp> 00127 struct __is_integer 00128 { 00129 enum { __value = 0 }; 00130 typedef __false_type __type; 00131 }; 00132 00133 // Thirteen specializations (yes there are eleven standard integer 00134 // types; <em>long long</em> and <em>unsigned long long</em> are 00135 // supported as extensions). Up to four target-specific __int<N> 00136 // types are supported as well. 00137 template<> 00138 struct __is_integer<bool> 00139 { 00140 enum { __value = 1 }; 00141 typedef __true_type __type; 00142 }; 00143 00144 template<> 00145 struct __is_integer<char> 00146 { 00147 enum { __value = 1 }; 00148 typedef __true_type __type; 00149 }; 00150 00151 template<> 00152 struct __is_integer<signed char> 00153 { 00154 enum { __value = 1 }; 00155 typedef __true_type __type; 00156 }; 00157 00158 template<> 00159 struct __is_integer<unsigned char> 00160 { 00161 enum { __value = 1 }; 00162 typedef __true_type __type; 00163 }; 00164 00165 # ifdef _GLIBCXX_USE_WCHAR_T 00166 template<> 00167 struct __is_integer<wchar_t> 00168 { 00169 enum { __value = 1 }; 00170 typedef __true_type __type; 00171 }; 00172 # endif 00173 00174 #ifdef _GLIBCXX_USE_CHAR8_T 00175 template<> 00176 struct __is_integer<char8_t> 00177 { 00178 enum { __value = 1 }; 00179 typedef __true_type __type; 00180 }; 00181 #endif 00182 00183 #if __cplusplus >= 201103L 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 #define __INT_N(TYPE) \ 00256 template<> \ 00257 struct __is_integer<TYPE> \ 00258 { \ 00259 enum { __value = 1 }; \ 00260 typedef __true_type __type; \ 00261 }; \ 00262 template<> \ 00263 struct __is_integer<unsigned TYPE> \ 00264 { \ 00265 enum { __value = 1 }; \ 00266 typedef __true_type __type; \ 00267 }; 00268 00269 #ifdef __GLIBCXX_TYPE_INT_N_0 00270 __INT_N(__GLIBCXX_TYPE_INT_N_0) 00271 #endif 00272 #ifdef __GLIBCXX_TYPE_INT_N_1 00273 __INT_N(__GLIBCXX_TYPE_INT_N_1) 00274 #endif 00275 #ifdef __GLIBCXX_TYPE_INT_N_2 00276 __INT_N(__GLIBCXX_TYPE_INT_N_2) 00277 #endif 00278 #ifdef __GLIBCXX_TYPE_INT_N_3 00279 __INT_N(__GLIBCXX_TYPE_INT_N_3) 00280 #endif 00281 00282 #undef __INT_N 00283 00284 // 00285 // Floating point types 00286 // 00287 template<typename _Tp> 00288 struct __is_floating 00289 { 00290 enum { __value = 0 }; 00291 typedef __false_type __type; 00292 }; 00293 00294 // three specializations (float, double and 'long double') 00295 template<> 00296 struct __is_floating<float> 00297 { 00298 enum { __value = 1 }; 00299 typedef __true_type __type; 00300 }; 00301 00302 template<> 00303 struct __is_floating<double> 00304 { 00305 enum { __value = 1 }; 00306 typedef __true_type __type; 00307 }; 00308 00309 template<> 00310 struct __is_floating<long double> 00311 { 00312 enum { __value = 1 }; 00313 typedef __true_type __type; 00314 }; 00315 00316 // 00317 // Pointer types 00318 // 00319 template<typename _Tp> 00320 struct __is_pointer 00321 { 00322 enum { __value = 0 }; 00323 typedef __false_type __type; 00324 }; 00325 00326 template<typename _Tp> 00327 struct __is_pointer<_Tp*> 00328 { 00329 enum { __value = 1 }; 00330 typedef __true_type __type; 00331 }; 00332 00333 // 00334 // An arithmetic type is an integer type or a floating point type 00335 // 00336 template<typename _Tp> 00337 struct __is_arithmetic 00338 : public __traitor<__is_integer<_Tp>, __is_floating<_Tp> > 00339 { }; 00340 00341 // 00342 // A scalar type is an arithmetic type or a pointer type 00343 // 00344 template<typename _Tp> 00345 struct __is_scalar 00346 : public __traitor<__is_arithmetic<_Tp>, __is_pointer<_Tp> > 00347 { }; 00348 00349 // 00350 // For use in std::copy and std::find overloads for streambuf iterators. 00351 // 00352 template<typename _Tp> 00353 struct __is_char 00354 { 00355 enum { __value = 0 }; 00356 typedef __false_type __type; 00357 }; 00358 00359 template<> 00360 struct __is_char<char> 00361 { 00362 enum { __value = 1 }; 00363 typedef __true_type __type; 00364 }; 00365 00366 #ifdef _GLIBCXX_USE_WCHAR_T 00367 template<> 00368 struct __is_char<wchar_t> 00369 { 00370 enum { __value = 1 }; 00371 typedef __true_type __type; 00372 }; 00373 #endif 00374 00375 template<typename _Tp> 00376 struct __is_byte 00377 { 00378 enum { __value = 0 }; 00379 typedef __false_type __type; 00380 }; 00381 00382 template<> 00383 struct __is_byte<char> 00384 { 00385 enum { __value = 1 }; 00386 typedef __true_type __type; 00387 }; 00388 00389 template<> 00390 struct __is_byte<signed char> 00391 { 00392 enum { __value = 1 }; 00393 typedef __true_type __type; 00394 }; 00395 00396 template<> 00397 struct __is_byte<unsigned char> 00398 { 00399 enum { __value = 1 }; 00400 typedef __true_type __type; 00401 }; 00402 00403 #if __cplusplus >= 201703L 00404 enum class byte : unsigned char; 00405 00406 template<> 00407 struct __is_byte<byte> 00408 { 00409 enum { __value = 1 }; 00410 typedef __true_type __type; 00411 }; 00412 #endif // C++17 00413 00414 // 00415 // Move iterator type 00416 // 00417 template<typename _Tp> 00418 struct __is_move_iterator 00419 { 00420 enum { __value = 0 }; 00421 typedef __false_type __type; 00422 }; 00423 00424 // Fallback implementation of the function in bits/stl_iterator.h used to 00425 // remove the move_iterator wrapper. 00426 template<typename _Iterator> 00427 inline _Iterator 00428 __miter_base(_Iterator __it) 00429 { return __it; } 00430 00431 _GLIBCXX_END_NAMESPACE_VERSION 00432 } // namespace 00433 } // extern "C++" 00434 00435 #endif //_CPP_TYPE_TRAITS_H