]> git.ipfire.org Git - thirdparty/gcc.git/blob - libstdc++-v3/include/ext/type_traits.h
aarch64: Add codegen support for AdvSIMD faminmax
[thirdparty/gcc.git] / libstdc++-v3 / include / ext / type_traits.h
1 // -*- C++ -*-
2
3 // Copyright (C) 2005-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 terms
7 // of the GNU General Public License as published by the Free Software
8 // Foundation; either version 3, or (at your option) any later
9 // version.
10
11 // This library is distributed in the hope that it will be useful, but
12 // WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 // 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 ext/type_traits.h
26 * This file is a GNU extension to the Standard C++ Library.
27 */
28
29 #ifndef _EXT_TYPE_TRAITS
30 #define _EXT_TYPE_TRAITS 1
31
32 #pragma GCC system_header
33
34 #include <bits/c++config.h>
35 #include <bits/cpp_type_traits.h>
36
37 #pragma GCC diagnostic push
38 #pragma GCC diagnostic ignored "-Wlong-long"
39
40 extern "C++" {
41
42 namespace __gnu_cxx _GLIBCXX_VISIBILITY(default)
43 {
44 _GLIBCXX_BEGIN_NAMESPACE_VERSION
45
46 // Define a nested type if some predicate holds.
47 template<bool, typename>
48 struct __enable_if
49 { };
50
51 template<typename _Tp>
52 struct __enable_if<true, _Tp>
53 { typedef _Tp __type; };
54
55
56 // Conditional expression for types. If true, first, if false, second.
57 template<bool _Cond, typename _Iftrue, typename _Iffalse>
58 struct __conditional_type
59 { typedef _Iftrue __type; };
60
61 template<typename _Iftrue, typename _Iffalse>
62 struct __conditional_type<false, _Iftrue, _Iffalse>
63 { typedef _Iffalse __type; };
64
65
66 // Given an integral builtin type, return the corresponding unsigned type.
67 template<typename _Tp>
68 struct __add_unsigned
69 {
70 private:
71 typedef __enable_if<std::__is_integer<_Tp>::__value, _Tp> __if_type;
72
73 public:
74 typedef typename __if_type::__type __type;
75 };
76
77 template<>
78 struct __add_unsigned<char>
79 { typedef unsigned char __type; };
80
81 template<>
82 struct __add_unsigned<signed char>
83 { typedef unsigned char __type; };
84
85 template<>
86 struct __add_unsigned<short>
87 { typedef unsigned short __type; };
88
89 template<>
90 struct __add_unsigned<int>
91 { typedef unsigned int __type; };
92
93 template<>
94 struct __add_unsigned<long>
95 { typedef unsigned long __type; };
96
97 template<>
98 struct __add_unsigned<long long>
99 { typedef unsigned long long __type; };
100
101 // Declare but don't define.
102 template<>
103 struct __add_unsigned<bool>;
104
105 template<>
106 struct __add_unsigned<wchar_t>;
107
108
109 // Given an integral builtin type, return the corresponding signed type.
110 template<typename _Tp>
111 struct __remove_unsigned
112 {
113 private:
114 typedef __enable_if<std::__is_integer<_Tp>::__value, _Tp> __if_type;
115
116 public:
117 typedef typename __if_type::__type __type;
118 };
119
120 template<>
121 struct __remove_unsigned<char>
122 { typedef signed char __type; };
123
124 template<>
125 struct __remove_unsigned<unsigned char>
126 { typedef signed char __type; };
127
128 template<>
129 struct __remove_unsigned<unsigned short>
130 { typedef short __type; };
131
132 template<>
133 struct __remove_unsigned<unsigned int>
134 { typedef int __type; };
135
136 template<>
137 struct __remove_unsigned<unsigned long>
138 { typedef long __type; };
139
140 template<>
141 struct __remove_unsigned<unsigned long long>
142 { typedef long long __type; };
143
144 // Declare but don't define.
145 template<>
146 struct __remove_unsigned<bool>;
147
148 template<>
149 struct __remove_unsigned<wchar_t>;
150
151
152 // For use in string and vstring.
153 template<typename _Type>
154 _GLIBCXX_CONSTEXPR
155 inline bool
156 __is_null_pointer(_Type* __ptr)
157 { return __ptr == 0; }
158
159 template<typename _Type>
160 _GLIBCXX_CONSTEXPR
161 inline bool
162 __is_null_pointer(_Type)
163 { return false; }
164
165 #if __cplusplus >= 201103L
166 constexpr bool
167 __is_null_pointer(std::nullptr_t)
168 { return true; }
169 #endif
170
171 // For arithmetic promotions in <complex> and <cmath>
172
173 template<typename _Tp, bool = std::__is_integer<_Tp>::__value>
174 struct __promote
175 { typedef double __type; };
176
177 // No nested __type member for non-integer non-floating point types,
178 // allows this type to be used for SFINAE to constrain overloads in
179 // <cmath> and <complex> to only the intended types.
180 template<typename _Tp>
181 struct __promote<_Tp, false>
182 { };
183
184 template<>
185 struct __promote<long double>
186 { typedef long double __type; };
187
188 template<>
189 struct __promote<double>
190 { typedef double __type; };
191
192 template<>
193 struct __promote<float>
194 { typedef float __type; };
195
196 #ifdef __STDCPP_FLOAT16_T__
197 template<>
198 struct __promote<_Float16>
199 { typedef _Float16 __type; };
200 #endif
201
202 #ifdef __STDCPP_FLOAT32_T__
203 template<>
204 struct __promote<_Float32>
205 { typedef _Float32 __type; };
206 #endif
207
208 #ifdef __STDCPP_FLOAT64_T__
209 template<>
210 struct __promote<_Float64>
211 { typedef _Float64 __type; };
212 #endif
213
214 #ifdef __STDCPP_FLOAT128_T__
215 template<>
216 struct __promote<_Float128>
217 { typedef _Float128 __type; };
218 #endif
219
220 #ifdef __STDCPP_BFLOAT16_T__
221 template<>
222 struct __promote<__gnu_cxx::__bfloat16_t>
223 { typedef __gnu_cxx::__bfloat16_t __type; };
224 #endif
225
226 #if __cpp_fold_expressions
227
228 template<typename... _Tp>
229 using __promoted_t = decltype((typename __promote<_Tp>::__type(0) + ...));
230
231 // Deducing the promoted type is done by __promoted_t<_Tp...>,
232 // then __promote is used to provide the nested __type member.
233 template<typename _Tp, typename _Up>
234 using __promote_2 = __promote<__promoted_t<_Tp, _Up>>;
235
236 template<typename _Tp, typename _Up, typename _Vp>
237 using __promote_3 = __promote<__promoted_t<_Tp, _Up, _Vp>>;
238
239 template<typename _Tp, typename _Up, typename _Vp, typename _Wp>
240 using __promote_4 = __promote<__promoted_t<_Tp, _Up, _Vp, _Wp>>;
241
242 #else
243
244 template<typename _Tp, typename _Up,
245 typename _Tp2 = typename __promote<_Tp>::__type,
246 typename _Up2 = typename __promote<_Up>::__type>
247 struct __promote_2
248 {
249 typedef __typeof__(_Tp2() + _Up2()) __type;
250 };
251
252 template<typename _Tp, typename _Up, typename _Vp,
253 typename _Tp2 = typename __promote<_Tp>::__type,
254 typename _Up2 = typename __promote<_Up>::__type,
255 typename _Vp2 = typename __promote<_Vp>::__type>
256 struct __promote_3
257 {
258 typedef __typeof__(_Tp2() + _Up2() + _Vp2()) __type;
259 };
260
261 template<typename _Tp, typename _Up, typename _Vp, typename _Wp,
262 typename _Tp2 = typename __promote<_Tp>::__type,
263 typename _Up2 = typename __promote<_Up>::__type,
264 typename _Vp2 = typename __promote<_Vp>::__type,
265 typename _Wp2 = typename __promote<_Wp>::__type>
266 struct __promote_4
267 {
268 typedef __typeof__(_Tp2() + _Up2() + _Vp2() + _Wp2()) __type;
269 };
270 #endif
271
272 _GLIBCXX_END_NAMESPACE_VERSION
273 } // namespace
274 } // extern "C++"
275
276 #pragma GCC diagnostic pop
277
278 #endif