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, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
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   template<class _Sp, class _Tp>
00107     struct __traitor
00108     {
00109       enum { __value = _Sp::__value || _Tp::__value };
00110       typedef typename __truth_type<__value>::__type __type;
00111     };
00112 
00113   // Compare for equality of types.
00114   template<typename, typename>
00115     struct __are_same
00116     {
00117       enum { __value = 0 };
00118       typedef __false_type __type;
00119     };
00120 
00121   template<typename _Tp>
00122     struct __are_same<_Tp, _Tp>
00123     {
00124       enum { __value = 1 };
00125       typedef __true_type __type;
00126     };
00127 
00128   // Define a nested type if some predicate holds.
00129   template<typename, bool>
00130     struct __enable_if
00131     { 
00132     };
00133 
00134   template<typename _Tp>
00135     struct __enable_if<_Tp, true>
00136     {
00137       typedef _Tp __type;
00138     };
00139 
00140   // Holds if the template-argument is a void type.
00141   template<typename _Tp>
00142     struct __is_void
00143     {
00144       enum { __value = 0 };
00145       typedef __false_type __type;
00146     };
00147 
00148   template<>
00149     struct __is_void<void>
00150     {
00151       enum { __value = 1 };
00152       typedef __true_type __type;
00153     };
00154 
00155   //
00156   // Integer types
00157   //
00158   template<typename _Tp>
00159     struct __is_integer
00160     {
00161       enum { __value = 0 };
00162       typedef __false_type __type;
00163     };
00164 
00165   // Thirteen specializations (yes there are eleven standard integer
00166   // types; 'long long' and 'unsigned long long' are supported as
00167   // extensions)
00168   template<>
00169     struct __is_integer<bool>
00170     {
00171       enum { __value = 1 };
00172       typedef __true_type __type;
00173     };
00174 
00175   template<>
00176     struct __is_integer<char>
00177     {
00178       enum { __value = 1 };
00179       typedef __true_type __type;
00180     };
00181 
00182   template<>
00183     struct __is_integer<signed char>
00184     {
00185       enum { __value = 1 };
00186       typedef __true_type __type;
00187     };
00188 
00189   template<>
00190     struct __is_integer<unsigned char>
00191     {
00192       enum { __value = 1 };
00193       typedef __true_type __type;
00194     };
00195 
00196 # ifdef _GLIBCXX_USE_WCHAR_T
00197   template<>
00198     struct __is_integer<wchar_t>
00199     {
00200       enum { __value = 1 };
00201       typedef __true_type __type;
00202     };
00203 # endif
00204 
00205   template<>
00206     struct __is_integer<short>
00207     {
00208       enum { __value = 1 };
00209       typedef __true_type __type;
00210     };
00211 
00212   template<>
00213     struct __is_integer<unsigned short>
00214     {
00215       enum { __value = 1 };
00216       typedef __true_type __type;
00217     };
00218 
00219   template<>
00220     struct __is_integer<int>
00221     {
00222       enum { __value = 1 };
00223       typedef __true_type __type;
00224     };
00225 
00226   template<>
00227     struct __is_integer<unsigned int>
00228     {
00229       enum { __value = 1 };
00230       typedef __true_type __type;
00231     };
00232 
00233   template<>
00234     struct __is_integer<long>
00235     {
00236       enum { __value = 1 };
00237       typedef __true_type __type;
00238     };
00239 
00240   template<>
00241     struct __is_integer<unsigned long>
00242     {
00243       enum { __value = 1 };
00244       typedef __true_type __type;
00245     };
00246 
00247   template<>
00248     struct __is_integer<long long>
00249     {
00250       enum { __value = 1 };
00251       typedef __true_type __type;
00252     };
00253 
00254   template<>
00255     struct __is_integer<unsigned long long>
00256     {
00257       enum { __value = 1 };
00258       typedef __true_type __type;
00259     };
00260 
00261   //
00262   // Floating point types
00263   //
00264   template<typename _Tp>
00265     struct __is_floating
00266     {
00267       enum { __value = 0 };
00268       typedef __false_type __type;
00269     };
00270 
00271   // three specializations (float, double and 'long double')
00272   template<>
00273     struct __is_floating<float>
00274     {
00275       enum { __value = 1 };
00276       typedef __true_type __type;
00277     };
00278 
00279   template<>
00280     struct __is_floating<double>
00281     {
00282       enum { __value = 1 };
00283       typedef __true_type __type;
00284     };
00285 
00286   template<>
00287     struct __is_floating<long double>
00288     {
00289       enum { __value = 1 };
00290       typedef __true_type __type;
00291     };
00292 
00293   //
00294   // Pointer types
00295   //
00296   template<typename _Tp>
00297     struct __is_pointer
00298     {
00299       enum { __value = 0 };
00300       typedef __false_type __type;
00301     };
00302 
00303   template<typename _Tp>
00304     struct __is_pointer<_Tp*>
00305     {
00306       enum { __value = 1 };
00307       typedef __true_type __type;
00308     };
00309 
00310   //
00311   // Normal iterator type
00312   //
00313   template<typename _Tp>
00314     struct __is_normal_iterator
00315     {
00316       enum { __value = 0 };
00317       typedef __false_type __type;
00318     };
00319 
00320   template<typename _Iterator, typename _Container>
00321     struct __is_normal_iterator< __gnu_cxx::__normal_iterator<_Iterator,
00322                                   _Container> >
00323     {
00324       enum { __value = 1 };
00325       typedef __true_type __type;
00326     };
00327 
00328   //
00329   // An arithmetic type is an integer type or a floating point type
00330   //
00331   template<typename _Tp>
00332     struct __is_arithmetic
00333     : public __traitor<__is_integer<_Tp>, __is_floating<_Tp> >
00334     { };
00335 
00336   //
00337   // A fundamental type is `void' or and arithmetic type
00338   //
00339   template<typename _Tp>
00340     struct __is_fundamental
00341     : public __traitor<__is_void<_Tp>, __is_arithmetic<_Tp> >
00342     { };
00343 
00344   //
00345   // A scalar type is an arithmetic type or a pointer type
00346   // 
00347   template<typename _Tp>
00348     struct __is_scalar
00349     : public __traitor<__is_arithmetic<_Tp>, __is_pointer<_Tp> >
00350     { };
00351 
00352   //
00353   // For the immediate use, the following is a good approximation
00354   //
00355   template<typename _Tp>
00356     struct __is_pod
00357     {
00358       enum
00359     {
00360       __value = (sizeof(__gnu_internal::__test_type<_Tp>(0))
00361              != sizeof(__gnu_internal::__one))
00362     };
00363     };
00364 
00365 } // namespace std
00366 
00367 #endif //_CPP_TYPE_TRAITS_H

Generated on Wed Apr 27 18:35:10 2005 for libstdc++ source by  doxygen 1.4.2