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

Generated on Wed Jun 9 11:18:17 2004 for libstdc++-v3 Source by doxygen 1.3.7