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, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2009, 2010
00004 // Free Software Foundation, Inc.
00005 //
00006 // This file is part of the GNU ISO C++ Library.  This library is free
00007 // software; you can redistribute it and/or modify it under the
00008 // terms of the GNU General Public License as published by the
00009 // Free Software Foundation; either version 3, or (at your option)
00010 // any later version.
00011 
00012 // This library is distributed in the hope that it will be useful,
00013 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00014 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015 // GNU General Public License for more details.
00016 
00017 // Under Section 7 of GPL version 3, you are granted additional
00018 // permissions described in the GCC Runtime Library Exception, version
00019 // 3.1, as published by the Free Software Foundation.
00020 
00021 // You should have received a copy of the GNU General Public License and
00022 // a copy of the GCC Runtime Library Exception along with this program;
00023 // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
00024 // <http://www.gnu.org/licenses/>.
00025 
00026 /** @file bits/cpp_type_traits.h
00027  *  This is an internal header file, included by other library headers.
00028  *  Do not attempt to use it directly. @headername{ext/type_traits}
00029  */
00030 
00031 // Written by Gabriel Dos Reis <dosreis@cmla.ens-cachan.fr>
00032 
00033 #ifndef _CPP_TYPE_TRAITS_H
00034 #define _CPP_TYPE_TRAITS_H 1
00035 
00036 #pragma GCC system_header
00037 
00038 #include <bits/c++config.h>
00039 
00040 //
00041 // This file provides some compile-time information about various types.
00042 // These representations were designed, on purpose, to be constant-expressions
00043 // and not types as found in <bits/type_traits.h>.  In particular, they
00044 // can be used in control structures and the optimizer hopefully will do
00045 // the obvious thing.
00046 //
00047 // Why integral expressions, and not functions nor types?
00048 // Firstly, these compile-time entities are used as template-arguments
00049 // so function return values won't work:  We need compile-time entities.
00050 // We're left with types and constant  integral expressions.
00051 // Secondly, from the point of view of ease of use, type-based compile-time
00052 // information is -not- *that* convenient.  On has to write lots of
00053 // overloaded functions and to hope that the compiler will select the right
00054 // one. As a net effect, the overall structure isn't very clear at first
00055 // glance.
00056 // Thirdly, partial ordering and overload resolution (of function templates)
00057 // is highly costly in terms of compiler-resource.  It is a Good Thing to
00058 // keep these resource consumption as least as possible.
00059 //
00060 // See valarray_array.h for a case use.
00061 //
00062 // -- Gaby (dosreis@cmla.ens-cachan.fr) 2000-03-06.
00063 //
00064 // Update 2005: types are also provided and <bits/type_traits.h> has been
00065 // removed.
00066 //
00067 
00068 // Forward declaration hack, should really include this from somewhere.
00069 namespace __gnu_cxx _GLIBCXX_VISIBILITY(default)
00070 {
00071 _GLIBCXX_BEGIN_NAMESPACE_VERSION
00072 
00073   template<typename _Iterator, typename _Container>
00074     class __normal_iterator;
00075 
00076 _GLIBCXX_END_NAMESPACE_VERSION
00077 } // namespace
00078 
00079 namespace std _GLIBCXX_VISIBILITY(default)
00080 {
00081 _GLIBCXX_BEGIN_NAMESPACE_VERSION
00082 
00083   struct __true_type { };
00084   struct __false_type { };
00085 
00086   template<bool>
00087     struct __truth_type
00088     { typedef __false_type __type; };
00089 
00090   template<>
00091     struct __truth_type<true>
00092     { typedef __true_type __type; };
00093 
00094   // N.B. The conversions to bool are needed due to the issue
00095   // explained in c++/19404.
00096   template<class _Sp, class _Tp>
00097     struct __traitor
00098     {
00099       enum { __value = bool(_Sp::__value) || bool(_Tp::__value) };
00100       typedef typename __truth_type<__value>::__type __type;
00101     };
00102 
00103   // Compare for equality of types.
00104   template<typename, typename>
00105     struct __are_same
00106     {
00107       enum { __value = 0 };
00108       typedef __false_type __type;
00109     };
00110 
00111   template<typename _Tp>
00112     struct __are_same<_Tp, _Tp>
00113     {
00114       enum { __value = 1 };
00115       typedef __true_type __type;
00116     };
00117 
00118   // Holds if the template-argument is a void type.
00119   template<typename _Tp>
00120     struct __is_void
00121     {
00122       enum { __value = 0 };
00123       typedef __false_type __type;
00124     };
00125 
00126   template<>
00127     struct __is_void<void>
00128     {
00129       enum { __value = 1 };
00130       typedef __true_type __type;
00131     };
00132 
00133   //
00134   // Integer types
00135   //
00136   template<typename _Tp>
00137     struct __is_integer
00138     {
00139       enum { __value = 0 };
00140       typedef __false_type __type;
00141     };
00142 
00143   // Thirteen specializations (yes there are eleven standard integer
00144   // types; <em>long long</em> and <em>unsigned long long</em> are
00145   // supported as extensions)
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 #ifdef __GXX_EXPERIMENTAL_CXX0X__
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   //
00256   // Floating point types
00257   //
00258   template<typename _Tp>
00259     struct __is_floating
00260     {
00261       enum { __value = 0 };
00262       typedef __false_type __type;
00263     };
00264 
00265   // three specializations (float, double and 'long double')
00266   template<>
00267     struct __is_floating<float>
00268     {
00269       enum { __value = 1 };
00270       typedef __true_type __type;
00271     };
00272 
00273   template<>
00274     struct __is_floating<double>
00275     {
00276       enum { __value = 1 };
00277       typedef __true_type __type;
00278     };
00279 
00280   template<>
00281     struct __is_floating<long double>
00282     {
00283       enum { __value = 1 };
00284       typedef __true_type __type;
00285     };
00286 
00287   //
00288   // Pointer types
00289   //
00290   template<typename _Tp>
00291     struct __is_pointer
00292     {
00293       enum { __value = 0 };
00294       typedef __false_type __type;
00295     };
00296 
00297   template<typename _Tp>
00298     struct __is_pointer<_Tp*>
00299     {
00300       enum { __value = 1 };
00301       typedef __true_type __type;
00302     };
00303 
00304   //
00305   // Normal iterator type
00306   //
00307   template<typename _Tp>
00308     struct __is_normal_iterator
00309     {
00310       enum { __value = 0 };
00311       typedef __false_type __type;
00312     };
00313 
00314   template<typename _Iterator, typename _Container>
00315     struct __is_normal_iterator< __gnu_cxx::__normal_iterator<_Iterator,
00316                                   _Container> >
00317     {
00318       enum { __value = 1 };
00319       typedef __true_type __type;
00320     };
00321 
00322   //
00323   // An arithmetic type is an integer type or a floating point type
00324   //
00325   template<typename _Tp>
00326     struct __is_arithmetic
00327     : public __traitor<__is_integer<_Tp>, __is_floating<_Tp> >
00328     { };
00329 
00330   //
00331   // A fundamental type is `void' or and arithmetic type
00332   //
00333   template<typename _Tp>
00334     struct __is_fundamental
00335     : public __traitor<__is_void<_Tp>, __is_arithmetic<_Tp> >
00336     { };
00337 
00338   //
00339   // A scalar type is an arithmetic type or a pointer type
00340   // 
00341   template<typename _Tp>
00342     struct __is_scalar
00343     : public __traitor<__is_arithmetic<_Tp>, __is_pointer<_Tp> >
00344     { };
00345 
00346   //
00347   // For use in std::copy and std::find overloads for streambuf iterators.
00348   //
00349   template<typename _Tp>
00350     struct __is_char
00351     {
00352       enum { __value = 0 };
00353       typedef __false_type __type;
00354     };
00355 
00356   template<>
00357     struct __is_char<char>
00358     {
00359       enum { __value = 1 };
00360       typedef __true_type __type;
00361     };
00362 
00363 #ifdef _GLIBCXX_USE_WCHAR_T
00364   template<>
00365     struct __is_char<wchar_t>
00366     {
00367       enum { __value = 1 };
00368       typedef __true_type __type;
00369     };
00370 #endif
00371 
00372   template<typename _Tp>
00373     struct __is_byte
00374     {
00375       enum { __value = 0 };
00376       typedef __false_type __type;
00377     };
00378 
00379   template<>
00380     struct __is_byte<char>
00381     {
00382       enum { __value = 1 };
00383       typedef __true_type __type;
00384     };
00385 
00386   template<>
00387     struct __is_byte<signed char>
00388     {
00389       enum { __value = 1 };
00390       typedef __true_type __type;
00391     };
00392 
00393   template<>
00394     struct __is_byte<unsigned char>
00395     {
00396       enum { __value = 1 };
00397       typedef __true_type __type;
00398     };
00399 
00400   //
00401   // Move iterator type
00402   //
00403   template<typename _Tp>
00404     struct __is_move_iterator
00405     {
00406       enum { __value = 0 };
00407       typedef __false_type __type;
00408     };
00409 
00410 #ifdef __GXX_EXPERIMENTAL_CXX0X__
00411   template<typename _Iterator>
00412     class move_iterator;
00413 
00414   template<typename _Iterator>
00415     struct __is_move_iterator< move_iterator<_Iterator> >
00416     {
00417       enum { __value = 1 };
00418       typedef __true_type __type;
00419     };
00420 #endif
00421 
00422 _GLIBCXX_END_NAMESPACE_VERSION
00423 } // namespace
00424 
00425 #endif //_CPP_TYPE_TRAITS_H