refactor: use _MiB consistently for Mebibyte conversions

Replace hard-coded MiB byte conversions (e.g. `1024*1024`, `1<<20`, `1048576`) with the existing `_MiB` literal to improve readability and avoid repeating constants.
In the few spots where arithmetic involves signed values, the result is identical to the previous code assuming those quantities never turn negative.

Also switch to brace init on every declaration assigned from `_MiB`/`_GiB` literals so a future oversized value (e.g. `unsigned int x{4096_MiB}`) becomes a compile error through the C++11 narrowing check instead of silently truncating.

Extend unit tests to cover the 32-bit `size_t` overflow boundary and to assert equivalence for integer and floating-point conversions.

Co-authored-by: MarcoFalke <*~=`'#}+{/-|&$^_@721217.xyz>
Co-authored-by: w0xlt <94266259+w0xlt@users.noreply.github.com>
This commit is contained in:
Lőrinc
2026-01-28 14:38:24 +01:00
parent b3edd30aa2
commit af0ee28eb6
36 changed files with 138 additions and 82 deletions

View File

@@ -1633,7 +1633,7 @@ BOOST_AUTO_TEST_CASE(util_ParseByteUnits)
BOOST_CHECK_EQUAL(ParseByteUnits("1K", noop).value(), 1ULL << 10);
BOOST_CHECK_EQUAL(ParseByteUnits("2m", noop).value(), 2'000'000ULL);
BOOST_CHECK_EQUAL(ParseByteUnits("2M", noop).value(), 2ULL << 20);
BOOST_CHECK_EQUAL(ParseByteUnits("2M", noop).value(), 2_MiB);
BOOST_CHECK_EQUAL(ParseByteUnits("3g", noop).value(), 3'000'000'000ULL);
BOOST_CHECK_EQUAL(ParseByteUnits("3G", noop).value(), 3_GiB);
@@ -1657,7 +1657,7 @@ BOOST_AUTO_TEST_CASE(util_ParseByteUnits)
BOOST_CHECK(!ParseByteUnits("+123m", noop));
// zero padding
BOOST_CHECK_EQUAL(ParseByteUnits("020M", noop).value(), 20ULL << 20);
BOOST_CHECK_EQUAL(ParseByteUnits("020M", noop).value(), 20_MiB);
// fractions not allowed
BOOST_CHECK(!ParseByteUnits("0.5T", noop));
@@ -1831,8 +1831,34 @@ BOOST_AUTO_TEST_CASE(mib_string_literal_test)
{
// Basic equivalences and simple arithmetic operations
BOOST_CHECK_EQUAL(0_MiB, 0);
BOOST_CHECK_EQUAL(1_MiB, 1 << 20);
BOOST_CHECK_EQUAL(1_MiB, 1024 * 1024);
BOOST_CHECK_EQUAL(1_MiB, 0x100000U);
BOOST_CHECK_EQUAL(1_MiB, 1048576U);
BOOST_CHECK_EQUAL(2ULL * 1_MiB, 2ULL << 20);
BOOST_CHECK_EQUAL((3_MiB + 123) / double(1_MiB), (3_MiB + 123) / 1024.0 / 1024.0);
// Specific codebase values
BOOST_CHECK_EQUAL(4_MiB, 1 << 22);
BOOST_CHECK_EQUAL(8_MiB, 1 << 23);
BOOST_CHECK_EQUAL(16_MiB, 0x1000000U);
BOOST_CHECK_EQUAL(16_MiB, 1 << 24);
BOOST_CHECK_EQUAL(32_MiB, 0x2000000U);
BOOST_CHECK_EQUAL(32_MiB, 32U << 20);
BOOST_CHECK_EQUAL(50_MiB / 1_MiB, 50U);
BOOST_CHECK_EQUAL(50_MiB, 52428800U);
BOOST_CHECK_EQUAL(128_MiB, 0x8000000U);
BOOST_CHECK_EQUAL(550_MiB, 550ULL * 1024 * 1024);
// Overflow handling
constexpr auto max_mib{std::numeric_limits<size_t>::max() >> 20};
if constexpr (SIZE_MAX == UINT32_MAX) {
BOOST_CHECK_EQUAL(max_mib, 4095U);
BOOST_CHECK_EQUAL(4095_MiB, size_t{4095} << 20);
BOOST_CHECK_EXCEPTION(4096_MiB, std::overflow_error, HasReason("MiB value too large for size_t byte conversion"));
} else {
BOOST_CHECK_EQUAL(4096_MiB, size_t{4096} << 20);
}
BOOST_CHECK_EXCEPTION(operator""_MiB(max_mib + 1), std::overflow_error, HasReason("MiB value too large for size_t byte conversion"));
}