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-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