mirror of
https://github.com/XRPLF/rippled.git
synced 2025-12-06 17:27:55 +00:00
refactor: change the return type of mulDiv to std::optional (#4243)
- Previously, mulDiv had `std::pair<bool, uint64_t>` as the output type.
- This is an error-prone interface as it is easy to ignore when
overflow occurs.
- Using a return type of `std::optional` should decrease the likelihood
of ignoring overflow.
- It also allows for the use of optional::value_or() as a way to
explicitly recover from overflow.
- Include limits.h header file preprocessing directive in order to
satisfy gcc's numeric_limits incomplete_type requirement.
Fix #3495
---------
Co-authored-by: John Freeman <jfreeman08@gmail.com>
This commit is contained in:
committed by
GitHub
parent
77dc63b549
commit
c6fee28b92
@@ -50,12 +50,17 @@ private:
|
||||
FeeLevel32 f{10};
|
||||
FeeLevel32 baseFee{100};
|
||||
|
||||
auto drops = mulDiv(baseFee, x, f).second;
|
||||
auto drops = mulDiv(baseFee, x, f);
|
||||
|
||||
BEAST_EXPECT(drops);
|
||||
BEAST_EXPECT(drops.value() == 1000);
|
||||
BEAST_EXPECT(
|
||||
(std::is_same_v<decltype(drops)::unit_type, feeunit::dropTag>));
|
||||
BEAST_EXPECT((std::is_same_v<decltype(drops), XRPAmount>));
|
||||
BEAST_EXPECT((std::is_same_v<
|
||||
std::remove_reference_t<decltype(*drops)>::unit_type,
|
||||
feeunit::dropTag>));
|
||||
|
||||
BEAST_EXPECT((std::is_same_v<
|
||||
std::remove_reference_t<decltype(*drops)>,
|
||||
XRPAmount>));
|
||||
}
|
||||
{
|
||||
XRPAmount x{100};
|
||||
@@ -70,12 +75,16 @@ private:
|
||||
FeeLevel64 f{10};
|
||||
FeeLevel64 baseFee{100};
|
||||
|
||||
auto drops = mulDiv(baseFee, x, f).second;
|
||||
auto drops = mulDiv(baseFee, x, f);
|
||||
|
||||
BEAST_EXPECT(drops);
|
||||
BEAST_EXPECT(drops.value() == 1000);
|
||||
BEAST_EXPECT(
|
||||
(std::is_same_v<decltype(drops)::unit_type, feeunit::dropTag>));
|
||||
BEAST_EXPECT((std::is_same_v<decltype(drops), XRPAmount>));
|
||||
BEAST_EXPECT((std::is_same_v<
|
||||
std::remove_reference_t<decltype(*drops)>::unit_type,
|
||||
feeunit::dropTag>));
|
||||
BEAST_EXPECT((std::is_same_v<
|
||||
std::remove_reference_t<decltype(*drops)>,
|
||||
XRPAmount>));
|
||||
}
|
||||
{
|
||||
FeeLevel64 x{1024};
|
||||
@@ -91,12 +100,16 @@ private:
|
||||
XRPAmount basefee{10};
|
||||
FeeLevel64 referencefee{256};
|
||||
|
||||
auto drops = mulDiv(x, basefee, referencefee).second;
|
||||
auto drops = mulDiv(x, basefee, referencefee);
|
||||
|
||||
BEAST_EXPECT(drops);
|
||||
BEAST_EXPECT(drops.value() == 40);
|
||||
BEAST_EXPECT(
|
||||
(std::is_same_v<decltype(drops)::unit_type, feeunit::dropTag>));
|
||||
BEAST_EXPECT((std::is_same_v<decltype(drops), XRPAmount>));
|
||||
BEAST_EXPECT((std::is_same_v<
|
||||
std::remove_reference_t<decltype(*drops)>::unit_type,
|
||||
feeunit::dropTag>));
|
||||
BEAST_EXPECT((std::is_same_v<
|
||||
std::remove_reference_t<decltype(*drops)>,
|
||||
XRPAmount>));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -32,27 +32,27 @@ struct mulDiv_test : beast::unit_test::suite
|
||||
const std::uint64_t max32 = std::numeric_limits<std::uint32_t>::max();
|
||||
|
||||
auto result = mulDiv(85, 20, 5);
|
||||
BEAST_EXPECT(result.first && result.second == 340);
|
||||
BEAST_EXPECT(result && *result == 340);
|
||||
result = mulDiv(20, 85, 5);
|
||||
BEAST_EXPECT(result.first && result.second == 340);
|
||||
BEAST_EXPECT(result && *result == 340);
|
||||
|
||||
result = mulDiv(0, max - 1, max - 3);
|
||||
BEAST_EXPECT(result.first && result.second == 0);
|
||||
BEAST_EXPECT(result && *result == 0);
|
||||
result = mulDiv(max - 1, 0, max - 3);
|
||||
BEAST_EXPECT(result.first && result.second == 0);
|
||||
BEAST_EXPECT(result && *result == 0);
|
||||
|
||||
result = mulDiv(max, 2, max / 2);
|
||||
BEAST_EXPECT(result.first && result.second == 4);
|
||||
BEAST_EXPECT(result && *result == 4);
|
||||
result = mulDiv(max, 1000, max / 1000);
|
||||
BEAST_EXPECT(result.first && result.second == 1000000);
|
||||
BEAST_EXPECT(result && *result == 1000000);
|
||||
result = mulDiv(max, 1000, max / 1001);
|
||||
BEAST_EXPECT(result.first && result.second == 1001000);
|
||||
BEAST_EXPECT(result && *result == 1001000);
|
||||
result = mulDiv(max32 + 1, max32 + 1, 5);
|
||||
BEAST_EXPECT(result.first && result.second == 3689348814741910323);
|
||||
BEAST_EXPECT(result && *result == 3689348814741910323);
|
||||
|
||||
// Overflow
|
||||
result = mulDiv(max - 1, max - 2, 5);
|
||||
BEAST_EXPECT(!result.first && result.second == max);
|
||||
BEAST_EXPECT(!result);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user