Skip to content

Commit caf2d13

Browse files
refactor: Update numeric concepts to use underlying type constraints
1 parent 1157f9b commit caf2d13

1 file changed

Lines changed: 27 additions & 62 deletions

File tree

src/conversion/underlying.cppm

Lines changed: 27 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -15,37 +15,16 @@ import mcpplibs.primitives.underlying.traits;
1515

1616
namespace mcpplibs::primitives::conversion::details {
1717

18-
template <typename T>
19-
concept integral_like = std::integral<std::remove_cvref_t<T>>;
20-
21-
template <typename T>
22-
concept floating_like = std::floating_point<std::remove_cvref_t<T>>;
23-
24-
template <typename T>
25-
concept numeric_like = integral_like<T> || floating_like<T>;
26-
27-
template <typename T>
28-
concept custom_numeric_like =
29-
requires(std::remove_cvref_t<T> a, std::remove_cvref_t<T> b) {
30-
{ a + b };
31-
{ a - b };
32-
{ a * b };
33-
{ a / b };
34-
{ a == b } -> std::convertible_to<bool>;
35-
};
36-
37-
template <typename T>
38-
concept numeric_cast_operand = numeric_like<T> || custom_numeric_like<T>;
39-
4018
template <typename DestRep, typename SrcRep>
4119
concept statically_castable = requires(SrcRep value) {
4220
static_cast<std::remove_cvref_t<DestRep>>(value);
4321
};
4422

4523
template <typename DestRep, typename SrcRep>
46-
concept builtin_numeric_pair = numeric_like<DestRep> && numeric_like<SrcRep>;
24+
concept builtin_numeric_pair =
25+
numeric_underlying_type<DestRep> && numeric_underlying_type<SrcRep>;
4726

48-
template <integral_like DestRep, integral_like SrcRep>
27+
template <integer_underlying_type DestRep, integer_underlying_type SrcRep>
4928
constexpr auto numeric_risk(SrcRep value)
5029
-> std::optional<risk::kind> {
5130
using dest_type = std::remove_cvref_t<DestRep>;
@@ -84,7 +63,7 @@ constexpr auto numeric_risk(SrcRep value)
8463
}
8564
}
8665

87-
template <integral_like DestRep, floating_like SrcRep>
66+
template <integer_underlying_type DestRep, floating_underlying_type SrcRep>
8867
constexpr auto numeric_risk(SrcRep value)
8968
-> std::optional<risk::kind> {
9069
using dest_type = std::remove_cvref_t<DestRep>;
@@ -113,7 +92,7 @@ constexpr auto numeric_risk(SrcRep value)
11392
return std::nullopt;
11493
}
11594

116-
template <floating_like DestRep, integral_like SrcRep>
95+
template <floating_underlying_type DestRep, integer_underlying_type SrcRep>
11796
constexpr auto numeric_risk(SrcRep value)
11897
-> std::optional<risk::kind> {
11998
using dest_type = std::remove_cvref_t<DestRep>;
@@ -133,7 +112,7 @@ constexpr auto numeric_risk(SrcRep value)
133112
return std::nullopt;
134113
}
135114

136-
template <floating_like DestRep, floating_like SrcRep>
115+
template <floating_underlying_type DestRep, floating_underlying_type SrcRep>
137116
constexpr auto numeric_risk(SrcRep value)
138117
-> std::optional<risk::kind> {
139118
using dest_type = std::remove_cvref_t<DestRep>;
@@ -167,15 +146,15 @@ constexpr auto numeric_risk(SrcRep value)
167146
return std::nullopt;
168147
}
169148

170-
template <numeric_cast_operand DestRep, numeric_cast_operand SrcRep>
149+
template <numeric_underlying_type DestRep, numeric_underlying_type SrcRep>
171150
requires statically_castable<DestRep, SrcRep>
172151
constexpr auto unchecked_rep_cast(SrcRep value) noexcept
173152
-> std::remove_cvref_t<DestRep> {
174153
using dest_type = std::remove_cvref_t<DestRep>;
175154
return static_cast<dest_type>(value);
176155
}
177156

178-
template <numeric_cast_operand DestRep, numeric_cast_operand SrcRep>
157+
template <numeric_underlying_type DestRep, numeric_underlying_type SrcRep>
179158
requires statically_castable<DestRep, SrcRep>
180159
constexpr auto checked_rep_cast(SrcRep value)
181160
-> cast_result<std::remove_cvref_t<DestRep>> {
@@ -191,7 +170,7 @@ constexpr auto checked_rep_cast(SrcRep value)
191170
return static_cast<dest_type>(value);
192171
}
193172

194-
template <numeric_cast_operand DestRep, numeric_cast_operand SrcRep>
173+
template <numeric_underlying_type DestRep, numeric_underlying_type SrcRep>
195174
requires statically_castable<DestRep, SrcRep>
196175
constexpr auto saturating_rep_cast(SrcRep value) noexcept
197176
-> std::remove_cvref_t<DestRep> {
@@ -215,14 +194,15 @@ constexpr auto saturating_rep_cast(SrcRep value) noexcept
215194
return static_cast<dest_type>(value);
216195
}
217196

218-
template <numeric_cast_operand DestRep, numeric_cast_operand SrcRep>
197+
template <numeric_underlying_type DestRep, numeric_underlying_type SrcRep>
219198
requires statically_castable<DestRep, SrcRep>
220199
constexpr auto truncating_rep_cast(SrcRep value) noexcept
221200
-> std::remove_cvref_t<DestRep> {
222201
using dest_type = std::remove_cvref_t<DestRep>;
223202
using src_type = std::remove_cvref_t<SrcRep>;
224203

225-
if constexpr (integral_like<dest_type> && floating_like<src_type>) {
204+
if constexpr (integer_underlying_type<dest_type> &&
205+
floating_underlying_type<src_type>) {
226206
if (std::isnan(value)) {
227207
return dest_type{};
228208
}
@@ -249,7 +229,7 @@ constexpr auto truncating_rep_cast(SrcRep value) noexcept
249229
return static_cast<dest_type>(value);
250230
}
251231

252-
template <numeric_cast_operand DestRep, numeric_cast_operand SrcRep>
232+
template <numeric_underlying_type DestRep, numeric_underlying_type SrcRep>
253233
requires statically_castable<DestRep, SrcRep>
254234
constexpr auto exact_rep_cast(SrcRep value)
255235
-> cast_result<std::remove_cvref_t<DestRep>> {
@@ -270,75 +250,60 @@ constexpr auto exact_rep_cast(SrcRep value)
270250

271251
export namespace mcpplibs::primitives::conversion {
272252

273-
template <details::integral_like DestRep, details::integral_like SrcRep>
253+
template <integer_underlying_type DestRep, integer_underlying_type SrcRep>
274254
constexpr auto numeric_risk(SrcRep value)
275255
-> std::optional<risk::kind> {
276256
return details::numeric_risk<DestRep>(value);
277257
}
278258

279-
template <details::integral_like DestRep, details::floating_like SrcRep>
259+
template <integer_underlying_type DestRep, floating_underlying_type SrcRep>
280260
constexpr auto numeric_risk(SrcRep value)
281261
-> std::optional<risk::kind> {
282262
return details::numeric_risk<DestRep>(value);
283263
}
284264

285-
template <details::floating_like DestRep, details::integral_like SrcRep>
265+
template <floating_underlying_type DestRep, integer_underlying_type SrcRep>
286266
constexpr auto numeric_risk(SrcRep value)
287267
-> std::optional<risk::kind> {
288268
return details::numeric_risk<DestRep>(value);
289269
}
290270

291-
template <details::floating_like DestRep, details::floating_like SrcRep>
271+
template <floating_underlying_type DestRep, floating_underlying_type SrcRep>
292272
constexpr auto numeric_risk(SrcRep value)
293273
-> std::optional<risk::kind> {
294274
return details::numeric_risk<DestRep>(value);
295275
}
296276

297-
template <details::numeric_cast_operand DestRep,
298-
details::numeric_cast_operand SrcRep>
299-
requires details::statically_castable<DestRep, SrcRep> &&
300-
(!(underlying_type<std::remove_cvref_t<DestRep>> &&
301-
underlying_type<std::remove_cvref_t<SrcRep>>))
277+
template <numeric_underlying_type DestRep, numeric_underlying_type SrcRep>
278+
requires details::statically_castable<DestRep, SrcRep>
302279
constexpr auto unchecked_cast(SrcRep value) noexcept
303280
-> std::remove_cvref_t<DestRep> {
304281
return details::unchecked_rep_cast<DestRep>(value);
305282
}
306283

307-
template <details::numeric_cast_operand DestRep,
308-
details::numeric_cast_operand SrcRep>
309-
requires details::statically_castable<DestRep, SrcRep> &&
310-
(!(underlying_type<std::remove_cvref_t<DestRep>> &&
311-
underlying_type<std::remove_cvref_t<SrcRep>>))
284+
template <numeric_underlying_type DestRep, numeric_underlying_type SrcRep>
285+
requires details::statically_castable<DestRep, SrcRep>
312286
constexpr auto checked_cast(SrcRep value)
313287
-> cast_result<std::remove_cvref_t<DestRep>> {
314288
return details::checked_rep_cast<DestRep>(value);
315289
}
316290

317-
template <details::numeric_cast_operand DestRep,
318-
details::numeric_cast_operand SrcRep>
319-
requires details::statically_castable<DestRep, SrcRep> &&
320-
(!(underlying_type<std::remove_cvref_t<DestRep>> &&
321-
underlying_type<std::remove_cvref_t<SrcRep>>))
291+
template <numeric_underlying_type DestRep, numeric_underlying_type SrcRep>
292+
requires details::statically_castable<DestRep, SrcRep>
322293
constexpr auto saturating_cast(SrcRep value) noexcept
323294
-> std::remove_cvref_t<DestRep> {
324295
return details::saturating_rep_cast<DestRep>(value);
325296
}
326297

327-
template <details::numeric_cast_operand DestRep,
328-
details::numeric_cast_operand SrcRep>
329-
requires details::statically_castable<DestRep, SrcRep> &&
330-
(!(underlying_type<std::remove_cvref_t<DestRep>> &&
331-
underlying_type<std::remove_cvref_t<SrcRep>>))
298+
template <numeric_underlying_type DestRep, numeric_underlying_type SrcRep>
299+
requires details::statically_castable<DestRep, SrcRep>
332300
constexpr auto truncating_cast(SrcRep value) noexcept
333301
-> std::remove_cvref_t<DestRep> {
334302
return details::truncating_rep_cast<DestRep>(value);
335303
}
336304

337-
template <details::numeric_cast_operand DestRep,
338-
details::numeric_cast_operand SrcRep>
339-
requires details::statically_castable<DestRep, SrcRep> &&
340-
(!(underlying_type<std::remove_cvref_t<DestRep>> &&
341-
underlying_type<std::remove_cvref_t<SrcRep>>))
305+
template <numeric_underlying_type DestRep, numeric_underlying_type SrcRep>
306+
requires details::statically_castable<DestRep, SrcRep>
342307
constexpr auto exact_cast(SrcRep value)
343308
-> cast_result<std::remove_cvref_t<DestRep>> {
344309
return details::exact_rep_cast<DestRep>(value);

0 commit comments

Comments
 (0)