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