Skip to content

Commit 8b7d8f8

Browse files
refactor: Update numeric risk templates to use std_integer and std_floating for improved type safety
1 parent 60cf921 commit 8b7d8f8

2 files changed

Lines changed: 18 additions & 15 deletions

File tree

src/conversion/underlying.cppm

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,9 @@ concept statically_castable = requires(SrcRep value) {
2121

2222
template <typename DestRep, typename SrcRep>
2323
concept builtin_numeric_pair =
24-
numeric_underlying_type<DestRep> && numeric_underlying_type<SrcRep>;
24+
std_numeric<DestRep> && std_numeric<SrcRep>;
2525

26-
template <integer_underlying_type DestRep, integer_underlying_type SrcRep>
26+
template <std_integer DestRep, std_integer SrcRep>
2727
constexpr auto numeric_risk(SrcRep value)
2828
-> std::optional<risk::kind> {
2929
using dest_type = std::remove_cvref_t<DestRep>;
@@ -62,7 +62,7 @@ constexpr auto numeric_risk(SrcRep value)
6262
}
6363
}
6464

65-
template <integer_underlying_type DestRep, floating_underlying_type SrcRep>
65+
template <std_integer DestRep, std_floating SrcRep>
6666
constexpr auto numeric_risk(SrcRep value)
6767
-> std::optional<risk::kind> {
6868
using dest_type = std::remove_cvref_t<DestRep>;
@@ -91,7 +91,7 @@ constexpr auto numeric_risk(SrcRep value)
9191
return std::nullopt;
9292
}
9393

94-
template <floating_underlying_type DestRep, integer_underlying_type SrcRep>
94+
template <std_floating DestRep, std_integer SrcRep>
9595
constexpr auto numeric_risk(SrcRep value)
9696
-> std::optional<risk::kind> {
9797
using dest_type = std::remove_cvref_t<DestRep>;
@@ -111,7 +111,7 @@ constexpr auto numeric_risk(SrcRep value)
111111
return std::nullopt;
112112
}
113113

114-
template <floating_underlying_type DestRep, floating_underlying_type SrcRep>
114+
template <std_floating DestRep, std_floating SrcRep>
115115
constexpr auto numeric_risk(SrcRep value)
116116
-> std::optional<risk::kind> {
117117
using dest_type = std::remove_cvref_t<DestRep>;
@@ -200,8 +200,7 @@ constexpr auto truncating_rep_cast(SrcRep value) noexcept
200200
using dest_type = std::remove_cvref_t<DestRep>;
201201
using src_type = std::remove_cvref_t<SrcRep>;
202202

203-
if constexpr (integer_underlying_type<dest_type> &&
204-
floating_underlying_type<src_type>) {
203+
if constexpr (std_integer<dest_type> && std_floating<src_type>) {
205204
if (std::isnan(value)) {
206205
return dest_type{};
207206
}
@@ -280,25 +279,25 @@ constexpr auto cast_underlying_result(Src value, RepCaster rep_caster)
280279

281280
export namespace mcpplibs::primitives::conversion {
282281

283-
template <integer_underlying_type DestRep, integer_underlying_type SrcRep>
282+
template <std_integer DestRep, std_integer SrcRep>
284283
constexpr auto numeric_risk(SrcRep value)
285284
-> std::optional<risk::kind> {
286285
return details::numeric_risk<DestRep>(value);
287286
}
288287

289-
template <integer_underlying_type DestRep, floating_underlying_type SrcRep>
288+
template <std_integer DestRep, std_floating SrcRep>
290289
constexpr auto numeric_risk(SrcRep value)
291290
-> std::optional<risk::kind> {
292291
return details::numeric_risk<DestRep>(value);
293292
}
294293

295-
template <floating_underlying_type DestRep, integer_underlying_type SrcRep>
294+
template <std_floating DestRep, std_integer SrcRep>
296295
constexpr auto numeric_risk(SrcRep value)
297296
-> std::optional<risk::kind> {
298297
return details::numeric_risk<DestRep>(value);
299298
}
300299

301-
template <floating_underlying_type DestRep, floating_underlying_type SrcRep>
300+
template <std_floating DestRep, std_floating SrcRep>
302301
constexpr auto numeric_risk(SrcRep value)
303302
-> std::optional<risk::kind> {
304303
return details::numeric_risk<DestRep>(value);

src/operations/operators.cppm

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -532,18 +532,22 @@ constexpr auto apply_assign(Lhs &lhs, Rhs const &rhs)
532532
using lhs_value_type = lhs_traits::value_type;
533533
using lhs_value_policy = lhs_traits::value_policy;
534534
using lhs_rep = underlying::traits<lhs_value_type>::rep_type;
535+
using assign_meta = dispatcher_meta<OpTag, Lhs, Rhs, ErrorPayload>;
536+
using common_value_type = assign_meta::common_rep;
537+
using common_rep = underlying::traits<common_value_type>::rep_type;
535538

536539
auto out = apply<OpTag, Lhs, Rhs, ErrorPayload>(lhs, rhs);
537540
if (!out.has_value()) {
538541
return std::unexpected(out.error());
539542
}
540543

541544
auto const assigned_common = out->load();
545+
auto const assigned_common_rep =
546+
underlying::traits<common_value_type>::to_rep(assigned_common);
542547
if constexpr (std::same_as<lhs_value_policy, policy::value::checked> &&
543-
std::integral<lhs_rep>) {
548+
std_integer<lhs_rep> && std_numeric<common_rep>) {
544549
if (auto const kind =
545-
conversion::numeric_risk<lhs_rep>(
546-
assigned_common);
550+
conversion::numeric_risk<lhs_rep>(assigned_common_rep);
547551
kind.has_value()) {
548552
return std::unexpected(
549553
details::to_error_payload<ErrorPayload>(
@@ -552,7 +556,7 @@ constexpr auto apply_assign(Lhs &lhs, Rhs const &rhs)
552556
}
553557

554558
auto const assigned_rep =
555-
conversion::saturating_cast<lhs_rep>(assigned_common);
559+
conversion::saturating_cast<lhs_rep>(assigned_common_rep);
556560
lhs.store(underlying::traits<lhs_value_type>::from_rep(assigned_rep));
557561
return out;
558562
}

0 commit comments

Comments
 (0)