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