1 // The -*- C++ -*- type traits classes for internal use in libstdc++ 2 3 // Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2009, 2010 4 // Free Software Foundation, Inc. 5 // 6 // This file is part of the GNU ISO C++ Library. This library is free 7 // software; you can redistribute it and/or modify it under the 8 // terms of the GNU General Public License as published by the 9 // Free Software Foundation; either version 3, or (at your option) 10 // any later version. 11 12 // This library is distributed in the hope that it will be useful, 13 // but WITHOUT ANY WARRANTY; without even the implied warranty of 14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 // GNU General Public License for more details. 16 17 // Under Section 7 of GPL version 3, you are granted additional 18 // permissions described in the GCC Runtime Library Exception, version 19 // 3.1, as published by the Free Software Foundation. 20 21 // You should have received a copy of the GNU General Public License and 22 // a copy of the GCC Runtime Library Exception along with this program; 23 // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 24 // <http://www.gnu.org/licenses/>. 25 26 /** @file bits/cpp_type_traits.h 27 * This is an internal header file, included by other library headers. 28 * Do not attempt to use it directly. @headername{ext/type_traits} 29 */ 30 31 // Written by Gabriel Dos Reis <dosreis (at) cmla.ens-cachan.fr> 32 33 #ifndef _CPP_TYPE_TRAITS_H 34 #define _CPP_TYPE_TRAITS_H 1 35 36 #pragma GCC system_header 37 38 #include <bits/c++config.h> 39 40 // 41 // This file provides some compile-time information about various types. 42 // These representations were designed, on purpose, to be constant-expressions 43 // and not types as found in <bits/type_traits.h>. In particular, they 44 // can be used in control structures and the optimizer hopefully will do 45 // the obvious thing. 46 // 47 // Why integral expressions, and not functions nor types? 48 // Firstly, these compile-time entities are used as template-arguments 49 // so function return values won't work: We need compile-time entities. 50 // We're left with types and constant integral expressions. 51 // Secondly, from the point of view of ease of use, type-based compile-time 52 // information is -not- *that* convenient. On has to write lots of 53 // overloaded functions and to hope that the compiler will select the right 54 // one. As a net effect, the overall structure isn't very clear at first 55 // glance. 56 // Thirdly, partial ordering and overload resolution (of function templates) 57 // is highly costly in terms of compiler-resource. It is a Good Thing to 58 // keep these resource consumption as least as possible. 59 // 60 // See valarray_array.h for a case use. 61 // 62 // -- Gaby (dosreis (at) cmla.ens-cachan.fr) 2000-03-06. 63 // 64 // Update 2005: types are also provided and <bits/type_traits.h> has been 65 // removed. 66 // 67 68 // Forward declaration hack, should really include this from somewhere. 69 namespace __gnu_cxx _GLIBCXX_VISIBILITY(default) 70 { 71 _GLIBCXX_BEGIN_NAMESPACE_VERSION 72 73 template<typename _Iterator, typename _Container> 74 class __normal_iterator; 75 76 _GLIBCXX_END_NAMESPACE_VERSION 77 } // namespace 78 79 namespace std _GLIBCXX_VISIBILITY(default) 80 { 81 _GLIBCXX_BEGIN_NAMESPACE_VERSION 82 83 struct __true_type { }; 84 struct __false_type { }; 85 86 template<bool> 87 struct __truth_type 88 { typedef __false_type __type; }; 89 90 template<> 91 struct __truth_type<true> 92 { typedef __true_type __type; }; 93 94 // N.B. The conversions to bool are needed due to the issue 95 // explained in c++/19404. 96 template<class _Sp, class _Tp> 97 struct __traitor 98 { 99 enum { __value = bool(_Sp::__value) || bool(_Tp::__value) }; 100 typedef typename __truth_type<__value>::__type __type; 101 }; 102 103 // Compare for equality of types. 104 template<typename, typename> 105 struct __are_same 106 { 107 enum { __value = 0 }; 108 typedef __false_type __type; 109 }; 110 111 template<typename _Tp> 112 struct __are_same<_Tp, _Tp> 113 { 114 enum { __value = 1 }; 115 typedef __true_type __type; 116 }; 117 118 // Holds if the template-argument is a void type. 119 template<typename _Tp> 120 struct __is_void 121 { 122 enum { __value = 0 }; 123 typedef __false_type __type; 124 }; 125 126 template<> 127 struct __is_void<void> 128 { 129 enum { __value = 1 }; 130 typedef __true_type __type; 131 }; 132 133 // 134 // Integer types 135 // 136 template<typename _Tp> 137 struct __is_integer 138 { 139 enum { __value = 0 }; 140 typedef __false_type __type; 141 }; 142 143 // Thirteen specializations (yes there are eleven standard integer 144 // types; <em>long long</em> and <em>unsigned long long</em> are 145 // supported as extensions) 146 template<> 147 struct __is_integer<bool> 148 { 149 enum { __value = 1 }; 150 typedef __true_type __type; 151 }; 152 153 template<> 154 struct __is_integer<char> 155 { 156 enum { __value = 1 }; 157 typedef __true_type __type; 158 }; 159 160 template<> 161 struct __is_integer<signed char> 162 { 163 enum { __value = 1 }; 164 typedef __true_type __type; 165 }; 166 167 template<> 168 struct __is_integer<unsigned char> 169 { 170 enum { __value = 1 }; 171 typedef __true_type __type; 172 }; 173 174 # ifdef _GLIBCXX_USE_WCHAR_T 175 template<> 176 struct __is_integer<wchar_t> 177 { 178 enum { __value = 1 }; 179 typedef __true_type __type; 180 }; 181 # endif 182 183 #ifdef __GXX_EXPERIMENTAL_CXX0X__ 184 template<> 185 struct __is_integer<char16_t> 186 { 187 enum { __value = 1 }; 188 typedef __true_type __type; 189 }; 190 191 template<> 192 struct __is_integer<char32_t> 193 { 194 enum { __value = 1 }; 195 typedef __true_type __type; 196 }; 197 #endif 198 199 template<> 200 struct __is_integer<short> 201 { 202 enum { __value = 1 }; 203 typedef __true_type __type; 204 }; 205 206 template<> 207 struct __is_integer<unsigned short> 208 { 209 enum { __value = 1 }; 210 typedef __true_type __type; 211 }; 212 213 template<> 214 struct __is_integer<int> 215 { 216 enum { __value = 1 }; 217 typedef __true_type __type; 218 }; 219 220 template<> 221 struct __is_integer<unsigned int> 222 { 223 enum { __value = 1 }; 224 typedef __true_type __type; 225 }; 226 227 template<> 228 struct __is_integer<long> 229 { 230 enum { __value = 1 }; 231 typedef __true_type __type; 232 }; 233 234 template<> 235 struct __is_integer<unsigned long> 236 { 237 enum { __value = 1 }; 238 typedef __true_type __type; 239 }; 240 241 template<> 242 struct __is_integer<long long> 243 { 244 enum { __value = 1 }; 245 typedef __true_type __type; 246 }; 247 248 template<> 249 struct __is_integer<unsigned long long> 250 { 251 enum { __value = 1 }; 252 typedef __true_type __type; 253 }; 254 255 // 256 // Floating point types 257 // 258 template<typename _Tp> 259 struct __is_floating 260 { 261 enum { __value = 0 }; 262 typedef __false_type __type; 263 }; 264 265 // three specializations (float, double and 'long double') 266 template<> 267 struct __is_floating<float> 268 { 269 enum { __value = 1 }; 270 typedef __true_type __type; 271 }; 272 273 template<> 274 struct __is_floating<double> 275 { 276 enum { __value = 1 }; 277 typedef __true_type __type; 278 }; 279 280 template<> 281 struct __is_floating<long double> 282 { 283 enum { __value = 1 }; 284 typedef __true_type __type; 285 }; 286 287 // 288 // Pointer types 289 // 290 template<typename _Tp> 291 struct __is_pointer 292 { 293 enum { __value = 0 }; 294 typedef __false_type __type; 295 }; 296 297 template<typename _Tp> 298 struct __is_pointer<_Tp*> 299 { 300 enum { __value = 1 }; 301 typedef __true_type __type; 302 }; 303 304 // 305 // Normal iterator type 306 // 307 template<typename _Tp> 308 struct __is_normal_iterator 309 { 310 enum { __value = 0 }; 311 typedef __false_type __type; 312 }; 313 314 template<typename _Iterator, typename _Container> 315 struct __is_normal_iterator< __gnu_cxx::__normal_iterator<_Iterator, 316 _Container> > 317 { 318 enum { __value = 1 }; 319 typedef __true_type __type; 320 }; 321 322 // 323 // An arithmetic type is an integer type or a floating point type 324 // 325 template<typename _Tp> 326 struct __is_arithmetic 327 : public __traitor<__is_integer<_Tp>, __is_floating<_Tp> > 328 { }; 329 330 // 331 // A fundamental type is `void' or and arithmetic type 332 // 333 template<typename _Tp> 334 struct __is_fundamental 335 : public __traitor<__is_void<_Tp>, __is_arithmetic<_Tp> > 336 { }; 337 338 // 339 // A scalar type is an arithmetic type or a pointer type 340 // 341 template<typename _Tp> 342 struct __is_scalar 343 : public __traitor<__is_arithmetic<_Tp>, __is_pointer<_Tp> > 344 { }; 345 346 // 347 // For use in std::copy and std::find overloads for streambuf iterators. 348 // 349 template<typename _Tp> 350 struct __is_char 351 { 352 enum { __value = 0 }; 353 typedef __false_type __type; 354 }; 355 356 template<> 357 struct __is_char<char> 358 { 359 enum { __value = 1 }; 360 typedef __true_type __type; 361 }; 362 363 #ifdef _GLIBCXX_USE_WCHAR_T 364 template<> 365 struct __is_char<wchar_t> 366 { 367 enum { __value = 1 }; 368 typedef __true_type __type; 369 }; 370 #endif 371 372 template<typename _Tp> 373 struct __is_byte 374 { 375 enum { __value = 0 }; 376 typedef __false_type __type; 377 }; 378 379 template<> 380 struct __is_byte<char> 381 { 382 enum { __value = 1 }; 383 typedef __true_type __type; 384 }; 385 386 template<> 387 struct __is_byte<signed char> 388 { 389 enum { __value = 1 }; 390 typedef __true_type __type; 391 }; 392 393 template<> 394 struct __is_byte<unsigned char> 395 { 396 enum { __value = 1 }; 397 typedef __true_type __type; 398 }; 399 400 // 401 // Move iterator type 402 // 403 template<typename _Tp> 404 struct __is_move_iterator 405 { 406 enum { __value = 0 }; 407 typedef __false_type __type; 408 }; 409 410 #ifdef __GXX_EXPERIMENTAL_CXX0X__ 411 template<typename _Iterator> 412 class move_iterator; 413 414 template<typename _Iterator> 415 struct __is_move_iterator< move_iterator<_Iterator> > 416 { 417 enum { __value = 1 }; 418 typedef __true_type __type; 419 }; 420 #endif 421 422 _GLIBCXX_END_NAMESPACE_VERSION 423 } // namespace 424 425 #endif //_CPP_TYPE_TRAITS_H 426