fixup size literals

This commit is contained in:
Matt Witherspoon
2025-09-03 15:45:07 -04:00
parent 9a55793631
commit ff80cca7d5
+14 -12
View File
@@ -208,37 +208,39 @@ namespace fc {
//TODO: these should really be consteval, but they're getting pulled in by a few of our c++17 compiled files
namespace size_literals {
namespace detail {
template <unsigned ShiftAmount>
constexpr unsigned long long to_bytes(const unsigned long long val) {
constexpr unsigned long long multiply_pow2(const unsigned long long val, const unsigned long long shift) {
if(shift >= std::numeric_limits<unsigned long long>::digits)
throw std::invalid_argument("exponent for pow2 too large");
constexpr unsigned long long max_ull = std::numeric_limits<unsigned long long>::max();
constexpr unsigned long long multiplier = 1ull << ShiftAmount;
if(val > max_ull/multiplier)
if(val > (max_ull >> shift))
throw std::invalid_argument("literal too large");
return val * multiplier;
return val << shift;
}
}
constexpr unsigned long long operator""_KiB(const unsigned long long val) {
return detail::to_bytes<10>(val);
return detail::multiply_pow2(val, 10);
}
constexpr unsigned long long operator""_MiB(const unsigned long long val) {
return detail::to_bytes<20>(val);
return detail::multiply_pow2(val, 20);
}
constexpr unsigned long long operator""_GiB(const unsigned long long val) {
return detail::to_bytes<30>(val);
return detail::multiply_pow2(val, 30);
}
constexpr unsigned long long operator""_TiB(const unsigned long long val) {
return detail::to_bytes<40>(val);
return detail::multiply_pow2(val, 40);
}
constexpr unsigned long long operator""_pow2(const unsigned long long n) {
if(n >= std::numeric_limits<unsigned long long>::digits)
throw std::invalid_argument("exponent for _pow2 too large");
return 1ull << n;
return detail::multiply_pow2(1, n);
}
static_assert(4_MiB == 4*1024*1024);
static_assert(16_pow2 == 64*1024);
static_assert(63_pow2 == 9223372036854775808ull);
}
}