# 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, 2006
    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 /** @file cpp_type_traits.h
    00032  *  This is an internal header file, included by other library headers.
    00033  *  You should not attempt to use it directly.
    00034  */
    00035
    00036 // Written by Gabriel Dos Reis <dosreis@cmla.ens-cachan.fr>
    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 // Forward declaration hack, should really include this from somewhere.
    00074 _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
    00075
    00076   template<typename _Iterator, typename _Container>
    00077     class __normal_iterator;
    00078
    00079 _GLIBCXX_END_NAMESPACE
    00080
    00081 _GLIBCXX_BEGIN_NAMESPACE(std)
    00082
    00083 namespace __detail
    00084 {
    00085   // NB: g++ can not compile these if declared within the class
    00086   // __is_pod itself.
    00087   typedef char __one;
    00088   typedef char __two[2];
    00089
    00090   template<typename _Tp>
    00091   __one __test_type(int _Tp::*);
    00092   template<typename _Tp>
    00093   __two& __test_type(...);
    00094 } // namespace __detail
    00095
    00096
    00097   struct __true_type { };
    00098   struct __false_type { };
    00099
    00100   template<bool>
    00101     struct __truth_type
    00102     { typedef __false_type __type; };
    00103
    00104   template<>
    00105     struct __truth_type<true>
    00106     { typedef __true_type __type; };
    00107
    00108   // N.B. The conversions to bool are needed due to the issue
    00109   // explained in c++/19404.
    00110   template<class _Sp, class _Tp>
    00111     struct __traitor
    00112     {
    00113       enum { __value = bool(_Sp::__value) || bool(_Tp::__value) };
    00114       typedef typename __truth_type<__value>::__type __type;
    00115     };
    00116
    00117   // Compare for equality of types.
    00118   template<typename, typename>
    00119     struct __are_same
    00120     {
    00121       enum { __value = 0 };
    00122       typedef __false_type __type;
    00123     };
    00124
    00125   template<typename _Tp>
    00126     struct __are_same<_Tp, _Tp>
    00127     {
    00128       enum { __value = 1 };
    00129       typedef __true_type __type;
    00130     };
    00131
    00132   // Holds if the template-argument is a void type.
    00133   template<typename _Tp>
    00134     struct __is_void
    00135     {
    00136       enum { __value = 0 };
    00137       typedef __false_type __type;
    00138     };
    00139
    00140   template<>
    00141     struct __is_void<void>
    00142     {
    00143       enum { __value = 1 };
    00144       typedef __true_type __type;
    00145     };
    00146
    00147   //
    00148   // Integer types
    00149   //
    00150   template<typename _Tp>
    00151     struct __is_integer
    00152     {
    00153       enum { __value = 0 };
    00154       typedef __false_type __type;
    00155     };
    00156
    00157   // Thirteen specializations (yes there are eleven standard integer
    00158   // types; 'long long' and 'unsigned long long' are supported as
    00159   // extensions)
    00160   template<>
    00161     struct __is_integer<bool>
    00162     {
    00163       enum { __value = 1 };
    00164       typedef __true_type __type;
    00165     };
    00166
    00167   template<>
    00168     struct __is_integer<char>
    00169     {
    00170       enum { __value = 1 };
    00171       typedef __true_type __type;
    00172     };
    00173
    00174   template<>
    00175     struct __is_integer<signed char>
    00176     {
    00177       enum { __value = 1 };
    00178       typedef __true_type __type;
    00179     };
    00180
    00181   template<>
    00182     struct __is_integer<unsigned char>
    00183     {
    00184       enum { __value = 1 };
    00185       typedef __true_type __type;
    00186     };
    00187
    00188 # ifdef _GLIBCXX_USE_WCHAR_T
    00189   template<>
    00190     struct __is_integer<wchar_t>
    00191     {
    00192       enum { __value = 1 };
    00193       typedef __true_type __type;
    00194     };
    00195 # endif
    00196
    00197   template<>
    00198     struct __is_integer<short>
    00199     {
    00200       enum { __value = 1 };
    00201       typedef __true_type __type;
    00202     };
    00203
    00204   template<>
    00205     struct __is_integer<unsigned short>
    00206     {
    00207       enum { __value = 1 };
    00208       typedef __true_type __type;
    00209     };
    00210
    00211   template<>
    00212     struct __is_integer<int>
    00213     {
    00214       enum { __value = 1 };
    00215       typedef __true_type __type;
    00216     };
    00217
    00218   template<>
    00219     struct __is_integer<unsigned int>
    00220     {
    00221       enum { __value = 1 };
    00222       typedef __true_type __type;
    00223     };
    00224
    00225   template<>
    00226     struct __is_integer<long>
    00227     {
    00228       enum { __value = 1 };
    00229       typedef __true_type __type;
    00230     };
    00231
    00232   template<>
    00233     struct __is_integer<unsigned long>
    00234     {
    00235       enum { __value = 1 };
    00236       typedef __true_type __type;
    00237     };
    00238
    00239   template<>
    00240     struct __is_integer<long long>
    00241     {
    00242       enum { __value = 1 };
    00243       typedef __true_type __type;
    00244     };
    00245
    00246   template<>
    00247     struct __is_integer<unsigned long long>
    00248     {
    00249       enum { __value = 1 };
    00250       typedef __true_type __type;
    00251     };
    00252
    00253   //
    00254   // Floating point types
    00255   //
    00256   template<typename _Tp>
    00257     struct __is_floating
    00258     {
    00259       enum { __value = 0 };
    00260       typedef __false_type __type;
    00261     };
    00262
    00263   // three specializations (float, double and 'long double')
    00264   template<>
    00265     struct __is_floating<float>
    00266     {
    00267       enum { __value = 1 };
    00268       typedef __true_type __type;
    00269     };
    00270
    00271   template<>
    00272     struct __is_floating<double>
    00273     {
    00274       enum { __value = 1 };
    00275       typedef __true_type __type;
    00276     };
    00277
    00278   template<>
    00279     struct __is_floating<long double>
    00280     {
    00281       enum { __value = 1 };
    00282       typedef __true_type __type;
    00283     };
    00284
    00285   //
    00286   // Pointer types
    00287   //
    00288   template<typename _Tp>
    00289     struct __is_pointer
    00290     {
    00291       enum { __value = 0 };
    00292       typedef __false_type __type;
    00293     };
    00294
    00295   template<typename _Tp>
    00296     struct __is_pointer<_Tp*>
    00297     {
    00298       enum { __value = 1 };
    00299       typedef __true_type __type;
    00300     };
    00301
    00302   //
    00303   // Normal iterator type
    00304   //
    00305   template<typename _Tp>
    00306     struct __is_normal_iterator
    00307     {
    00308       enum { __value = 0 };
    00309       typedef __false_type __type;
    00310     };
    00311
    00312   template<typename _Iterator, typename _Container>
    00313     struct __is_normal_iterator< __gnu_cxx::__normal_iterator<_Iterator,
    00314                                   _Container> >
    00315     {
    00316       enum { __value = 1 };
    00317       typedef __true_type __type;
    00318     };
    00319
    00320   //
    00321   // An arithmetic type is an integer type or a floating point type
    00322   //
    00323   template<typename _Tp>
    00324     struct __is_arithmetic
    00325     : public __traitor<__is_integer<_Tp>, __is_floating<_Tp> >
    00326     { };
    00327
    00328   //
    00329   // A fundamental type is `void' or and arithmetic type
    00330   //
    00331   template<typename _Tp>
    00332     struct __is_fundamental
    00333     : public __traitor<__is_void<_Tp>, __is_arithmetic<_Tp> >
    00334     { };
    00335
    00336   //
    00337   // A scalar type is an arithmetic type or a pointer type
    00338   //
    00339   template<typename _Tp>
    00340     struct __is_scalar
    00341     : public __traitor<__is_arithmetic<_Tp>, __is_pointer<_Tp> >
    00342     { };
    00343
    00344   // For the immediate use, the following is a good approximation.
    00345   template<typename _Tp>
    00346     struct __is_pod
    00347     {
    00348       enum
    00349     {
    00350       __value = (sizeof(__detail::__test_type<_Tp>(0))
    00351              != sizeof(__detail::__one))
    00352     };
    00353     };
    00354
    00355   //
    00356   // A stripped-down version of std::tr1::is_empty
    00357   //
    00358   template<typename _Tp>
    00359     struct __is_empty
    00360     {
    00361     private:
    00362       template<typename>
    00363         struct __first { };
    00364       template<typename _Up>
    00365         struct __second
    00366         : public _Up { };
    00367
    00368     public:
    00369       enum
    00370     {
    00371       __value = sizeof(__first<_Tp>) == sizeof(__second<_Tp>)
    00372     };
    00373     };
    00374
    00375   //
    00376   // For use in std::copy and std::find overloads for streambuf iterators.
    00377   //
    00378   template<typename _Tp>
    00379     struct __is_char
    00380     {
    00381       enum { __value = 0 };
    00382       typedef __false_type __type;
    00383     };
    00384
    00385   template<>
    00386     struct __is_char<char>
    00387     {
    00388       enum { __value = 1 };
    00389       typedef __true_type __type;
    00390     };
    00391
    00392 #ifdef _GLIBCXX_USE_WCHAR_T
    00393   template<>
    00394     struct __is_char<wchar_t>
    00395     {
    00396       enum { __value = 1 };
    00397       typedef __true_type __type;
    00398     };
    00399 #endif
    00400
    00401 _GLIBCXX_END_NAMESPACE
    00402
    00403 #endif //_CPP_TYPE_TRAITS_H