33 constexpr bool is_integral = std::is_integral_v<From> && std::is_integral_v<To>;
34 constexpr bool is_floating_point = std::is_floating_point_v<From> && std::is_floating_point_v<To>;
35 static_assert(is_integral || is_floating_point);
37 using FromLimits = std::numeric_limits<From>;
38 using ToLimits = std::numeric_limits<To>;
40 constexpr bool check_positive_overflow =
41 is_integral ? ToLimits::digits < FromLimits::digits : ToLimits::max() < FromLimits::max();
42 constexpr bool check_negative_overflow =
47 FromLimits::is_signed && (!ToLimits::is_signed || ToLimits::digits < FromLimits::digits)
48 : ToLimits::lowest() > FromLimits::lowest();
50 std::string_view overflow_type{};
52 if constexpr (check_positive_overflow) {
53 if (input >
static_cast<From>(ToLimits::max())) {
54 if (!FromLimits::has_infinity || !std::isinf(input)) {
55 overflow_type =
"positive";
60 if constexpr (check_negative_overflow) {
61 if (input <
static_cast<From>(ToLimits::lowest())) {
62 if (!FromLimits::has_infinity || !std::isinf(input)) {
63 overflow_type =
"negative";
68 if (!overflow_type.empty()) {
69 throw Exception(fmt::format(
70 "Failed to convert {} {} into {} due to {} integer overflow",
72 static_cast<
impl::PrintableValue<From>>(input),
78 return static_cast<To>(input);