mirror of
https://github.com/Atmosphere-NX/Atmosphere.git
synced 2025-06-07 18:04:40 -04:00
strat: revise fs unsupported operation results, add overflow utils
This commit is contained in:
parent
ba4e7c5866
commit
11e4bed199
31 changed files with 265 additions and 142 deletions
|
@ -69,4 +69,91 @@ namespace ams::util {
|
|||
return ::ams::util::impl::IsIntValueRepresentableImpl<To, From>(v);
|
||||
}
|
||||
|
||||
template<std::integral T>
|
||||
constexpr ALWAYS_INLINE bool CanAddWithoutOverflow(T x, T y) {
|
||||
if constexpr (std::unsigned_integral<T>) {
|
||||
return x <= std::numeric_limits<T>::max() - y;
|
||||
} else {
|
||||
if (y >= 0) {
|
||||
return x <= std::numeric_limits<T>::max() - y;
|
||||
} else {
|
||||
return x >= std::numeric_limits<T>::min() - y;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template<std::integral T>
|
||||
constexpr ALWAYS_INLINE bool CanSubtractWithoutOverflow(T x, T y) {
|
||||
if constexpr (std::unsigned_integral<T>) {
|
||||
return x >= std::numeric_limits<T>::min() + y;
|
||||
} else {
|
||||
if (y >= 0) {
|
||||
return x >= std::numeric_limits<T>::min() + y;
|
||||
} else {
|
||||
return x <= std::numeric_limits<T>::max() + y;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template<std::integral T>
|
||||
constexpr ALWAYS_INLINE bool CanMultiplyWithoutOverflow(T x, T y) {
|
||||
if (x == 0 || y == 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if constexpr (std::unsigned_integral<T>) {
|
||||
return y <= std::numeric_limits<T>::max() / x;
|
||||
} else {
|
||||
if (x > 0) {
|
||||
if (y > 0) {
|
||||
return y <= std::numeric_limits<T>::max() / x;
|
||||
} else /*if (y < 0) */ {
|
||||
return y >= std::numeric_limits<T>::min() / x;
|
||||
}
|
||||
} else /* if (x < 0) */ {
|
||||
if (y > 0) {
|
||||
return x >= std::numeric_limits<T>::min() / y;
|
||||
} else /*if (y < 0) */ {
|
||||
return y >= std::numeric_limits<T>::max() / x;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template<std::integral T>
|
||||
constexpr inline bool TryAddWithoutOverflow(T *out, T x, T y) {
|
||||
AMS_ASSERT(out != nullptr);
|
||||
|
||||
if (CanAddWithoutOverflow(x, y)) {
|
||||
*out = x + y;
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
template<std::integral T>
|
||||
constexpr inline bool TrySubtractWithoutOverflow(T *out, T x, T y) {
|
||||
AMS_ASSERT(out != nullptr);
|
||||
|
||||
if (CanSubtractWithoutOverflow(x, y)) {
|
||||
*out = x - y;
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
template<std::integral T>
|
||||
constexpr inline bool TryMultiplyWithoutOverflow(T *out, T x, T y) {
|
||||
AMS_ASSERT(out != nullptr);
|
||||
|
||||
if (CanMultiplyWithoutOverflow(x, y)) {
|
||||
*out = x * y;
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue