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 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 00032 /** @file cpp_type_traits.h 00033 * This is an internal header file, included by other library headers. 00034 * You should not attempt to use it directly. 00035 */ 00036 00037 #ifndef _CPP_TYPE_TRAITS_H 00038 #define _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 // NB: g++ can not compile these if declared within the class 00068 // __is_pod itself. 00069 namespace __gnu_internal 00070 { 00071 typedef char __one; 00072 typedef char __two[2]; 00073 00074 template <typename _Tp> 00075 __one __test_type (int _Tp::*); 00076 template <typename _Tp> 00077 __two& __test_type (...); 00078 } // namespace __gnu_internal 00079 00080 namespace std 00081 { 00082 // Compare for equality of types. 00083 template<typename, typename> 00084 struct __are_same 00085 { 00086 enum 00087 { 00088 _M_type = 0 00089 }; 00090 }; 00091 00092 template<typename _Tp> 00093 struct __are_same<_Tp, _Tp> 00094 { 00095 enum 00096 { 00097 _M_type = 1 00098 }; 00099 }; 00100 00101 // Define a nested type if some predicate holds. 00102 template<typename, bool> 00103 struct __enable_if 00104 { 00105 }; 00106 00107 template<typename _Tp> 00108 struct __enable_if<_Tp, true> 00109 { 00110 typedef _Tp _M_type; 00111 }; 00112 00113 // Holds if the template-argument is a void type. 00114 template<typename _Tp> 00115 struct __is_void 00116 { 00117 enum 00118 { 00119 _M_type = 0 00120 }; 00121 }; 00122 00123 template<> 00124 struct __is_void<void> 00125 { 00126 enum 00127 { 00128 _M_type = 1 00129 }; 00130 }; 00131 00132 // 00133 // Integer types 00134 // 00135 template<typename _Tp> 00136 struct __is_integer 00137 { 00138 enum 00139 { 00140 _M_type = 0 00141 }; 00142 }; 00143 00144 // Thirteen specializations (yes there are eleven standard integer 00145 // types; 'long long' and 'unsigned long long' are supported as 00146 // extensions) 00147 template<> 00148 struct __is_integer<bool> 00149 { 00150 enum 00151 { 00152 _M_type = 1 00153 }; 00154 }; 00155 00156 template<> 00157 struct __is_integer<char> 00158 { 00159 enum 00160 { 00161 _M_type = 1 00162 }; 00163 }; 00164 00165 template<> 00166 struct __is_integer<signed char> 00167 { 00168 enum 00169 { 00170 _M_type = 1 00171 }; 00172 }; 00173 00174 template<> 00175 struct __is_integer<unsigned char> 00176 { 00177 enum 00178 { 00179 _M_type = 1 00180 }; 00181 }; 00182 00183 # ifdef _GLIBCXX_USE_WCHAR_T 00184 template<> 00185 struct __is_integer<wchar_t> 00186 { 00187 enum 00188 { 00189 _M_type = 1 00190 }; 00191 }; 00192 # endif 00193 00194 template<> 00195 struct __is_integer<short> 00196 { 00197 enum 00198 { 00199 _M_type = 1 00200 }; 00201 }; 00202 00203 template<> 00204 struct __is_integer<unsigned short> 00205 { 00206 enum 00207 { 00208 _M_type = 1 00209 }; 00210 }; 00211 00212 template<> 00213 struct __is_integer<int> 00214 { 00215 enum 00216 { 00217 _M_type = 1 00218 }; 00219 }; 00220 00221 template<> 00222 struct __is_integer<unsigned int> 00223 { 00224 enum 00225 { 00226 _M_type = 1 00227 }; 00228 }; 00229 00230 template<> 00231 struct __is_integer<long> 00232 { 00233 enum 00234 { 00235 _M_type = 1 00236 }; 00237 }; 00238 00239 template<> 00240 struct __is_integer<unsigned long> 00241 { 00242 enum 00243 { 00244 _M_type = 1 00245 }; 00246 }; 00247 00248 template<> 00249 struct __is_integer<long long> 00250 { 00251 enum 00252 { 00253 _M_type = 1 00254 }; 00255 }; 00256 00257 template<> 00258 struct __is_integer<unsigned long long> 00259 { 00260 enum 00261 { 00262 _M_type = 1 00263 }; 00264 }; 00265 00266 // 00267 // Floating point types 00268 // 00269 template<typename _Tp> 00270 struct __is_floating 00271 { 00272 enum 00273 { 00274 _M_type = 0 00275 }; 00276 }; 00277 00278 // three specializations (float, double and 'long double') 00279 template<> 00280 struct __is_floating<float> 00281 { 00282 enum 00283 { 00284 _M_type = 1 00285 }; 00286 }; 00287 00288 template<> 00289 struct __is_floating<double> 00290 { 00291 enum 00292 { 00293 _M_type = 1 00294 }; 00295 }; 00296 00297 template<> 00298 struct __is_floating<long double> 00299 { 00300 enum 00301 { 00302 _M_type = 1 00303 }; 00304 }; 00305 00306 // 00307 // An arithmetic type is an integer type or a floating point type 00308 // 00309 template<typename _Tp> 00310 struct __is_arithmetic 00311 { 00312 enum 00313 { 00314 _M_type = __is_integer<_Tp>::_M_type || __is_floating<_Tp>::_M_type 00315 }; 00316 }; 00317 00318 // 00319 // A fundamental type is `void' or and arithmetic type 00320 // 00321 template<typename _Tp> 00322 struct __is_fundamental 00323 { 00324 enum 00325 { 00326 _M_type = __is_void<_Tp>::_M_type || __is_arithmetic<_Tp>::_M_type 00327 }; 00328 }; 00329 00330 // 00331 // For the immediate use, the following is a good approximation 00332 // 00333 template<typename _Tp> 00334 struct __is_pod 00335 { 00336 enum 00337 { 00338 _M_type = (sizeof(__gnu_internal::__test_type<_Tp>(0)) 00339 != sizeof(__gnu_internal::__one)) 00340 }; 00341 }; 00342 00343 } // namespace std 00344 00345 #endif //_CPP_TYPE_TRAITS_H

Generated on Tue Sep 7 10:05:02 2004 for libstdc++-v3 Source by doxygen 1.3.8