libstdc++
cpp_type_traits.h
Go to the documentation of this file.
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