# 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