1// The -*- C++ -*- type traits classes for internal use in libstdc++ 2 3// Copyright (C) 2000-2014 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) 145 template<> 146 struct __is_integer<bool> 147 { 148 enum { __value = 1 }; 149 typedef __true_type __type; 150 }; 151 152 template<> 153 struct __is_integer<char> 154 { 155 enum { __value = 1 }; 156 typedef __true_type __type; 157 }; 158 159 template<> 160 struct __is_integer<signed char> 161 { 162 enum { __value = 1 }; 163 typedef __true_type __type; 164 }; 165 166 template<> 167 struct __is_integer<unsigned char> 168 { 169 enum { __value = 1 }; 170 typedef __true_type __type; 171 }; 172 173# ifdef _GLIBCXX_USE_WCHAR_T 174 template<> 175 struct __is_integer<wchar_t> 176 { 177 enum { __value = 1 }; 178 typedef __true_type __type; 179 }; 180# endif 181 182#if __cplusplus >= 201103L 183 template<> 184 struct __is_integer<char16_t> 185 { 186 enum { __value = 1 }; 187 typedef __true_type __type; 188 }; 189 190 template<> 191 struct __is_integer<char32_t> 192 { 193 enum { __value = 1 }; 194 typedef __true_type __type; 195 }; 196#endif 197 198 template<> 199 struct __is_integer<short> 200 { 201 enum { __value = 1 }; 202 typedef __true_type __type; 203 }; 204 205 template<> 206 struct __is_integer<unsigned short> 207 { 208 enum { __value = 1 }; 209 typedef __true_type __type; 210 }; 211 212 template<> 213 struct __is_integer<int> 214 { 215 enum { __value = 1 }; 216 typedef __true_type __type; 217 }; 218 219 template<> 220 struct __is_integer<unsigned int> 221 { 222 enum { __value = 1 }; 223 typedef __true_type __type; 224 }; 225 226 template<> 227 struct __is_integer<long> 228 { 229 enum { __value = 1 }; 230 typedef __true_type __type; 231 }; 232 233 template<> 234 struct __is_integer<unsigned long> 235 { 236 enum { __value = 1 }; 237 typedef __true_type __type; 238 }; 239 240 template<> 241 struct __is_integer<long long> 242 { 243 enum { __value = 1 }; 244 typedef __true_type __type; 245 }; 246 247 template<> 248 struct __is_integer<unsigned long long> 249 { 250 enum { __value = 1 }; 251 typedef __true_type __type; 252 }; 253 254 // 255 // Floating point types 256 // 257 template<typename _Tp> 258 struct __is_floating 259 { 260 enum { __value = 0 }; 261 typedef __false_type __type; 262 }; 263 264 // three specializations (float, double and 'long double') 265 template<> 266 struct __is_floating<float> 267 { 268 enum { __value = 1 }; 269 typedef __true_type __type; 270 }; 271 272 template<> 273 struct __is_floating<double> 274 { 275 enum { __value = 1 }; 276 typedef __true_type __type; 277 }; 278 279 template<> 280 struct __is_floating<long double> 281 { 282 enum { __value = 1 }; 283 typedef __true_type __type; 284 }; 285 286 // 287 // Pointer types 288 // 289 template<typename _Tp> 290 struct __is_pointer 291 { 292 enum { __value = 0 }; 293 typedef __false_type __type; 294 }; 295 296 template<typename _Tp> 297 struct __is_pointer<_Tp*> 298 { 299 enum { __value = 1 }; 300 typedef __true_type __type; 301 }; 302 303 // 304 // Normal iterator type 305 // 306 template<typename _Tp> 307 struct __is_normal_iterator 308 { 309 enum { __value = 0 }; 310 typedef __false_type __type; 311 }; 312 313 template<typename _Iterator, typename _Container> 314 struct __is_normal_iterator< __gnu_cxx::__normal_iterator<_Iterator, 315 _Container> > 316 { 317 enum { __value = 1 }; 318 typedef __true_type __type; 319 }; 320 321 // 322 // An arithmetic type is an integer type or a floating point type 323 // 324 template<typename _Tp> 325 struct __is_arithmetic 326 : public __traitor<__is_integer<_Tp>, __is_floating<_Tp> > 327 { }; 328 329 // 330 // A scalar type is an arithmetic type or a pointer type 331 // 332 template<typename _Tp> 333 struct __is_scalar 334 : public __traitor<__is_arithmetic<_Tp>, __is_pointer<_Tp> > 335 { }; 336 337 // 338 // For use in std::copy and std::find overloads for streambuf iterators. 339 // 340 template<typename _Tp> 341 struct __is_char 342 { 343 enum { __value = 0 }; 344 typedef __false_type __type; 345 }; 346 347 template<> 348 struct __is_char<char> 349 { 350 enum { __value = 1 }; 351 typedef __true_type __type; 352 }; 353 354#ifdef _GLIBCXX_USE_WCHAR_T 355 template<> 356 struct __is_char<wchar_t> 357 { 358 enum { __value = 1 }; 359 typedef __true_type __type; 360 }; 361#endif 362 363 template<typename _Tp> 364 struct __is_byte 365 { 366 enum { __value = 0 }; 367 typedef __false_type __type; 368 }; 369 370 template<> 371 struct __is_byte<char> 372 { 373 enum { __value = 1 }; 374 typedef __true_type __type; 375 }; 376 377 template<> 378 struct __is_byte<signed char> 379 { 380 enum { __value = 1 }; 381 typedef __true_type __type; 382 }; 383 384 template<> 385 struct __is_byte<unsigned char> 386 { 387 enum { __value = 1 }; 388 typedef __true_type __type; 389 }; 390 391 // 392 // Move iterator type 393 // 394 template<typename _Tp> 395 struct __is_move_iterator 396 { 397 enum { __value = 0 }; 398 typedef __false_type __type; 399 }; 400 401#if __cplusplus >= 201103L 402 template<typename _Iterator> 403 class move_iterator; 404 405 template<typename _Iterator> 406 struct __is_move_iterator< move_iterator<_Iterator> > 407 { 408 enum { __value = 1 }; 409 typedef __true_type __type; 410 }; 411#endif 412 413_GLIBCXX_END_NAMESPACE_VERSION 414} // namespace 415 416#endif //_CPP_TYPE_TRAITS_H 417