i386: Allow all register_operand SUBREGs in x86_ternlog_idx.
[official-gcc.git] / libstdc++-v3 / include / bits / cpp_type_traits.h
blob6834dee5557074020397119e3f9b04e315009c73
1 // The -*- C++ -*- type traits classes for internal use in libstdc++
3 // Copyright (C) 2000-2024 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.
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.
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.
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/>.
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}
30 // Written by Gabriel Dos Reis <dosreis@cmla.ens-cachan.fr>
32 #ifndef _CPP_TYPE_TRAITS_H
33 #define _CPP_TYPE_TRAITS_H 1
35 #pragma GCC system_header
37 #include <bits/c++config.h>
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.
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.
59 // See valarray_array.h for a case use.
61 // -- Gaby (dosreis@cmla.ens-cachan.fr) 2000-03-06.
63 // Update 2005: types are also provided and <bits/type_traits.h> has been
64 // removed.
67 extern "C++" {
69 namespace std _GLIBCXX_VISIBILITY(default)
71 _GLIBCXX_BEGIN_NAMESPACE_VERSION
73 struct __true_type { };
74 struct __false_type { };
76 template<bool>
77 struct __truth_type
78 { typedef __false_type __type; };
80 template<>
81 struct __truth_type<true>
82 { typedef __true_type __type; };
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
89 enum { __value = bool(_Sp::__value) || bool(_Tp::__value) };
90 typedef typename __truth_type<__value>::__type __type;
93 // Compare for equality of types.
94 template<typename, typename>
95 struct __are_same
97 enum { __value = 0 };
98 typedef __false_type __type;
101 template<typename _Tp>
102 struct __are_same<_Tp, _Tp>
104 enum { __value = 1 };
105 typedef __true_type __type;
108 // Holds if the template-argument is a void type.
109 template<typename _Tp>
110 struct __is_void
112 enum { __value = 0 };
113 typedef __false_type __type;
116 template<>
117 struct __is_void<void>
119 enum { __value = 1 };
120 typedef __true_type __type;
124 // Integer types
126 template<typename _Tp>
127 struct __is_integer
129 enum { __value = 0 };
130 typedef __false_type __type;
133 // Explicit specializations for the standard integer types.
134 // Up to four target-specific __int<N> types are supported as well.
135 template<>
136 struct __is_integer<bool>
138 enum { __value = 1 };
139 typedef __true_type __type;
142 template<>
143 struct __is_integer<char>
145 enum { __value = 1 };
146 typedef __true_type __type;
149 template<>
150 struct __is_integer<signed char>
152 enum { __value = 1 };
153 typedef __true_type __type;
156 template<>
157 struct __is_integer<unsigned char>
159 enum { __value = 1 };
160 typedef __true_type __type;
163 # ifdef __WCHAR_TYPE__
164 template<>
165 struct __is_integer<wchar_t>
167 enum { __value = 1 };
168 typedef __true_type __type;
170 # endif
172 #ifdef _GLIBCXX_USE_CHAR8_T
173 template<>
174 struct __is_integer<char8_t>
176 enum { __value = 1 };
177 typedef __true_type __type;
179 #endif
181 #if __cplusplus >= 201103L
182 template<>
183 struct __is_integer<char16_t>
185 enum { __value = 1 };
186 typedef __true_type __type;
189 template<>
190 struct __is_integer<char32_t>
192 enum { __value = 1 };
193 typedef __true_type __type;
195 #endif
197 template<>
198 struct __is_integer<short>
200 enum { __value = 1 };
201 typedef __true_type __type;
204 template<>
205 struct __is_integer<unsigned short>
207 enum { __value = 1 };
208 typedef __true_type __type;
211 template<>
212 struct __is_integer<int>
214 enum { __value = 1 };
215 typedef __true_type __type;
218 template<>
219 struct __is_integer<unsigned int>
221 enum { __value = 1 };
222 typedef __true_type __type;
225 template<>
226 struct __is_integer<long>
228 enum { __value = 1 };
229 typedef __true_type __type;
232 template<>
233 struct __is_integer<unsigned long>
235 enum { __value = 1 };
236 typedef __true_type __type;
239 template<>
240 struct __is_integer<long long>
242 enum { __value = 1 };
243 typedef __true_type __type;
246 template<>
247 struct __is_integer<unsigned long long>
249 enum { __value = 1 };
250 typedef __true_type __type;
253 #define __INT_N(TYPE) \
254 __extension__ \
255 template<> \
256 struct __is_integer<TYPE> \
258 enum { __value = 1 }; \
259 typedef __true_type __type; \
260 }; \
261 __extension__ \
262 template<> \
263 struct __is_integer<unsigned TYPE> \
265 enum { __value = 1 }; \
266 typedef __true_type __type; \
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
282 #undef __INT_N
285 // Floating point types
287 template<typename _Tp>
288 struct __is_floating
290 enum { __value = 0 };
291 typedef __false_type __type;
294 // three specializations (float, double and 'long double')
295 template<>
296 struct __is_floating<float>
298 enum { __value = 1 };
299 typedef __true_type __type;
302 template<>
303 struct __is_floating<double>
305 enum { __value = 1 };
306 typedef __true_type __type;
309 template<>
310 struct __is_floating<long double>
312 enum { __value = 1 };
313 typedef __true_type __type;
316 #ifdef __STDCPP_FLOAT16_T__
317 template<>
318 struct __is_floating<_Float16>
320 enum { __value = 1 };
321 typedef __true_type __type;
323 #endif
325 #ifdef __STDCPP_FLOAT32_T__
326 template<>
327 struct __is_floating<_Float32>
329 enum { __value = 1 };
330 typedef __true_type __type;
332 #endif
334 #ifdef __STDCPP_FLOAT64_T__
335 template<>
336 struct __is_floating<_Float64>
338 enum { __value = 1 };
339 typedef __true_type __type;
341 #endif
343 #ifdef __STDCPP_FLOAT128_T__
344 template<>
345 struct __is_floating<_Float128>
347 enum { __value = 1 };
348 typedef __true_type __type;
350 #endif
352 #ifdef __STDCPP_BFLOAT16_T__
353 template<>
354 struct __is_floating<__gnu_cxx::__bfloat16_t>
356 enum { __value = 1 };
357 typedef __true_type __type;
359 #endif
362 // Pointer types
364 #if _GLIBCXX_USE_BUILTIN_TRAIT(__is_pointer)
365 template<typename _Tp, bool _IsPtr = __is_pointer(_Tp)>
366 struct __is_pointer : __truth_type<_IsPtr>
368 enum { __value = _IsPtr };
370 #else
371 template<typename _Tp>
372 struct __is_pointer
374 enum { __value = 0 };
375 typedef __false_type __type;
378 template<typename _Tp>
379 struct __is_pointer<_Tp*>
381 enum { __value = 1 };
382 typedef __true_type __type;
384 #endif
387 // An arithmetic type is an integer type or a floating point type
389 template<typename _Tp>
390 struct __is_arithmetic
391 : public __traitor<__is_integer<_Tp>, __is_floating<_Tp> >
392 { };
395 // A scalar type is an arithmetic type or a pointer type
397 template<typename _Tp>
398 struct __is_scalar
399 : public __traitor<__is_arithmetic<_Tp>, __is_pointer<_Tp> >
400 { };
403 // For use in std::copy and std::find overloads for streambuf iterators.
405 template<typename _Tp>
406 struct __is_char
408 enum { __value = 0 };
409 typedef __false_type __type;
412 template<>
413 struct __is_char<char>
415 enum { __value = 1 };
416 typedef __true_type __type;
419 #ifdef __WCHAR_TYPE__
420 template<>
421 struct __is_char<wchar_t>
423 enum { __value = 1 };
424 typedef __true_type __type;
426 #endif
428 template<typename _Tp>
429 struct __is_byte
431 enum { __value = 0 };
432 typedef __false_type __type;
435 template<>
436 struct __is_byte<char>
438 enum { __value = 1 };
439 typedef __true_type __type;
442 template<>
443 struct __is_byte<signed char>
445 enum { __value = 1 };
446 typedef __true_type __type;
449 template<>
450 struct __is_byte<unsigned char>
452 enum { __value = 1 };
453 typedef __true_type __type;
456 #if __cplusplus >= 201703L
457 enum class byte : unsigned char;
459 template<>
460 struct __is_byte<byte>
462 enum { __value = 1 };
463 typedef __true_type __type;
465 #endif // C++17
467 #ifdef _GLIBCXX_USE_CHAR8_T
468 template<>
469 struct __is_byte<char8_t>
471 enum { __value = 1 };
472 typedef __true_type __type;
474 #endif
476 template<typename> struct iterator_traits;
478 // A type that is safe for use with memcpy, memmove, memcmp etc.
479 template<typename _Tp>
480 struct __is_nonvolatile_trivially_copyable
482 enum { __value = __is_trivially_copyable(_Tp) };
485 // Cannot use memcpy/memmove/memcmp on volatile types even if they are
486 // trivially copyable, so ensure __memcpyable<volatile int*, volatile int*>
487 // and similar will be false.
488 template<typename _Tp>
489 struct __is_nonvolatile_trivially_copyable<volatile _Tp>
491 enum { __value = 0 };
494 // Whether two iterator types can be used with memcpy/memmove.
495 template<typename _OutputIter, typename _InputIter>
496 struct __memcpyable
498 enum { __value = 0 };
501 template<typename _Tp>
502 struct __memcpyable<_Tp*, _Tp*>
503 : __is_nonvolatile_trivially_copyable<_Tp>
504 { };
506 template<typename _Tp>
507 struct __memcpyable<_Tp*, const _Tp*>
508 : __is_nonvolatile_trivially_copyable<_Tp>
509 { };
511 // Whether two iterator types can be used with memcmp.
512 // This trait only says it's well-formed to use memcmp, not that it
513 // gives the right answer for a given algorithm. So for example, std::equal
514 // needs to add additional checks that the types are integers or pointers,
515 // because other trivially copyable types can overload operator==.
516 template<typename _Iter1, typename _Iter2>
517 struct __memcmpable
519 enum { __value = 0 };
522 // OK to use memcmp with pointers to trivially copyable types.
523 template<typename _Tp>
524 struct __memcmpable<_Tp*, _Tp*>
525 : __is_nonvolatile_trivially_copyable<_Tp>
526 { };
528 template<typename _Tp>
529 struct __memcmpable<const _Tp*, _Tp*>
530 : __is_nonvolatile_trivially_copyable<_Tp>
531 { };
533 template<typename _Tp>
534 struct __memcmpable<_Tp*, const _Tp*>
535 : __is_nonvolatile_trivially_copyable<_Tp>
536 { };
538 // Whether memcmp can be used to determine ordering for a type
539 // e.g. in std::lexicographical_compare or three-way comparisons.
540 // True for unsigned integer-like types where comparing each byte in turn
541 // as an unsigned char yields the right result. This is true for all
542 // unsigned integers on big endian targets, but only unsigned narrow
543 // character types (and std::byte) on little endian targets.
544 template<typename _Tp, bool _TreatAsBytes =
545 #if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
546 __is_integer<_Tp>::__value
547 #else
548 __is_byte<_Tp>::__value
549 #endif
551 struct __is_memcmp_ordered
553 static const bool __value = _Tp(-1) > _Tp(1); // is unsigned
556 template<typename _Tp>
557 struct __is_memcmp_ordered<_Tp, false>
559 static const bool __value = false;
562 // Whether two types can be compared using memcmp.
563 template<typename _Tp, typename _Up, bool = sizeof(_Tp) == sizeof(_Up)>
564 struct __is_memcmp_ordered_with
566 static const bool __value = __is_memcmp_ordered<_Tp>::__value
567 && __is_memcmp_ordered<_Up>::__value;
570 template<typename _Tp, typename _Up>
571 struct __is_memcmp_ordered_with<_Tp, _Up, false>
573 static const bool __value = false;
576 #if __cplusplus >= 201703L
577 #if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
578 // std::byte is not an integer, but it can be compared using memcmp.
579 template<>
580 struct __is_memcmp_ordered<std::byte, false>
581 { static constexpr bool __value = true; };
582 #endif
584 // std::byte can only be compared to itself, not to other types.
585 template<>
586 struct __is_memcmp_ordered_with<std::byte, std::byte, true>
587 { static constexpr bool __value = true; };
589 template<typename _Tp, bool _SameSize>
590 struct __is_memcmp_ordered_with<_Tp, std::byte, _SameSize>
591 { static constexpr bool __value = false; };
593 template<typename _Up, bool _SameSize>
594 struct __is_memcmp_ordered_with<std::byte, _Up, _SameSize>
595 { static constexpr bool __value = false; };
596 #endif
599 // Move iterator type
601 template<typename _Tp>
602 struct __is_move_iterator
604 enum { __value = 0 };
605 typedef __false_type __type;
608 // Fallback implementation of the function in bits/stl_iterator.h used to
609 // remove the move_iterator wrapper.
610 template<typename _Iterator>
611 _GLIBCXX20_CONSTEXPR
612 inline _Iterator
613 __miter_base(_Iterator __it)
614 { return __it; }
616 _GLIBCXX_END_NAMESPACE_VERSION
617 } // namespace
618 } // extern "C++"
620 #endif //_CPP_TYPE_TRAITS_H