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

Generated on Tue Jan 30 17:31:48 2007 for GNU C++ STL by doxygen 1.3.6