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

Generated on Thu Nov 1 13:11:25 2007 for libstdc++ by  doxygen 1.5.1