|
13 | 13 | #pragma once
|
14 | 14 |
|
15 | 15 | #include <type_traits>
|
| 16 | +#include <cmath> |
16 | 17 | #include "simple_string.hpp"
|
17 | 18 |
|
18 | 19 | #undef max
|
@@ -88,9 +89,41 @@ inline void checkLowerLimit(const From& from)
|
88 | 89 | template <typename From, typename To>
|
89 | 90 | inline void checkTruncation(const From& from)
|
90 | 91 | {
|
91 |
| - if(from != static_cast<From>(static_cast<To>(from))) |
| 92 | + // Handle integer to floating point |
| 93 | + if constexpr(std::is_integral_v<From> && std::is_floating_point_v<To>) |
92 | 94 | {
|
93 |
| - throw std::runtime_error("Floating point truncated"); |
| 95 | + // Check if value can be represented exactly in the target type |
| 96 | + To as_float = static_cast<To>(from); |
| 97 | + From back_conv = static_cast<From>(as_float); |
| 98 | + if(back_conv != from) |
| 99 | + { |
| 100 | + throw std::runtime_error("Loss of precision in conversion to floating point"); |
| 101 | + } |
| 102 | + } |
| 103 | + // Handle floating point to integer |
| 104 | + if constexpr(std::is_floating_point_v<From> && std::is_integral_v<To>) |
| 105 | + { |
| 106 | + if(from > static_cast<From>(std::numeric_limits<To>::max()) || |
| 107 | + from < static_cast<From>(std::numeric_limits<To>::lowest()) || |
| 108 | + from != std::nearbyint(from)) |
| 109 | + { |
| 110 | + throw std::runtime_error("Invalid floating point to integer conversion"); |
| 111 | + } |
| 112 | + } |
| 113 | + // Handle other conversions |
| 114 | + else |
| 115 | + { |
| 116 | + if(from > static_cast<From>(std::numeric_limits<To>::max()) || |
| 117 | + from < static_cast<From>(std::numeric_limits<To>::lowest())) |
| 118 | + { |
| 119 | + throw std::runtime_error("Value outside numeric limits"); |
| 120 | + } |
| 121 | + To as_target = static_cast<To>(from); |
| 122 | + From back_to_source = static_cast<From>(as_target); |
| 123 | + if(from != back_to_source) |
| 124 | + { |
| 125 | + throw std::runtime_error("Value truncated in conversion"); |
| 126 | + } |
94 | 127 | }
|
95 | 128 | }
|
96 | 129 |
|
|
0 commit comments