libstdc++
|
00001 // The -*- C++ -*- type traits classes for internal use in libstdc++ 00002 00003 // Copyright (C) 2000-2015 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). Up to four target-specific __int<N> 00145 // types are supported as well. 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 #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 // Normal iterator type 00335 // 00336 template<typename _Tp> 00337 struct __is_normal_iterator 00338 { 00339 enum { __value = 0 }; 00340 typedef __false_type __type; 00341 }; 00342 00343 template<typename _Iterator, typename _Container> 00344 struct __is_normal_iterator< __gnu_cxx::__normal_iterator<_Iterator, 00345 _Container> > 00346 { 00347 enum { __value = 1 }; 00348 typedef __true_type __type; 00349 }; 00350 00351 // 00352 // An arithmetic type is an integer type or a floating point type 00353 // 00354 template<typename _Tp> 00355 struct __is_arithmetic 00356 : public __traitor<__is_integer<_Tp>, __is_floating<_Tp> > 00357 { }; 00358 00359 // 00360 // A scalar type is an arithmetic type or a pointer type 00361 // 00362 template<typename _Tp> 00363 struct __is_scalar 00364 : public __traitor<__is_arithmetic<_Tp>, __is_pointer<_Tp> > 00365 { }; 00366 00367 // 00368 // For use in std::copy and std::find overloads for streambuf iterators. 00369 // 00370 template<typename _Tp> 00371 struct __is_char 00372 { 00373 enum { __value = 0 }; 00374 typedef __false_type __type; 00375 }; 00376 00377 template<> 00378 struct __is_char<char> 00379 { 00380 enum { __value = 1 }; 00381 typedef __true_type __type; 00382 }; 00383 00384 #ifdef _GLIBCXX_USE_WCHAR_T 00385 template<> 00386 struct __is_char<wchar_t> 00387 { 00388 enum { __value = 1 }; 00389 typedef __true_type __type; 00390 }; 00391 #endif 00392 00393 template<typename _Tp> 00394 struct __is_byte 00395 { 00396 enum { __value = 0 }; 00397 typedef __false_type __type; 00398 }; 00399 00400 template<> 00401 struct __is_byte<char> 00402 { 00403 enum { __value = 1 }; 00404 typedef __true_type __type; 00405 }; 00406 00407 template<> 00408 struct __is_byte<signed char> 00409 { 00410 enum { __value = 1 }; 00411 typedef __true_type __type; 00412 }; 00413 00414 template<> 00415 struct __is_byte<unsigned char> 00416 { 00417 enum { __value = 1 }; 00418 typedef __true_type __type; 00419 }; 00420 00421 // 00422 // Move iterator type 00423 // 00424 template<typename _Tp> 00425 struct __is_move_iterator 00426 { 00427 enum { __value = 0 }; 00428 typedef __false_type __type; 00429 }; 00430 00431 #if __cplusplus >= 201103L 00432 template<typename _Iterator> 00433 class move_iterator; 00434 00435 template<typename _Iterator> 00436 struct __is_move_iterator< move_iterator<_Iterator> > 00437 { 00438 enum { __value = 1 }; 00439 typedef __true_type __type; 00440 }; 00441 #endif 00442 00443 _GLIBCXX_END_NAMESPACE_VERSION 00444 } // namespace 00445 00446 #endif //_CPP_TYPE_TRAITS_H