Line data Source code
1 : // The -*- C++ -*- type traits classes for internal use in libstdc++ 2 : 3 : // Copyright (C) 2000-2019 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. One 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 : extern "C++" { 68 : 69 : namespace std _GLIBCXX_VISIBILITY(default) 70 : { 71 : _GLIBCXX_BEGIN_NAMESPACE_VERSION 72 : 73 : struct __true_type { }; 74 : struct __false_type { }; 75 : 76 : template<bool> 77 : struct __truth_type 78 : { typedef __false_type __type; }; 79 : 80 : template<> 81 : struct __truth_type<true> 82 : { typedef __true_type __type; }; 83 : 84 : // N.B. The conversions to bool are needed due to the issue 85 : // explained in c++/19404. 86 : template<class _Sp, class _Tp> 87 : struct __traitor 88 : { 89 : enum { __value = bool(_Sp::__value) || bool(_Tp::__value) }; 90 : typedef typename __truth_type<__value>::__type __type; 91 : }; 92 : 93 : // Compare for equality of types. 94 : template<typename, typename> 95 : struct __are_same 96 : { 97 : enum { __value = 0 }; 98 : typedef __false_type __type; 99 : }; 100 : 101 : template<typename _Tp> 102 : struct __are_same<_Tp, _Tp> 103 : { 104 : enum { __value = 1 }; 105 : typedef __true_type __type; 106 : }; 107 : 108 : // Holds if the template-argument is a void type. 109 : template<typename _Tp> 110 : struct __is_void 111 : { 112 : enum { __value = 0 }; 113 : typedef __false_type __type; 114 : }; 115 : 116 : template<> 117 : struct __is_void<void> 118 : { 119 : enum { __value = 1 }; 120 : typedef __true_type __type; 121 : }; 122 : 123 : // 124 : // Integer types 125 : // 126 : template<typename _Tp> 127 : struct __is_integer 128 : { 129 : enum { __value = 0 }; 130 : typedef __false_type __type; 131 : }; 132 : 133 : // Thirteen specializations (yes there are eleven standard integer 134 : // types; <em>long long</em> and <em>unsigned long long</em> are 135 : // supported as extensions). Up to four target-specific __int<N> 136 : // types are supported as well. 137 : template<> 138 : struct __is_integer<bool> 139 : { 140 : enum { __value = 1 }; 141 : typedef __true_type __type; 142 : }; 143 : 144 : template<> 145 : struct __is_integer<char> 146 : { 147 : enum { __value = 1 }; 148 : typedef __true_type __type; 149 : }; 150 : 151 : template<> 152 : struct __is_integer<signed char> 153 : { 154 : enum { __value = 1 }; 155 : typedef __true_type __type; 156 : }; 157 : 158 : template<> 159 : struct __is_integer<unsigned char> 160 : { 161 : enum { __value = 1 }; 162 : typedef __true_type __type; 163 : }; 164 : 165 : # ifdef _GLIBCXX_USE_WCHAR_T 166 : template<> 167 : struct __is_integer<wchar_t> 168 : { 169 : enum { __value = 1 }; 170 : typedef __true_type __type; 171 : }; 172 : # endif 173 : 174 : #ifdef _GLIBCXX_USE_CHAR8_T 175 : template<> 176 : struct __is_integer<char8_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 : // An arithmetic type is an integer type or a floating point type 335 : // 336 : template<typename _Tp> 337 : struct __is_arithmetic 338 : : public __traitor<__is_integer<_Tp>, __is_floating<_Tp> > 339 : { }; 340 : 341 : // 342 : // A scalar type is an arithmetic type or a pointer type 343 : // 344 : template<typename _Tp> 345 : struct __is_scalar 346 : : public __traitor<__is_arithmetic<_Tp>, __is_pointer<_Tp> > 347 : { }; 348 : 349 : // 350 : // For use in std::copy and std::find overloads for streambuf iterators. 351 : // 352 : template<typename _Tp> 353 : struct __is_char 354 : { 355 : enum { __value = 0 }; 356 : typedef __false_type __type; 357 : }; 358 : 359 : template<> 360 : struct __is_char<char> 361 : { 362 : enum { __value = 1 }; 363 : typedef __true_type __type; 364 : }; 365 : 366 : #ifdef _GLIBCXX_USE_WCHAR_T 367 : template<> 368 : struct __is_char<wchar_t> 369 : { 370 : enum { __value = 1 }; 371 : typedef __true_type __type; 372 : }; 373 : #endif 374 : 375 : template<typename _Tp> 376 : struct __is_byte 377 : { 378 : enum { __value = 0 }; 379 : typedef __false_type __type; 380 : }; 381 : 382 : template<> 383 : struct __is_byte<char> 384 : { 385 : enum { __value = 1 }; 386 : typedef __true_type __type; 387 : }; 388 : 389 : template<> 390 : struct __is_byte<signed char> 391 : { 392 : enum { __value = 1 }; 393 : typedef __true_type __type; 394 : }; 395 : 396 : template<> 397 : struct __is_byte<unsigned char> 398 : { 399 : enum { __value = 1 }; 400 : typedef __true_type __type; 401 : }; 402 : 403 : #if __cplusplus >= 201703L 404 : enum class byte : unsigned char; 405 : 406 : template<> 407 : struct __is_byte<byte> 408 : { 409 : enum { __value = 1 }; 410 : typedef __true_type __type; 411 : }; 412 : #endif // C++17 413 : 414 : // 415 : // Move iterator type 416 : // 417 : template<typename _Tp> 418 : struct __is_move_iterator 419 : { 420 : enum { __value = 0 }; 421 : typedef __false_type __type; 422 : }; 423 : 424 : // Fallback implementation of the function in bits/stl_iterator.h used to 425 : // remove the move_iterator wrapper. 426 : template<typename _Iterator> 427 : inline _Iterator 428 150616861 : __miter_base(_Iterator __it) 429 0 : { return __it; } 430 : 431 : _GLIBCXX_END_NAMESPACE_VERSION 432 : } // namespace 433 : } // extern "C++" 434 : 435 : #endif //_CPP_TYPE_TRAITS_H