1 // The -*- C++ -*- type traits classes for internal use in libstdc++
3 // Copyright (C) 2000-2024 Free Software Foundation, Inc.
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)
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
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
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
69 namespace std
_GLIBCXX_VISIBILITY(default)
71 _GLIBCXX_BEGIN_NAMESPACE_VERSION
73 struct __true_type
{ };
74 struct __false_type
{ };
78 { typedef __false_type __type
; };
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
>
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
>
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
>
112 enum { __value
= 0 };
113 typedef __false_type __type
;
117 struct __is_void
<void>
119 enum { __value
= 1 };
120 typedef __true_type __type
;
126 template<typename _Tp
>
129 enum { __value
= 0 };
130 typedef __false_type __type
;
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.
138 struct __is_integer
<bool>
140 enum { __value
= 1 };
141 typedef __true_type __type
;
145 struct __is_integer
<char>
147 enum { __value
= 1 };
148 typedef __true_type __type
;
152 struct __is_integer
<signed char>
154 enum { __value
= 1 };
155 typedef __true_type __type
;
159 struct __is_integer
<unsigned char>
161 enum { __value
= 1 };
162 typedef __true_type __type
;
165 # ifdef __WCHAR_TYPE__
167 struct __is_integer
<wchar_t>
169 enum { __value
= 1 };
170 typedef __true_type __type
;
174 #ifdef _GLIBCXX_USE_CHAR8_T
176 struct __is_integer
<char8_t
>
178 enum { __value
= 1 };
179 typedef __true_type __type
;
183 #if __cplusplus >= 201103L
185 struct __is_integer
<char16_t
>
187 enum { __value
= 1 };
188 typedef __true_type __type
;
192 struct __is_integer
<char32_t
>
194 enum { __value
= 1 };
195 typedef __true_type __type
;
200 struct __is_integer
<short>
202 enum { __value
= 1 };
203 typedef __true_type __type
;
207 struct __is_integer
<unsigned short>
209 enum { __value
= 1 };
210 typedef __true_type __type
;
214 struct __is_integer
<int>
216 enum { __value
= 1 };
217 typedef __true_type __type
;
221 struct __is_integer
<unsigned int>
223 enum { __value
= 1 };
224 typedef __true_type __type
;
228 struct __is_integer
<long>
230 enum { __value
= 1 };
231 typedef __true_type __type
;
235 struct __is_integer
<unsigned long>
237 enum { __value
= 1 };
238 typedef __true_type __type
;
242 struct __is_integer
<long long>
244 enum { __value
= 1 };
245 typedef __true_type __type
;
249 struct __is_integer
<unsigned long long>
251 enum { __value
= 1 };
252 typedef __true_type __type
;
255 #define __INT_N(TYPE) \
258 struct __is_integer<TYPE> \
260 enum { __value = 1 }; \
261 typedef __true_type __type; \
265 struct __is_integer<unsigned TYPE> \
267 enum { __value = 1 }; \
268 typedef __true_type __type; \
271 #ifdef __GLIBCXX_TYPE_INT_N_0
272 __INT_N(__GLIBCXX_TYPE_INT_N_0
)
274 #ifdef __GLIBCXX_TYPE_INT_N_1
275 __INT_N(__GLIBCXX_TYPE_INT_N_1
)
277 #ifdef __GLIBCXX_TYPE_INT_N_2
278 __INT_N(__GLIBCXX_TYPE_INT_N_2
)
280 #ifdef __GLIBCXX_TYPE_INT_N_3
281 __INT_N(__GLIBCXX_TYPE_INT_N_3
)
287 // Floating point types
289 template<typename _Tp
>
292 enum { __value
= 0 };
293 typedef __false_type __type
;
296 // three specializations (float, double and 'long double')
298 struct __is_floating
<float>
300 enum { __value
= 1 };
301 typedef __true_type __type
;
305 struct __is_floating
<double>
307 enum { __value
= 1 };
308 typedef __true_type __type
;
312 struct __is_floating
<long double>
314 enum { __value
= 1 };
315 typedef __true_type __type
;
318 #ifdef __STDCPP_FLOAT16_T__
320 struct __is_floating
<_Float16
>
322 enum { __value
= 1 };
323 typedef __true_type __type
;
327 #ifdef __STDCPP_FLOAT32_T__
329 struct __is_floating
<_Float32
>
331 enum { __value
= 1 };
332 typedef __true_type __type
;
336 #ifdef __STDCPP_FLOAT64_T__
338 struct __is_floating
<_Float64
>
340 enum { __value
= 1 };
341 typedef __true_type __type
;
345 #ifdef __STDCPP_FLOAT128_T__
347 struct __is_floating
<_Float128
>
349 enum { __value
= 1 };
350 typedef __true_type __type
;
354 #ifdef __STDCPP_BFLOAT16_T__
356 struct __is_floating
<__gnu_cxx::__bfloat16_t
>
358 enum { __value
= 1 };
359 typedef __true_type __type
;
366 template<typename _Tp
>
369 enum { __value
= 0 };
370 typedef __false_type __type
;
373 template<typename _Tp
>
374 struct __is_pointer
<_Tp
*>
376 enum { __value
= 1 };
377 typedef __true_type __type
;
381 // An arithmetic type is an integer type or a floating point type
383 template<typename _Tp
>
384 struct __is_arithmetic
385 : public __traitor
<__is_integer
<_Tp
>, __is_floating
<_Tp
> >
389 // A scalar type is an arithmetic type or a pointer type
391 template<typename _Tp
>
393 : public __traitor
<__is_arithmetic
<_Tp
>, __is_pointer
<_Tp
> >
397 // For use in std::copy and std::find overloads for streambuf iterators.
399 template<typename _Tp
>
402 enum { __value
= 0 };
403 typedef __false_type __type
;
407 struct __is_char
<char>
409 enum { __value
= 1 };
410 typedef __true_type __type
;
413 #ifdef __WCHAR_TYPE__
415 struct __is_char
<wchar_t>
417 enum { __value
= 1 };
418 typedef __true_type __type
;
422 template<typename _Tp
>
425 enum { __value
= 0 };
426 typedef __false_type __type
;
430 struct __is_byte
<char>
432 enum { __value
= 1 };
433 typedef __true_type __type
;
437 struct __is_byte
<signed char>
439 enum { __value
= 1 };
440 typedef __true_type __type
;
444 struct __is_byte
<unsigned char>
446 enum { __value
= 1 };
447 typedef __true_type __type
;
450 #if __cplusplus >= 201703L
451 enum class byte
: unsigned char;
454 struct __is_byte
<byte
>
456 enum { __value
= 1 };
457 typedef __true_type __type
;
461 #ifdef _GLIBCXX_USE_CHAR8_T
463 struct __is_byte
<char8_t
>
465 enum { __value
= 1 };
466 typedef __true_type __type
;
470 template<typename
> struct iterator_traits
;
472 // A type that is safe for use with memcpy, memmove, memcmp etc.
473 template<typename _Tp
>
474 struct __is_nonvolatile_trivially_copyable
476 enum { __value
= __is_trivially_copyable(_Tp
) };
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.
482 template<typename _Tp
>
483 struct __is_nonvolatile_trivially_copyable
<volatile _Tp
>
485 enum { __value
= 0 };
488 // Whether two iterator types can be used with memcpy/memmove.
489 template<typename _OutputIter
, typename _InputIter
>
492 enum { __value
= 0 };
495 template<typename _Tp
>
496 struct __memcpyable
<_Tp
*, _Tp
*>
497 : __is_nonvolatile_trivially_copyable
<_Tp
>
500 template<typename _Tp
>
501 struct __memcpyable
<_Tp
*, const _Tp
*>
502 : __is_nonvolatile_trivially_copyable
<_Tp
>
505 // Whether two iterator types can be used with memcmp.
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==.
510 template<typename _Iter1
, typename _Iter2
>
513 enum { __value
= 0 };
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
>
522 template<typename _Tp
>
523 struct __memcmpable
<const _Tp
*, _Tp
*>
524 : __is_nonvolatile_trivially_copyable
<_Tp
>
527 template<typename _Tp
>
528 struct __memcmpable
<_Tp
*, const _Tp
*>
529 : __is_nonvolatile_trivially_copyable
<_Tp
>
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
542 __is_byte
<_Tp
>::__value
545 struct __is_memcmp_ordered
547 static const bool __value
= _Tp(-1) > _Tp(1); // is unsigned
550 template<typename _Tp
>
551 struct __is_memcmp_ordered
<_Tp
, false>
553 static const bool __value
= false;
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
560 static const bool __value
= __is_memcmp_ordered
<_Tp
>::__value
561 && __is_memcmp_ordered
<_Up
>::__value
;
564 template<typename _Tp
, typename _Up
>
565 struct __is_memcmp_ordered_with
<_Tp
, _Up
, false>
567 static const bool __value
= false;
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.
574 struct __is_memcmp_ordered
<std::byte
, false>
575 { static constexpr bool __value
= true; };
578 // std::byte can only be compared to itself, not to other types.
580 struct __is_memcmp_ordered_with
<std::byte
, std::byte
, true>
581 { static constexpr bool __value
= true; };
583 template<typename _Tp
, bool _SameSize
>
584 struct __is_memcmp_ordered_with
<_Tp
, std::byte
, _SameSize
>
585 { static constexpr bool __value
= false; };
587 template<typename _Up
, bool _SameSize
>
588 struct __is_memcmp_ordered_with
<std::byte
, _Up
, _SameSize
>
589 { static constexpr bool __value
= false; };
593 // Move iterator type
595 template<typename _Tp
>
596 struct __is_move_iterator
598 enum { __value
= 0 };
599 typedef __false_type __type
;
602 // Fallback implementation of the function in bits/stl_iterator.h used to
603 // remove the move_iterator wrapper.
604 template<typename _Iterator
>
607 __miter_base(_Iterator __it
)
610 _GLIBCXX_END_NAMESPACE_VERSION
614 #endif //_CPP_TYPE_TRAITS_H