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
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 2, 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 // You should have received a copy of the GNU General Public License along
00018 // with this library; see the file COPYING.  If not, write to the Free
00019 // Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
00020 // USA.
00021 
00022 // As a special exception, you may use this file as part of a free software
00023 // library without restriction.  Specifically, if other files instantiate
00024 // templates or use macros or inline functions from this file, or you compile
00025 // this file and link it with other files to produce an executable, this
00026 // file does not by itself cause the resulting executable to be covered by
00027 // the GNU General Public License.  This exception does not however
00028 // invalidate any other reasons why the executable file might be covered by
00029 // the GNU General Public License.
00030 
00031 // Written by Gabriel Dos Reis <dosreis@cmla.ens-cachan.fr>
00032 
00033 /** @file cpp_type_traits.h
00034  *  This is an internal header file, included by other library headers.
00035  *  You should not attempt to use it directly.
00036  */
00037 
00038 #ifndef _CPP_TYPE_TRAITS_H
00039 #define _CPP_TYPE_TRAITS_H 1
00040 
00041 #pragma GCC system_header
00042 
00043 #include <bits/c++config.h>
00044 
00045 //
00046 // This file provides some compile-time information about various types.
00047 // These representations were designed, on purpose, to be constant-expressions
00048 // and not types as found in <bits/type_traits.h>.  In particular, they
00049 // can be used in control structures and the optimizer hopefully will do
00050 // the obvious thing.
00051 //
00052 // Why integral expressions, and not functions nor types?
00053 // Firstly, these compile-time entities are used as template-arguments
00054 // so function return values won't work:  We need compile-time entities.
00055 // We're left with types and constant  integral expressions.
00056 // Secondly, from the point of view of ease of use, type-based compile-time
00057 // information is -not- *that* convenient.  On has to write lots of
00058 // overloaded functions and to hope that the compiler will select the right
00059 // one. As a net effect, the overall structure isn't very clear at first
00060 // glance.
00061 // Thirdly, partial ordering and overload resolution (of function templates)
00062 // is highly costly in terms of compiler-resource.  It is a Good Thing to
00063 // keep these resource consumption as least as possible.
00064 //
00065 // See valarray_array.h for a case use.
00066 //
00067 // -- Gaby (dosreis@cmla.ens-cachan.fr) 2000-03-06.
00068 //
00069 // Update 2005: types are also provided and <bits/type_traits.h> has been
00070 // removed.
00071 //
00072 
00073 // NB: g++ can not compile these if declared within the class
00074 // __is_pod itself.
00075 namespace __gnu_internal
00076 {
00077   typedef char __one;
00078   typedef char __two[2];
00079 
00080   template<typename _Tp>
00081   __one __test_type(int _Tp::*);
00082   template<typename _Tp>
00083   __two& __test_type(...);
00084 } // namespace __gnu_internal
00085 
00086 // Forward declaration hack, should really include this from somewhere.
00087 namespace __gnu_cxx
00088 {
00089   template<typename _Iterator, typename _Container>
00090     class __normal_iterator;
00091 } // namespace __gnu_cxx
00092 
00093 struct __true_type { };
00094 struct __false_type { };
00095 
00096 namespace std
00097 {
00098   template<bool>
00099     struct __truth_type
00100     { typedef __false_type __type; };
00101 
00102   template<>
00103     struct __truth_type<true>
00104     { typedef __true_type __type; };
00105 
00106   // N.B. The conversions to bool are needed due to the issue
00107   // explained in c++/19404.
00108   template<class _Sp, class _Tp>
00109     struct __traitor
00110     {
00111       enum { __value = bool(_Sp::__value) || bool(_Tp::__value) };
00112       typedef typename __truth_type<__value>::__type __type;
00113     };
00114 
00115   // Compare for equality of types.
00116   template<typename, typename>
00117     struct __are_same
00118     {
00119       enum { __value = 0 };
00120       typedef __false_type __type;
00121     };
00122 
00123   template<typename _Tp>
00124     struct __are_same<_Tp, _Tp>
00125     {
00126       enum { __value = 1 };
00127       typedef __true_type __type;
00128     };
00129 
00130   // Define a nested type if some predicate holds.
00131   template<typename, bool>
00132     struct __enable_if
00133     { 
00134     };
00135 
00136   template<typename _Tp>
00137     struct __enable_if<_Tp, true>
00138     {
00139       typedef _Tp __type;
00140     };
00141 
00142   // Holds if the template-argument is a void type.
00143   template<typename _Tp>
00144     struct __is_void
00145     {
00146       enum { __value = 0 };
00147       typedef __false_type __type;
00148     };
00149 
00150   template<>
00151     struct __is_void<void>
00152     {
00153       enum { __value = 1 };
00154       typedef __true_type __type;
00155     };
00156 
00157   //
00158   // Integer types
00159   //
00160   template<typename _Tp>
00161     struct __is_integer
00162     {
00163       enum { __value = 0 };
00164       typedef __false_type __type;
00165     };
00166 
00167   // Thirteen specializations (yes there are eleven standard integer
00168   // types; 'long long' and 'unsigned long long' are supported as
00169   // extensions)
00170   template<>
00171     struct __is_integer<bool>
00172     {
00173       enum { __value = 1 };
00174       typedef __true_type __type;
00175     };
00176 
00177   template<>
00178     struct __is_integer<char>
00179     {
00180       enum { __value = 1 };
00181       typedef __true_type __type;
00182     };
00183 
00184   template<>
00185     struct __is_integer<signed char>
00186     {
00187       enum { __value = 1 };
00188       typedef __true_type __type;
00189     };
00190 
00191   template<>
00192     struct __is_integer<unsigned char>
00193     {
00194       enum { __value = 1 };
00195       typedef __true_type __type;
00196     };
00197 
00198 # ifdef _GLIBCXX_USE_WCHAR_T
00199   template<>
00200     struct __is_integer<wchar_t>
00201     {
00202       enum { __value = 1 };
00203       typedef __true_type __type;
00204     };
00205 # endif
00206 
00207   template<>
00208     struct __is_integer<short>
00209     {
00210       enum { __value = 1 };
00211       typedef __true_type __type;
00212     };
00213 
00214   template<>
00215     struct __is_integer<unsigned short>
00216     {
00217       enum { __value = 1 };
00218       typedef __true_type __type;
00219     };
00220 
00221   template<>
00222     struct __is_integer<int>
00223     {
00224       enum { __value = 1 };
00225       typedef __true_type __type;
00226     };
00227 
00228   template<>
00229     struct __is_integer<unsigned int>
00230     {
00231       enum { __value = 1 };
00232       typedef __true_type __type;
00233     };
00234 
00235   template<>
00236     struct __is_integer<long>
00237     {
00238       enum { __value = 1 };
00239       typedef __true_type __type;
00240     };
00241 
00242   template<>
00243     struct __is_integer<unsigned long>
00244     {
00245       enum { __value = 1 };
00246       typedef __true_type __type;
00247     };
00248 
00249   template<>
00250     struct __is_integer<long long>
00251     {
00252       enum { __value = 1 };
00253       typedef __true_type __type;
00254     };
00255 
00256   template<>
00257     struct __is_integer<unsigned long long>
00258     {
00259       enum { __value = 1 };
00260       typedef __true_type __type;
00261     };
00262 
00263   //
00264   // Floating point types
00265   //
00266   template<typename _Tp>
00267     struct __is_floating
00268     {
00269       enum { __value = 0 };
00270       typedef __false_type __type;
00271     };
00272 
00273   // three specializations (float, double and 'long double')
00274   template<>
00275     struct __is_floating<float>
00276     {
00277       enum { __value = 1 };
00278       typedef __true_type __type;
00279     };
00280 
00281   template<>
00282     struct __is_floating<double>
00283     {
00284       enum { __value = 1 };
00285       typedef __true_type __type;
00286     };
00287 
00288   template<>
00289     struct __is_floating<long double>
00290     {
00291       enum { __value = 1 };
00292       typedef __true_type __type;
00293     };
00294 
00295   //
00296   // Pointer types
00297   //
00298   template<typename _Tp>
00299     struct __is_pointer
00300     {
00301       enum { __value = 0 };
00302       typedef __false_type __type;
00303     };
00304 
00305   template<typename _Tp>
00306     struct __is_pointer<_Tp*>
00307     {
00308       enum { __value = 1 };
00309       typedef __true_type __type;
00310     };
00311 
00312   //
00313   // Normal iterator type
00314   //
00315   template<typename _Tp>
00316     struct __is_normal_iterator
00317     {
00318       enum { __value = 0 };
00319       typedef __false_type __type;
00320     };
00321 
00322   template<typename _Iterator, typename _Container>
00323     struct __is_normal_iterator< __gnu_cxx::__normal_iterator<_Iterator,
00324                                   _Container> >
00325     {
00326       enum { __value = 1 };
00327       typedef __true_type __type;
00328     };
00329 
00330   //
00331   // An arithmetic type is an integer type or a floating point type
00332   //
00333   template<typename _Tp>
00334     struct __is_arithmetic
00335     : public __traitor<__is_integer<_Tp>, __is_floating<_Tp> >
00336     { };
00337 
00338   //
00339   // A fundamental type is `void' or and arithmetic type
00340   //
00341   template<typename _Tp>
00342     struct __is_fundamental
00343     : public __traitor<__is_void<_Tp>, __is_arithmetic<_Tp> >
00344     { };
00345 
00346   //
00347   // A scalar type is an arithmetic type or a pointer type
00348   // 
00349   template<typename _Tp>
00350     struct __is_scalar
00351     : public __traitor<__is_arithmetic<_Tp>, __is_pointer<_Tp> >
00352     { };
00353 
00354   //
00355   // For the immediate use, the following is a good approximation
00356   //
00357   template<typename _Tp>
00358     struct __is_pod
00359     {
00360       enum
00361     {
00362       __value = (sizeof(__gnu_internal::__test_type<_Tp>(0))
00363              != sizeof(__gnu_internal::__one))
00364     };
00365     };
00366 
00367   //
00368   // A stripped-down version of std::tr1::is_empty
00369   //
00370   template<typename _Tp>
00371     struct __is_empty
00372     { 
00373     private:
00374       template<typename>
00375         struct __first { };
00376       template<typename _Up>
00377         struct __second
00378         : public _Up { };
00379            
00380     public:
00381       enum
00382     {
00383       __value = sizeof(__first<_Tp>) == sizeof(__second<_Tp>)
00384     };
00385     };
00386 
00387 } // namespace std
00388 
00389 #endif //_CPP_TYPE_TRAITS_H

Generated on Thu Nov 1 17:35:57 2007 for libstdc++ by  doxygen 1.5.1