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