# 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 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_BITS_CPP_TYPE_TRAITS_H
    00038 #define _CPP_BITS_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 namespace std
    00068 {
    00069   template<typename _Tp>
    00070     struct __is_void
    00071     {
    00072       enum
    00073       {
    00074         _M_type = 0
    00075       };
    00076     };
    00077
    00078   template<>
    00079     struct __is_void<void>
    00080     {
    00081       enum
    00082       {
    00083         _M_type = 1
    00084       };
    00085     };
    00086
    00087   //
    00088   // Integer types
    00089   //
    00090   template<typename _Tp>
    00091     struct __is_integer
    00092     {
    00093       enum
    00094       {
    00095     _M_type = 0
    00096       };
    00097     };
    00098
    00099   // Thirteen specializations (yes there are eleven standard integer
    00100   // types; 'long long' and 'unsigned long long' are supported as
    00101   // extensions)
    00102   template<>
    00103     struct __is_integer<bool>
    00104     {
    00105       enum
    00106       {
    00107     _M_type = 1
    00108       };
    00109     };
    00110
    00111   template<>
    00112     struct __is_integer<char>
    00113     {
    00114       enum
    00115       {
    00116     _M_type = 1
    00117       };
    00118     };
    00119
    00120   template<>
    00121     struct __is_integer<signed char>
    00122     {
    00123       enum
    00124       {
    00125     _M_type = 1
    00126       };
    00127     };
    00128
    00129   template<>
    00130   struct __is_integer<unsigned char>
    00131   {
    00132     enum
    00133     {
    00134       _M_type = 1
    00135     };
    00136   };
    00137
    00138 # ifdef _GLIBCPP_USE_WCHAR_T
    00139   template<>
    00140   struct __is_integer<wchar_t>
    00141   {
    00142     enum
    00143     {
    00144       _M_type = 1
    00145     };
    00146   };
    00147 # endif
    00148
    00149   template<>
    00150   struct __is_integer<short>
    00151   {
    00152     enum
    00153     {
    00154       _M_type = 1
    00155     };
    00156   };
    00157
    00158   template<>
    00159   struct __is_integer<unsigned short>
    00160   {
    00161     enum
    00162     {
    00163       _M_type = 1
    00164     };
    00165   };
    00166
    00167   template<>
    00168   struct __is_integer<int>
    00169   {
    00170     enum
    00171     {
    00172       _M_type = 1
    00173     };
    00174   };
    00175
    00176   template<>
    00177   struct __is_integer<unsigned int>
    00178   {
    00179     enum
    00180     {
    00181       _M_type = 1
    00182     };
    00183   };
    00184
    00185   template<>
    00186   struct __is_integer<long>
    00187   {
    00188     enum
    00189     {
    00190       _M_type = 1
    00191     };
    00192   };
    00193
    00194   template<>
    00195   struct __is_integer<unsigned long>
    00196   {
    00197     enum
    00198     {
    00199       _M_type = 1
    00200     };
    00201   };
    00202
    00203   template<>
    00204   struct __is_integer<long long>
    00205   {
    00206     enum
    00207     {
    00208       _M_type = 1
    00209     };
    00210   };
    00211
    00212   template<>
    00213   struct __is_integer<unsigned long long>
    00214   {
    00215     enum
    00216     {
    00217       _M_type = 1
    00218     };
    00219   };
    00220
    00221   //
    00222   // Floating point types
    00223   //
    00224   template<typename _Tp>
    00225   struct __is_floating
    00226   {
    00227     enum
    00228     {
    00229       _M_type = 0
    00230     };
    00231   };
    00232
    00233   // three specializations (float, double and 'long double')
    00234   template<>
    00235   struct __is_floating<float>
    00236   {
    00237     enum
    00238     {
    00239       _M_type = 1
    00240     };
    00241   };
    00242
    00243   template<>
    00244   struct __is_floating<double>
    00245   {
    00246     enum
    00247     {
    00248       _M_type = 1
    00249     };
    00250   };
    00251
    00252   template<>
    00253   struct __is_floating<long double>
    00254   {
    00255     enum
    00256     {
    00257       _M_type = 1
    00258     };
    00259   };
    00260
    00261   //
    00262   // An arithmetic type is an integer type or a floating point type
    00263   //
    00264   template<typename _Tp>
    00265   struct __is_arithmetic
    00266   {
    00267     enum
    00268     {
    00269       _M_type = __is_integer<_Tp>::_M_type || __is_floating<_Tp>::_M_type
    00270     };
    00271   };
    00272
    00273   //
    00274   // A fundamental type is `void' or and arithmetic type
    00275   //
    00276   template<typename _Tp>
    00277   struct __is_fundamental
    00278   {
    00279     enum
    00280     {
    00281       _M_type = __is_void<_Tp>::_M_type || __is_arithmetic<_Tp>::_M_type
    00282     };
    00283   };
    00284
    00285   //
    00286   // For the immediate use, the following is a good approximation
    00287   //
    00288   template<typename _Tp>
    00289   struct __is_pod
    00290   {
    00291     enum
    00292     {
    00293       _M_type = __is_fundamental<_Tp>::_M_type
    00294     };
    00295   };
    00296
    00297 } // namespace std
    00298
    00299
    00300 #endif //_CPP_BITS_CPP_TYPE_TRAITS_H