]> git.ipfire.org Git - thirdparty/gcc.git/blame - libstdc++-v3/include/bits/cpp_type_traits.h
Update copyright years.
[thirdparty/gcc.git] / libstdc++-v3 / include / bits / cpp_type_traits.h
CommitLineData
725dc051
BK
1// The -*- C++ -*- type traits classes for internal use in libstdc++
2
83ffe9cd 3// Copyright (C) 2000-2023 Free Software Foundation, Inc.
725dc051
BK
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
748086b7 8// Free Software Foundation; either version 3, or (at your option)
725dc051
BK
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
748086b7
JJ
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/>.
725dc051 24
f910786b 25/** @file bits/cpp_type_traits.h
729e3d3f 26 * This is an internal header file, included by other library headers.
f910786b 27 * Do not attempt to use it directly. @headername{ext/type_traits}
729e3d3f
PE
28 */
29
143c27b0
BK
30// Written by Gabriel Dos Reis <dosreis@cmla.ens-cachan.fr>
31
3d7c150e
BK
32#ifndef _CPP_TYPE_TRAITS_H
33#define _CPP_TYPE_TRAITS_H 1
725dc051 34
b0a85b86
GDR
35#pragma GCC system_header
36
c0736a9d
PC
37#include <bits/c++config.h>
38
725dc051
BK
39//
40// This file provides some compile-time information about various types.
ca6c4418 41// These representations were designed, on purpose, to be constant-expressions
5e91e92e 42// and not types as found in <bits/type_traits.h>. In particular, they
725dc051
BK
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?
ca6c4418
GDR
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
c124af93 51// information is -not- *that* convenient. One has to write lots of
725dc051
BK
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.
ca6c4418
GDR
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
725dc051
BK
57// keep these resource consumption as least as possible.
58//
ca6c4418
GDR
59// See valarray_array.h for a case use.
60//
725dc051
BK
61// -- Gaby (dosreis@cmla.ens-cachan.fr) 2000-03-06.
62//
c0736a9d
PC
63// Update 2005: types are also provided and <bits/type_traits.h> has been
64// removed.
65//
725dc051 66
ab56cbed
JW
67extern "C++" {
68
12ffa228
BK
69namespace std _GLIBCXX_VISIBILITY(default)
70{
71_GLIBCXX_BEGIN_NAMESPACE_VERSION
3cbc7af0 72
78a53887
BK
73 struct __true_type { };
74 struct __false_type { };
75
c0736a9d
PC
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
a9dd5a46
PC
84 // N.B. The conversions to bool are needed due to the issue
85 // explained in c++/19404.
c0736a9d
PC
86 template<class _Sp, class _Tp>
87 struct __traitor
88 {
a9dd5a46 89 enum { __value = bool(_Sp::__value) || bool(_Tp::__value) };
4d73fac9 90 typedef typename __truth_type<__value>::__type __type;
c0736a9d
PC
91 };
92
cdc958d8
GDR
93 // Compare for equality of types.
94 template<typename, typename>
95 struct __are_same
96 {
4d73fac9
PC
97 enum { __value = 0 };
98 typedef __false_type __type;
cdc958d8
GDR
99 };
100
101 template<typename _Tp>
102 struct __are_same<_Tp, _Tp>
103 {
4d73fac9
PC
104 enum { __value = 1 };
105 typedef __true_type __type;
cdc958d8
GDR
106 };
107
cdc958d8 108 // Holds if the template-argument is a void type.
725dc051 109 template<typename _Tp>
ca6c4418 110 struct __is_void
725dc051 111 {
4d73fac9 112 enum { __value = 0 };
c0736a9d 113 typedef __false_type __type;
725dc051 114 };
725dc051
BK
115
116 template<>
ca6c4418 117 struct __is_void<void>
725dc051 118 {
4d73fac9 119 enum { __value = 1 };
c0736a9d 120 typedef __true_type __type;
725dc051 121 };
725dc051
BK
122
123 //
124 // Integer types
125 //
126 template<typename _Tp>
127 struct __is_integer
128 {
4d73fac9 129 enum { __value = 0 };
c0736a9d 130 typedef __false_type __type;
725dc051
BK
131 };
132
133 // Thirteen specializations (yes there are eleven standard integer
2a60a9f6 134 // types; <em>long long</em> and <em>unsigned long long</em> are
78a7c317
DD
135 // supported as extensions). Up to four target-specific __int<N>
136 // types are supported as well.
725dc051
BK
137 template<>
138 struct __is_integer<bool>
139 {
4d73fac9 140 enum { __value = 1 };
c0736a9d 141 typedef __true_type __type;
725dc051 142 };
ed6814f7 143
725dc051
BK
144 template<>
145 struct __is_integer<char>
146 {
4d73fac9 147 enum { __value = 1 };
c0736a9d 148 typedef __true_type __type;
725dc051
BK
149 };
150
151 template<>
152 struct __is_integer<signed char>
153 {
4d73fac9 154 enum { __value = 1 };
c0736a9d 155 typedef __true_type __type;
725dc051 156 };
ed6814f7 157
725dc051 158 template<>
ff89096a 159 struct __is_integer<unsigned char>
725dc051 160 {
4d73fac9 161 enum { __value = 1 };
c0736a9d 162 typedef __true_type __type;
725dc051 163 };
725dc051 164
29e41848 165# ifdef __WCHAR_TYPE__
725dc051 166 template<>
ff89096a 167 struct __is_integer<wchar_t>
725dc051 168 {
4d73fac9 169 enum { __value = 1 };
c0736a9d 170 typedef __true_type __type;
725dc051 171 };
725dc051 172# endif
ed6814f7 173
c124af93
TH
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
734f5023 183#if __cplusplus >= 201103L
37f449aa
PC
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
725dc051 199 template<>
ff89096a 200 struct __is_integer<short>
725dc051 201 {
4d73fac9 202 enum { __value = 1 };
c0736a9d 203 typedef __true_type __type;
725dc051 204 };
725dc051
BK
205
206 template<>
ff89096a 207 struct __is_integer<unsigned short>
725dc051 208 {
4d73fac9 209 enum { __value = 1 };
c0736a9d 210 typedef __true_type __type;
725dc051 211 };
725dc051
BK
212
213 template<>
ff89096a 214 struct __is_integer<int>
725dc051 215 {
4d73fac9 216 enum { __value = 1 };
c0736a9d 217 typedef __true_type __type;
725dc051 218 };
725dc051
BK
219
220 template<>
ff89096a 221 struct __is_integer<unsigned int>
725dc051 222 {
4d73fac9 223 enum { __value = 1 };
c0736a9d 224 typedef __true_type __type;
725dc051 225 };
725dc051
BK
226
227 template<>
ff89096a 228 struct __is_integer<long>
725dc051 229 {
4d73fac9 230 enum { __value = 1 };
c0736a9d 231 typedef __true_type __type;
725dc051 232 };
725dc051
BK
233
234 template<>
ff89096a 235 struct __is_integer<unsigned long>
725dc051 236 {
4d73fac9 237 enum { __value = 1 };
c0736a9d 238 typedef __true_type __type;
725dc051 239 };
725dc051 240
725dc051 241 template<>
ff89096a 242 struct __is_integer<long long>
725dc051 243 {
4d73fac9 244 enum { __value = 1 };
c0736a9d 245 typedef __true_type __type;
725dc051 246 };
725dc051
BK
247
248 template<>
ff89096a 249 struct __is_integer<unsigned long long>
725dc051 250 {
4d73fac9 251 enum { __value = 1 };
c0736a9d 252 typedef __true_type __type;
725dc051 253 };
725dc051 254
78a7c317 255#define __INT_N(TYPE) \
42167831 256 __extension__ \
78a7c317
DD
257 template<> \
258 struct __is_integer<TYPE> \
259 { \
260 enum { __value = 1 }; \
261 typedef __true_type __type; \
262 }; \
42167831 263 __extension__ \
78a7c317
DD
264 template<> \
265 struct __is_integer<unsigned TYPE> \
266 { \
267 enum { __value = 1 }; \
268 typedef __true_type __type; \
269 };
270
271#ifdef __GLIBCXX_TYPE_INT_N_0
272__INT_N(__GLIBCXX_TYPE_INT_N_0)
273#endif
274#ifdef __GLIBCXX_TYPE_INT_N_1
275__INT_N(__GLIBCXX_TYPE_INT_N_1)
276#endif
277#ifdef __GLIBCXX_TYPE_INT_N_2
278__INT_N(__GLIBCXX_TYPE_INT_N_2)
279#endif
280#ifdef __GLIBCXX_TYPE_INT_N_3
281__INT_N(__GLIBCXX_TYPE_INT_N_3)
282#endif
283
284#undef __INT_N
285
725dc051
BK
286 //
287 // Floating point types
288 //
289 template<typename _Tp>
ff89096a 290 struct __is_floating
725dc051 291 {
4d73fac9 292 enum { __value = 0 };
c0736a9d 293 typedef __false_type __type;
725dc051 294 };
725dc051
BK
295
296 // three specializations (float, double and 'long double')
297 template<>
ff89096a 298 struct __is_floating<float>
725dc051 299 {
4d73fac9 300 enum { __value = 1 };
c0736a9d 301 typedef __true_type __type;
725dc051 302 };
725dc051
BK
303
304 template<>
ff89096a 305 struct __is_floating<double>
725dc051 306 {
4d73fac9 307 enum { __value = 1 };
c0736a9d 308 typedef __true_type __type;
725dc051 309 };
725dc051
BK
310
311 template<>
ff89096a 312 struct __is_floating<long double>
725dc051 313 {
4d73fac9 314 enum { __value = 1 };
c0736a9d 315 typedef __true_type __type;
725dc051 316 };
725dc051 317
db55f1dd
JJ
318#ifdef __STDCPP_FLOAT16_T__
319 template<>
320 struct __is_floating<_Float16>
321 {
322 enum { __value = 1 };
323 typedef __true_type __type;
324 };
325#endif
326
327#ifdef __STDCPP_FLOAT32_T__
328 template<>
329 struct __is_floating<_Float32>
330 {
331 enum { __value = 1 };
332 typedef __true_type __type;
333 };
334#endif
335
336#ifdef __STDCPP_FLOAT64_T__
337 template<>
338 struct __is_floating<_Float64>
339 {
340 enum { __value = 1 };
341 typedef __true_type __type;
342 };
343#endif
344
345#ifdef __STDCPP_FLOAT128_T__
346 template<>
347 struct __is_floating<_Float128>
348 {
349 enum { __value = 1 };
350 typedef __true_type __type;
351 };
352#endif
353
354#ifdef __STDCPP_BFLOAT16_T__
355 template<>
356 struct __is_floating<__gnu_cxx::__bfloat16_t>
357 {
358 enum { __value = 1 };
359 typedef __true_type __type;
360 };
361#endif
362
badd64ad
PC
363 //
364 // Pointer types
365 //
366 template<typename _Tp>
367 struct __is_pointer
368 {
4d73fac9 369 enum { __value = 0 };
c0736a9d 370 typedef __false_type __type;
badd64ad
PC
371 };
372
373 template<typename _Tp>
374 struct __is_pointer<_Tp*>
375 {
4d73fac9 376 enum { __value = 1 };
c0736a9d 377 typedef __true_type __type;
5e91e92e
PC
378 };
379
725dc051
BK
380 //
381 // An arithmetic type is an integer type or a floating point type
382 //
383 template<typename _Tp>
ff89096a 384 struct __is_arithmetic
c0736a9d
PC
385 : public __traitor<__is_integer<_Tp>, __is_floating<_Tp> >
386 { };
387
badd64ad 388 //
67dd4a93 389 // A scalar type is an arithmetic type or a pointer type
badd64ad
PC
390 //
391 template<typename _Tp>
67dd4a93 392 struct __is_scalar
c0736a9d
PC
393 : public __traitor<__is_arithmetic<_Tp>, __is_pointer<_Tp> >
394 { };
badd64ad 395
0002d5d2
PC
396 //
397 // For use in std::copy and std::find overloads for streambuf iterators.
398 //
399 template<typename _Tp>
400 struct __is_char
401 {
402 enum { __value = 0 };
403 typedef __false_type __type;
404 };
405
406 template<>
407 struct __is_char<char>
408 {
409 enum { __value = 1 };
410 typedef __true_type __type;
411 };
412
29e41848 413#ifdef __WCHAR_TYPE__
0002d5d2
PC
414 template<>
415 struct __is_char<wchar_t>
416 {
417 enum { __value = 1 };
418 typedef __true_type __type;
419 };
420#endif
421
394033f8
PC
422 template<typename _Tp>
423 struct __is_byte
424 {
425 enum { __value = 0 };
426 typedef __false_type __type;
427 };
428
429 template<>
430 struct __is_byte<char>
431 {
432 enum { __value = 1 };
433 typedef __true_type __type;
434 };
435
436 template<>
437 struct __is_byte<signed char>
438 {
439 enum { __value = 1 };
440 typedef __true_type __type;
441 };
442
443 template<>
444 struct __is_byte<unsigned char>
445 {
446 enum { __value = 1 };
447 typedef __true_type __type;
448 };
449
cd7ec27c
JW
450#if __cplusplus >= 201703L
451 enum class byte : unsigned char;
452
453 template<>
454 struct __is_byte<byte>
455 {
456 enum { __value = 1 };
457 typedef __true_type __type;
458 };
459#endif // C++17
460
3a4cc628
JW
461#ifdef _GLIBCXX_USE_CHAR8_T
462 template<>
463 struct __is_byte<char8_t>
464 {
465 enum { __value = 1 };
466 typedef __true_type __type;
467 };
468#endif
469
462f6c20
JW
470 template<typename> struct iterator_traits;
471
472 // A type that is safe for use with memcpy, memmove, memcmp etc.
473 template<typename _Tp>
474 struct __is_nonvolatile_trivially_copyable
475 {
476 enum { __value = __is_trivially_copyable(_Tp) };
477 };
478
94f7d7ec
JW
479 // Cannot use memcpy/memmove/memcmp on volatile types even if they are
480 // trivially copyable, so ensure __memcpyable<volatile int*, volatile int*>
481 // and similar will be false.
462f6c20
JW
482 template<typename _Tp>
483 struct __is_nonvolatile_trivially_copyable<volatile _Tp>
484 {
485 enum { __value = 0 };
486 };
487
488 // Whether two iterator types can be used with memcpy/memmove.
489 template<typename _OutputIter, typename _InputIter>
490 struct __memcpyable
491 {
492 enum { __value = 0 };
493 };
494
495 template<typename _Tp>
496 struct __memcpyable<_Tp*, _Tp*>
497 : __is_nonvolatile_trivially_copyable<_Tp>
498 { };
499
500 template<typename _Tp>
501 struct __memcpyable<_Tp*, const _Tp*>
502 : __is_nonvolatile_trivially_copyable<_Tp>
503 { };
504
505 // Whether two iterator types can be used with memcmp.
94f7d7ec
JW
506 // This trait only says it's well-formed to use memcmp, not that it
507 // gives the right answer for a given algorithm. So for example, std::equal
508 // needs to add additional checks that the types are integers or pointers,
509 // because other trivially copyable types can overload operator==.
462f6c20
JW
510 template<typename _Iter1, typename _Iter2>
511 struct __memcmpable
512 {
513 enum { __value = 0 };
514 };
515
516 // OK to use memcmp with pointers to trivially copyable types.
517 template<typename _Tp>
518 struct __memcmpable<_Tp*, _Tp*>
519 : __is_nonvolatile_trivially_copyable<_Tp>
520 { };
521
522 template<typename _Tp>
523 struct __memcmpable<const _Tp*, _Tp*>
524 : __is_nonvolatile_trivially_copyable<_Tp>
525 { };
526
527 template<typename _Tp>
528 struct __memcmpable<_Tp*, const _Tp*>
529 : __is_nonvolatile_trivially_copyable<_Tp>
530 { };
531
2f983fa6
JW
532 // Whether memcmp can be used to determine ordering for a type
533 // e.g. in std::lexicographical_compare or three-way comparisons.
534 // True for unsigned integer-like types where comparing each byte in turn
535 // as an unsigned char yields the right result. This is true for all
536 // unsigned integers on big endian targets, but only unsigned narrow
537 // character types (and std::byte) on little endian targets.
538 template<typename _Tp, bool _TreatAsBytes =
539#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
540 __is_integer<_Tp>::__value
541#else
542 __is_byte<_Tp>::__value
543#endif
544 >
545 struct __is_memcmp_ordered
546 {
547 static const bool __value = _Tp(-1) > _Tp(1); // is unsigned
548 };
549
550 template<typename _Tp>
551 struct __is_memcmp_ordered<_Tp, false>
552 {
553 static const bool __value = false;
554 };
555
556 // Whether two types can be compared using memcmp.
557 template<typename _Tp, typename _Up, bool = sizeof(_Tp) == sizeof(_Up)>
558 struct __is_memcmp_ordered_with
559 {
560 static const bool __value = __is_memcmp_ordered<_Tp>::__value
561 && __is_memcmp_ordered<_Up>::__value;
562 };
563
564 template<typename _Tp, typename _Up>
565 struct __is_memcmp_ordered_with<_Tp, _Up, false>
566 {
567 static const bool __value = false;
568 };
569
570#if __cplusplus >= 201703L
571#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
572 // std::byte is not an integer, but it can be compared using memcmp.
573 template<>
574 struct __is_memcmp_ordered<std::byte, false>
575 { static constexpr bool __value = true; };
576#endif
577
578 // std::byte can only be compared to itself, not to other types.
579 template<>
580 struct __is_memcmp_ordered_with<std::byte, std::byte, true>
581 { static constexpr bool __value = true; };
582
583 template<typename _Tp, bool _SameSize>
584 struct __is_memcmp_ordered_with<_Tp, std::byte, _SameSize>
585 { static constexpr bool __value = false; };
586
587 template<typename _Up, bool _SameSize>
588 struct __is_memcmp_ordered_with<std::byte, _Up, _SameSize>
589 { static constexpr bool __value = false; };
590#endif
591
f0112db9
PC
592 //
593 // Move iterator type
594 //
595 template<typename _Tp>
596 struct __is_move_iterator
597 {
598 enum { __value = 0 };
599 typedef __false_type __type;
600 };
601
5bc1c07c
FD
602 // Fallback implementation of the function in bits/stl_iterator.h used to
603 // remove the move_iterator wrapper.
604 template<typename _Iterator>
3a66e68a 605 _GLIBCXX20_CONSTEXPR
5bc1c07c
FD
606 inline _Iterator
607 __miter_base(_Iterator __it)
608 { return __it; }
609
12ffa228
BK
610_GLIBCXX_END_NAMESPACE_VERSION
611} // namespace
ab56cbed 612} // extern "C++"
725dc051 613
3d7c150e 614#endif //_CPP_TYPE_TRAITS_H