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