libstdc++
|
00001 // The -*- C++ -*- type traits classes for internal use in libstdc++ 00002 00003 // Copyright (C) 2000-2018 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 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 #if __cplusplus >= 201103L 00175 template<> 00176 struct __is_integer<char16_t> 00177 { 00178 enum { __value = 1 }; 00179 typedef __true_type __type; 00180 }; 00181 00182 template<> 00183 struct __is_integer<char32_t> 00184 { 00185 enum { __value = 1 }; 00186 typedef __true_type __type; 00187 }; 00188 #endif 00189 00190 template<> 00191 struct __is_integer<short> 00192 { 00193 enum { __value = 1 }; 00194 typedef __true_type __type; 00195 }; 00196 00197 template<> 00198 struct __is_integer<unsigned short> 00199 { 00200 enum { __value = 1 }; 00201 typedef __true_type __type; 00202 }; 00203 00204 template<> 00205 struct __is_integer<int> 00206 { 00207 enum { __value = 1 }; 00208 typedef __true_type __type; 00209 }; 00210 00211 template<> 00212 struct __is_integer<unsigned int> 00213 { 00214 enum { __value = 1 }; 00215 typedef __true_type __type; 00216 }; 00217 00218 template<> 00219 struct __is_integer<long> 00220 { 00221 enum { __value = 1 }; 00222 typedef __true_type __type; 00223 }; 00224 00225 template<> 00226 struct __is_integer<unsigned long> 00227 { 00228 enum { __value = 1 }; 00229 typedef __true_type __type; 00230 }; 00231 00232 template<> 00233 struct __is_integer<long long> 00234 { 00235 enum { __value = 1 }; 00236 typedef __true_type __type; 00237 }; 00238 00239 template<> 00240 struct __is_integer<unsigned long long> 00241 { 00242 enum { __value = 1 }; 00243 typedef __true_type __type; 00244 }; 00245 00246 #define __INT_N(TYPE) \ 00247 template<> \ 00248 struct __is_integer<TYPE> \ 00249 { \ 00250 enum { __value = 1 }; \ 00251 typedef __true_type __type; \ 00252 }; \ 00253 template<> \ 00254 struct __is_integer<unsigned TYPE> \ 00255 { \ 00256 enum { __value = 1 }; \ 00257 typedef __true_type __type; \ 00258 }; 00259 00260 #ifdef __GLIBCXX_TYPE_INT_N_0 00261 __INT_N(__GLIBCXX_TYPE_INT_N_0) 00262 #endif 00263 #ifdef __GLIBCXX_TYPE_INT_N_1 00264 __INT_N(__GLIBCXX_TYPE_INT_N_1) 00265 #endif 00266 #ifdef __GLIBCXX_TYPE_INT_N_2 00267 __INT_N(__GLIBCXX_TYPE_INT_N_2) 00268 #endif 00269 #ifdef __GLIBCXX_TYPE_INT_N_3 00270 __INT_N(__GLIBCXX_TYPE_INT_N_3) 00271 #endif 00272 00273 #undef __INT_N 00274 00275 // 00276 // Floating point types 00277 // 00278 template<typename _Tp> 00279 struct __is_floating 00280 { 00281 enum { __value = 0 }; 00282 typedef __false_type __type; 00283 }; 00284 00285 // three specializations (float, double and 'long double') 00286 template<> 00287 struct __is_floating<float> 00288 { 00289 enum { __value = 1 }; 00290 typedef __true_type __type; 00291 }; 00292 00293 template<> 00294 struct __is_floating<double> 00295 { 00296 enum { __value = 1 }; 00297 typedef __true_type __type; 00298 }; 00299 00300 template<> 00301 struct __is_floating<long double> 00302 { 00303 enum { __value = 1 }; 00304 typedef __true_type __type; 00305 }; 00306 00307 // 00308 // Pointer types 00309 // 00310 template<typename _Tp> 00311 struct __is_pointer 00312 { 00313 enum { __value = 0 }; 00314 typedef __false_type __type; 00315 }; 00316 00317 template<typename _Tp> 00318 struct __is_pointer<_Tp*> 00319 { 00320 enum { __value = 1 }; 00321 typedef __true_type __type; 00322 }; 00323 00324 // 00325 // An arithmetic type is an integer type or a floating point type 00326 // 00327 template<typename _Tp> 00328 struct __is_arithmetic 00329 : public __traitor<__is_integer<_Tp>, __is_floating<_Tp> > 00330 { }; 00331 00332 // 00333 // A scalar type is an arithmetic type or a pointer type 00334 // 00335 template<typename _Tp> 00336 struct __is_scalar 00337 : public __traitor<__is_arithmetic<_Tp>, __is_pointer<_Tp> > 00338 { }; 00339 00340 // 00341 // For use in std::copy and std::find overloads for streambuf iterators. 00342 // 00343 template<typename _Tp> 00344 struct __is_char 00345 { 00346 enum { __value = 0 }; 00347 typedef __false_type __type; 00348 }; 00349 00350 template<> 00351 struct __is_char<char> 00352 { 00353 enum { __value = 1 }; 00354 typedef __true_type __type; 00355 }; 00356 00357 #ifdef _GLIBCXX_USE_WCHAR_T 00358 template<> 00359 struct __is_char<wchar_t> 00360 { 00361 enum { __value = 1 }; 00362 typedef __true_type __type; 00363 }; 00364 #endif 00365 00366 template<typename _Tp> 00367 struct __is_byte 00368 { 00369 enum { __value = 0 }; 00370 typedef __false_type __type; 00371 }; 00372 00373 template<> 00374 struct __is_byte<char> 00375 { 00376 enum { __value = 1 }; 00377 typedef __true_type __type; 00378 }; 00379 00380 template<> 00381 struct __is_byte<signed char> 00382 { 00383 enum { __value = 1 }; 00384 typedef __true_type __type; 00385 }; 00386 00387 template<> 00388 struct __is_byte<unsigned char> 00389 { 00390 enum { __value = 1 }; 00391 typedef __true_type __type; 00392 }; 00393 00394 #if __cplusplus >= 201703L 00395 enum class byte : unsigned char; 00396 00397 template<> 00398 struct __is_byte<byte> 00399 { 00400 enum { __value = 1 }; 00401 typedef __true_type __type; 00402 }; 00403 #endif // C++17 00404 00405 // 00406 // Move iterator type 00407 // 00408 template<typename _Tp> 00409 struct __is_move_iterator 00410 { 00411 enum { __value = 0 }; 00412 typedef __false_type __type; 00413 }; 00414 00415 // Fallback implementation of the function in bits/stl_iterator.h used to 00416 // remove the move_iterator wrapper. 00417 template<typename _Iterator> 00418 inline _Iterator 00419 __miter_base(_Iterator __it) 00420 { return __it; } 00421 00422 _GLIBCXX_END_NAMESPACE_VERSION 00423 } // namespace 00424 } // extern "C++" 00425 00426 #endif //_CPP_TYPE_TRAITS_H