Stratax 0.4.0rc1
Loading...
Searching...
No Matches
Promotion.hpp
Go to the documentation of this file.
1
4#pragma once
5
6#include <concepts>
7#include <cstddef>
8#include <type_traits>
9
11
12namespace stratax::core {
13
23template<typename L, typename R>
24struct Promote;
25
29template<typename T>
30requires requires
31{
32 typename DTypeTraits<T>::type;
34}
35struct Promote<T, T>
36{
38 using type = T;
39};
40
44template<typename L, typename R>
45requires (
46 DTypeTraits<L>::kind == DTypeKind::SignedInteger &&
47 DTypeTraits<R>::kind == DTypeKind::SignedInteger
48)
50{
52 using type = std::conditional_t<
54 L,
55 R
56 >;
57};
58
62template<typename L, typename R>
63requires (
64 DTypeTraits<L>::kind == DTypeKind::UnsignedInteger &&
65 DTypeTraits<R>::kind == DTypeKind::UnsignedInteger
66)
67struct Promote<L, R>
68{
70 using type = std::conditional_t<
72 L,
73 R
74 >;
75};
76
84template<typename L, typename R>
85requires (
86 (DTypeTraits<L>::kind == DTypeKind::SignedInteger &&
87 DTypeTraits<R>::kind == DTypeKind::UnsignedInteger) ||
88 (DTypeTraits<L>::kind == DTypeKind::UnsignedInteger &&
89 DTypeTraits<R>::kind == DTypeKind::SignedInteger)
90)
91struct Promote<L, R>
92{
93private:
94 using signed_type = std::conditional_t<
95 DTypeTraits<L>::kind == DTypeKind::SignedInteger,
96 L,
97 R
98 >;
99
100 using unsigned_type = std::conditional_t<
101 DTypeTraits<L>::kind == DTypeKind::UnsignedInteger,
102 L,
103 R
104 >;
105
106 static constexpr std::size_t signed_bits =
108
109 static constexpr std::size_t unsigned_bits =
111
112 /*
113 * An N-bit unsigned integer requires N+1 bits in a signed
114 * representation to preserve its complete range.
115 */
116 static constexpr std::size_t required_bits =
117 signed_bits > unsigned_bits
118 ? signed_bits
119 : unsigned_bits + 1;
120
121public:
123 using type = std::conditional_t<
124 (required_bits <= 8),
126 std::conditional_t<
127 (required_bits <= 16),
129 std::conditional_t<
130 (required_bits <= 32),
132 std::conditional_t<
133 (required_bits <= 64),
136 >
137 >
138 >
139 >;
140};
141
149template<typename L, typename R>
150requires (
151 (
152 (DTypeTraits<L>::kind == DTypeKind::SignedInteger ||
153 DTypeTraits<L>::kind == DTypeKind::UnsignedInteger) &&
154 DTypeTraits<R>::kind == DTypeKind::Floating
155 ) ||
156 (
157 DTypeTraits<L>::kind == DTypeKind::Floating &&
158 (DTypeTraits<R>::kind == DTypeKind::SignedInteger ||
159 DTypeTraits<R>::kind == DTypeKind::UnsignedInteger)
160 )
161)
162struct Promote<L, R>
163{
164private:
165 using integer_type = std::conditional_t<
166 DTypeTraits<L>::kind == DTypeKind::SignedInteger ||
167 DTypeTraits<L>::kind == DTypeKind::UnsignedInteger,
168 L,
169 R
170 >;
171
172 using floating_type = std::conditional_t<
173 DTypeTraits<L>::kind == DTypeKind::Floating,
174 L,
175 R
176 >;
177
178 static constexpr int integer_digits =
180
181 static constexpr int floating_digits =
183
184public:
186 using type = std::conditional_t<
187 (integer_digits <= floating_digits),
188 floating_type,
189 std::conditional_t<
190 std::same_as<floating_type, dtype::float32>,
192 floating_type
193 >
194 >;
195};
196
201template<typename L, typename R>
202requires (
203 DTypeTraits<L>::kind == DTypeKind::Floating &&
204 DTypeTraits<R>::kind == DTypeKind::Floating
205)
206struct Promote<L, R>
207{
209 using type = std::conditional_t<
211 L,
212 R
213 >;
214};
215
219template<typename L, typename R>
220requires (
221 DTypeTraits<L>::kind == DTypeKind::Complex &&
222 DTypeTraits<R>::kind == DTypeKind::Complex
223)
224struct Promote<L, R>
225{
226private:
227 using left_component =
229
230 using right_component =
232
233 using promoted_component =
235
236public:
238 using type =
240};
241
249template<typename L, typename R>
250requires (
251 (
252 (DTypeTraits<L>::kind == DTypeKind::SignedInteger ||
253 DTypeTraits<L>::kind == DTypeKind::UnsignedInteger ||
254 DTypeTraits<L>::kind == DTypeKind::Floating) &&
255 DTypeTraits<R>::kind == DTypeKind::Complex
256 ) ||
257 (
258 DTypeTraits<L>::kind == DTypeKind::Complex &&
259 (DTypeTraits<R>::kind == DTypeKind::SignedInteger ||
260 DTypeTraits<R>::kind == DTypeKind::UnsignedInteger ||
261 DTypeTraits<R>::kind == DTypeKind::Floating)
262 )
263)
264struct Promote<L, R>
265{
266private:
267 using real_type = std::conditional_t<
268 DTypeTraits<L>::kind == DTypeKind::Complex,
269 R,
270 L
271 >;
272
273 using complex_type = std::conditional_t<
274 DTypeTraits<L>::kind == DTypeKind::Complex,
275 L,
276 R
277 >;
278
279 using component_type =
281
282 using promoted_component =
284
285public:
287 using type =
289};
290
296template<typename L, typename R>
297using promote_t = typename Promote<
298 std::remove_cvref_t<L>,
299 std::remove_cvref_t<R>
300>::type;
301
302} // namespace stratax::core
Compile-time metadata for supported dtypes.
typename ComplexComponent< std::remove_cvref_t< T > >::type complex_component_t
Underlying real dtype of a complex dtype.
typename ComplexFromReal< std::remove_cvref_t< T > >::type complex_from_real_t
Complex dtype corresponding to a real floating-point dtype.
typename Promote< std::remove_cvref_t< L >, std::remove_cvref_t< R > >::type promote_t
Convenience alias for the promoted dtype of two types.
std::int32_t int32
Signed 32-bit integer dtype.
Definition Types.hpp:31
double float64
Native double dtype.
Definition Types.hpp:47
std::int8_t int8
Signed 8-bit integer dtype.
Definition Types.hpp:27
std::int16_t int16
Signed 16-bit integer dtype.
Definition Types.hpp:29
std::int64_t int64
Signed 64-bit integer dtype.
Definition Types.hpp:33
Provides compile-time metadata for a supported Stratax dtype.
std::conditional_t<(DTypeTraits< L >::bits >=DTypeTraits< R >::bits), L, R > type
Result dtype selected by this promotion specialization.
Definition Promotion.hpp:56
T type
Result dtype selected by this promotion specialization.
Definition Promotion.hpp:38
Determines the promoted dtype for two Stratax dtypes.
Definition Promotion.hpp:24