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

Generated on Sun Sep 12 15:49:57 2004 for libstdc++ source by doxygen 1.3.8