52 -> std::enable_if_t<!std::is_same<SourceType, TargetType>::value, TargetType>
54 if constexpr (std::is_integral_v<TargetType> && std::is_floating_point_v<SourceType>) {
55 SourceType float_max = std::nextafter(
56 static_cast<SourceType
>(std::numeric_limits<TargetType>::max()),
58 SourceType float_min = std::nextafter(
59 static_cast<SourceType
>(std::numeric_limits<TargetType>::min()),
61 if (value > float_max || value < float_min) {
62 logger().error(
"Casting failed: float cast overflow for float {}", value);
67 TargetType value_2 =
static_cast<TargetType
>(value);
69 if constexpr (std::is_integral_v<SourceType> && std::is_floating_point_v<TargetType>) {
70 TargetType float_max = std::nextafter(
71 static_cast<TargetType
>(std::numeric_limits<SourceType>::max()),
73 TargetType float_min = std::nextafter(
74 static_cast<TargetType
>(std::numeric_limits<SourceType>::min()),
76 if (value_2 > float_max || value_2 < float_min) {
77 logger().error(
"Casting failed: float cast overflow for integer {}", value);
82 SourceType value_3 =
static_cast<SourceType
>(value_2);
84 if ((value_2 >= 0) != (value >= 0)) {
86 logger().error(
"Casting failed: from {} to {} causes a sign change...", value, value_2);
88 }
else if (value_3 == value) {
93 constexpr SourceType EPS =
94 static_cast<SourceType
>(std::numeric_limits<TargetType>::epsilon());
98 LA_DISABLE_WARNING_BEGIN
99 LA_DISABLE_WARNING_MSVC(4146)
100 const SourceType value_abs = value_3 > 0 ? value_3 : -value_3;
101 LA_DISABLE_WARNING_END
103 const SourceType scaled_eps = value_abs >= SourceType(1) ? EPS * value_abs : EPS;
104 if (value_3 > value && value_3 < value + scaled_eps) {
106 }
else if (value_3 < value && value_3 + scaled_eps > value) {
111 "Casting failed: from {} to {} will incur error ({}) larger than {}",
114 value -
static_cast<SourceType
>(value_2),
167 std::is_enum_v<T> || std::is_enum_v<U>,
168 "At least one of the types should be an enum");
170 (std::is_enum_v<T> && std::is_enum_v<U>) == std::is_same_v<T, U>,
171 "Casting one enum to another is prohibited");
173 using underlying_t = std::underlying_type_t<std::conditional_t<std::is_enum_v<T>, T, U>>;
174 using enum_t = std::conditional_t<std::is_enum_v<T>, T, U>;
175 using other_t = std::conditional_t<std::is_enum_v<T>, U, T>;
177 if constexpr (std::is_enum_v<T>) {
constexpr auto safe_cast(SourceType value) -> std::enable_if_t<!std::is_same< SourceType, TargetType >::value, TargetType >
Perform safe cast from SourceType to TargetType, where "safe" means:
Definition safe_cast.h:51