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