mirror of
https://github.com/XRPLF/rippled.git
synced 2025-11-20 19:15:54 +00:00
Compare commits
1 Commits
ximinez/le
...
ximinez/le
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
518f292c2b |
@@ -13,12 +13,28 @@ class Number;
|
|||||||
std::string
|
std::string
|
||||||
to_string(Number const& amount);
|
to_string(Number const& amount);
|
||||||
|
|
||||||
|
template <class T1, class T2>
|
||||||
|
concept ArithmeticWithNumber =
|
||||||
|
std::is_arithmetic_v<std::remove_reference_t<T1>> &&
|
||||||
|
std::is_convertible_v<T2, Number>;
|
||||||
|
|
||||||
|
template <class T1, class T2>
|
||||||
|
concept OneNumberParam =
|
||||||
|
ArithmeticWithNumber<T1, T2> || ArithmeticWithNumber<T2, T1>;
|
||||||
|
|
||||||
class Number
|
class Number
|
||||||
{
|
{
|
||||||
using rep = std::int64_t;
|
using rep = std::int64_t;
|
||||||
rep mantissa_{0};
|
rep mantissa_{0};
|
||||||
int exponent_{std::numeric_limits<int>::lowest()};
|
int exponent_{std::numeric_limits<int>::lowest()};
|
||||||
|
|
||||||
|
using urep = std::make_unsigned_t<rep>;
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
rep
|
||||||
|
utoi(T mantissa)
|
||||||
|
requires std::is_unsigned_v<T>;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// The range for the mantissa when normalized
|
// The range for the mantissa when normalized
|
||||||
constexpr static std::int64_t minMantissa = 1'000'000'000'000'000LL;
|
constexpr static std::int64_t minMantissa = 1'000'000'000'000'000LL;
|
||||||
@@ -35,7 +51,10 @@ public:
|
|||||||
|
|
||||||
explicit constexpr Number() = default;
|
explicit constexpr Number() = default;
|
||||||
|
|
||||||
Number(rep mantissa);
|
template <class T>
|
||||||
|
explicit Number(T mantissa)
|
||||||
|
requires std::is_unsigned_v<T>;
|
||||||
|
explicit Number(rep mantissa);
|
||||||
explicit Number(rep mantissa, int exponent);
|
explicit Number(rep mantissa, int exponent);
|
||||||
explicit constexpr Number(rep mantissa, int exponent, unchecked) noexcept;
|
explicit constexpr Number(rep mantissa, int exponent, unchecked) noexcept;
|
||||||
|
|
||||||
@@ -59,13 +78,39 @@ public:
|
|||||||
|
|
||||||
Number&
|
Number&
|
||||||
operator+=(Number const& x);
|
operator+=(Number const& x);
|
||||||
|
template <class T>
|
||||||
|
Number&
|
||||||
|
operator+=(T x)
|
||||||
|
{
|
||||||
|
return operator+=(Number(x));
|
||||||
|
}
|
||||||
|
|
||||||
Number&
|
Number&
|
||||||
operator-=(Number const& x);
|
operator-=(Number const& x);
|
||||||
|
template <class T>
|
||||||
|
Number&
|
||||||
|
operator-=(T x)
|
||||||
|
{
|
||||||
|
return operator-=(Number(x));
|
||||||
|
}
|
||||||
|
|
||||||
Number&
|
Number&
|
||||||
operator*=(Number const& x);
|
operator*=(Number const& x);
|
||||||
|
template <class T>
|
||||||
|
Number&
|
||||||
|
operator*=(T x)
|
||||||
|
{
|
||||||
|
return operator*=(Number(x));
|
||||||
|
}
|
||||||
|
|
||||||
Number&
|
Number&
|
||||||
operator/=(Number const& x);
|
operator/=(Number const& x);
|
||||||
|
template <class T>
|
||||||
|
Number&
|
||||||
|
operator/=(T x)
|
||||||
|
{
|
||||||
|
return operator/=(Number(x));
|
||||||
|
}
|
||||||
|
|
||||||
static constexpr Number
|
static constexpr Number
|
||||||
min() noexcept;
|
min() noexcept;
|
||||||
@@ -87,12 +132,26 @@ public:
|
|||||||
{
|
{
|
||||||
return x.mantissa_ == y.mantissa_ && x.exponent_ == y.exponent_;
|
return x.mantissa_ == y.mantissa_ && x.exponent_ == y.exponent_;
|
||||||
}
|
}
|
||||||
|
template <class T1, class T2>
|
||||||
|
friend constexpr bool
|
||||||
|
operator==(T1&& x, T2&& y) noexcept
|
||||||
|
requires OneNumberParam<T1, T2>
|
||||||
|
{
|
||||||
|
return operator==(Number(x), Number(y));
|
||||||
|
}
|
||||||
|
|
||||||
friend constexpr bool
|
friend constexpr bool
|
||||||
operator!=(Number const& x, Number const& y) noexcept
|
operator!=(Number const& x, Number const& y) noexcept
|
||||||
{
|
{
|
||||||
return !(x == y);
|
return !(x == y);
|
||||||
}
|
}
|
||||||
|
template <class T1, class T2>
|
||||||
|
friend constexpr bool
|
||||||
|
operator!=(T1&& x, T2&& y) noexcept
|
||||||
|
requires OneNumberParam<T1, T2>
|
||||||
|
{
|
||||||
|
return operator!=(Number(x), Number(y));
|
||||||
|
}
|
||||||
|
|
||||||
friend constexpr bool
|
friend constexpr bool
|
||||||
operator<(Number const& x, Number const& y) noexcept
|
operator<(Number const& x, Number const& y) noexcept
|
||||||
@@ -123,6 +182,13 @@ public:
|
|||||||
// If equal exponents, compare mantissas
|
// If equal exponents, compare mantissas
|
||||||
return x.mantissa_ < y.mantissa_;
|
return x.mantissa_ < y.mantissa_;
|
||||||
}
|
}
|
||||||
|
template <class T1, class T2>
|
||||||
|
friend constexpr bool
|
||||||
|
operator<(T1&& x, T2&& y) noexcept
|
||||||
|
requires OneNumberParam<T1, T2>
|
||||||
|
{
|
||||||
|
return operator<(Number(x), Number(y));
|
||||||
|
}
|
||||||
|
|
||||||
/** Return the sign of the amount */
|
/** Return the sign of the amount */
|
||||||
constexpr int
|
constexpr int
|
||||||
@@ -154,18 +220,39 @@ public:
|
|||||||
{
|
{
|
||||||
return y < x;
|
return y < x;
|
||||||
}
|
}
|
||||||
|
template <class T1, class T2>
|
||||||
|
friend constexpr bool
|
||||||
|
operator>(T1&& x, T2&& y) noexcept
|
||||||
|
requires OneNumberParam<T1, T2>
|
||||||
|
{
|
||||||
|
return operator>(Number(x), Number(y));
|
||||||
|
}
|
||||||
|
|
||||||
friend constexpr bool
|
friend constexpr bool
|
||||||
operator<=(Number const& x, Number const& y) noexcept
|
operator<=(Number const& x, Number const& y) noexcept
|
||||||
{
|
{
|
||||||
return !(y < x);
|
return !(y < x);
|
||||||
}
|
}
|
||||||
|
template <class T1, class T2>
|
||||||
|
friend constexpr bool
|
||||||
|
operator<=(T1&& x, T2&& y) noexcept
|
||||||
|
requires OneNumberParam<T1, T2>
|
||||||
|
{
|
||||||
|
return operator<=(Number(x), Number(y));
|
||||||
|
}
|
||||||
|
|
||||||
friend constexpr bool
|
friend constexpr bool
|
||||||
operator>=(Number const& x, Number const& y) noexcept
|
operator>=(Number const& x, Number const& y) noexcept
|
||||||
{
|
{
|
||||||
return !(x < y);
|
return !(x < y);
|
||||||
}
|
}
|
||||||
|
template <class T1, class T2>
|
||||||
|
friend constexpr bool
|
||||||
|
operator>=(T1&& x, T2&& y) noexcept
|
||||||
|
requires OneNumberParam<T1, T2>
|
||||||
|
{
|
||||||
|
return operator>=(Number(x), Number(y));
|
||||||
|
}
|
||||||
|
|
||||||
friend std::ostream&
|
friend std::ostream&
|
||||||
operator<<(std::ostream& os, Number const& x)
|
operator<<(std::ostream& os, Number const& x)
|
||||||
@@ -192,6 +279,16 @@ private:
|
|||||||
class Guard;
|
class Guard;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
Number::rep
|
||||||
|
Number::utoi(T mantissa)
|
||||||
|
requires std::is_unsigned_v<T>
|
||||||
|
{
|
||||||
|
if (mantissa > std::numeric_limits<rep>::max())
|
||||||
|
throw std::overflow_error("too high");
|
||||||
|
return static_cast<rep>(mantissa);
|
||||||
|
}
|
||||||
|
|
||||||
inline constexpr Number::Number(rep mantissa, int exponent, unchecked) noexcept
|
inline constexpr Number::Number(rep mantissa, int exponent, unchecked) noexcept
|
||||||
: mantissa_{mantissa}, exponent_{exponent}
|
: mantissa_{mantissa}, exponent_{exponent}
|
||||||
{
|
{
|
||||||
@@ -207,6 +304,13 @@ inline Number::Number(rep mantissa) : Number{mantissa, 0}
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
Number::Number(T mantissa)
|
||||||
|
requires std::is_unsigned_v<T>
|
||||||
|
: Number{utoi(mantissa), 0}
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
inline constexpr Number::rep
|
inline constexpr Number::rep
|
||||||
Number::mantissa() const noexcept
|
Number::mantissa() const noexcept
|
||||||
{
|
{
|
||||||
@@ -277,6 +381,14 @@ operator+(Number const& x, Number const& y)
|
|||||||
return z;
|
return z;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <class T1, class T2>
|
||||||
|
constexpr Number
|
||||||
|
operator+(T1&& x, T2&& y)
|
||||||
|
requires OneNumberParam<T1, T2>
|
||||||
|
{
|
||||||
|
return operator+(Number(x), Number(y));
|
||||||
|
}
|
||||||
|
|
||||||
inline Number
|
inline Number
|
||||||
operator-(Number const& x, Number const& y)
|
operator-(Number const& x, Number const& y)
|
||||||
{
|
{
|
||||||
@@ -285,6 +397,14 @@ operator-(Number const& x, Number const& y)
|
|||||||
return z;
|
return z;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <class T1, class T2>
|
||||||
|
constexpr Number
|
||||||
|
operator-(T1&& x, T2&& y)
|
||||||
|
requires OneNumberParam<T1, T2>
|
||||||
|
{
|
||||||
|
return operator-(Number(x), Number(y));
|
||||||
|
}
|
||||||
|
|
||||||
inline Number
|
inline Number
|
||||||
operator*(Number const& x, Number const& y)
|
operator*(Number const& x, Number const& y)
|
||||||
{
|
{
|
||||||
@@ -293,6 +413,14 @@ operator*(Number const& x, Number const& y)
|
|||||||
return z;
|
return z;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <class T1, class T2>
|
||||||
|
constexpr Number
|
||||||
|
operator*(T1&& x, T2&& y)
|
||||||
|
requires OneNumberParam<T1, T2>
|
||||||
|
{
|
||||||
|
return operator*(Number(x), Number(y));
|
||||||
|
}
|
||||||
|
|
||||||
inline Number
|
inline Number
|
||||||
operator/(Number const& x, Number const& y)
|
operator/(Number const& x, Number const& y)
|
||||||
{
|
{
|
||||||
@@ -301,6 +429,14 @@ operator/(Number const& x, Number const& y)
|
|||||||
return z;
|
return z;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <class T1, class T2>
|
||||||
|
constexpr Number
|
||||||
|
operator/(T1&& x, T2&& y)
|
||||||
|
requires OneNumberParam<T1, T2>
|
||||||
|
{
|
||||||
|
return operator/(Number(x), Number(y));
|
||||||
|
}
|
||||||
|
|
||||||
inline constexpr Number
|
inline constexpr Number
|
||||||
Number::min() noexcept
|
Number::min() noexcept
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -29,7 +29,9 @@ struct Fees
|
|||||||
XRPAmount
|
XRPAmount
|
||||||
accountReserve(std::size_t ownerCount) const
|
accountReserve(std::size_t ownerCount) const
|
||||||
{
|
{
|
||||||
return reserve + ownerCount * increment;
|
auto const p = ownerCount * increment;
|
||||||
|
auto const s = reserve + p;
|
||||||
|
return s;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ public:
|
|||||||
IOUAmount() = default;
|
IOUAmount() = default;
|
||||||
explicit IOUAmount(Number const& other);
|
explicit IOUAmount(Number const& other);
|
||||||
IOUAmount(beast::Zero);
|
IOUAmount(beast::Zero);
|
||||||
IOUAmount(std::int64_t mantissa, int exponent);
|
IOUAmount(std::int64_t mantissa, int exponent = 0);
|
||||||
|
|
||||||
IOUAmount& operator=(beast::Zero);
|
IOUAmount& operator=(beast::Zero);
|
||||||
|
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ public:
|
|||||||
|
|
||||||
operator Number() const noexcept
|
operator Number() const noexcept
|
||||||
{
|
{
|
||||||
return value();
|
return Number{value()};
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Return the sign of the amount */
|
/** Return the sign of the amount */
|
||||||
|
|||||||
@@ -20,7 +20,9 @@ namespace ripple {
|
|||||||
class XRPAmount : private boost::totally_ordered<XRPAmount>,
|
class XRPAmount : private boost::totally_ordered<XRPAmount>,
|
||||||
private boost::additive<XRPAmount>,
|
private boost::additive<XRPAmount>,
|
||||||
private boost::equality_comparable<XRPAmount, std::int64_t>,
|
private boost::equality_comparable<XRPAmount, std::int64_t>,
|
||||||
private boost::additive<XRPAmount, std::int64_t>
|
private boost::equality_comparable<XRPAmount, int>,
|
||||||
|
private boost::additive<XRPAmount, std::int64_t>,
|
||||||
|
private boost::additive<XRPAmount, int>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
using unit_type = unit::dropTag;
|
using unit_type = unit::dropTag;
|
||||||
@@ -68,11 +70,13 @@ public:
|
|||||||
return XRPAmount{drops_ * rhs};
|
return XRPAmount{drops_ * rhs};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
friend constexpr XRPAmount
|
friend constexpr XRPAmount
|
||||||
operator*(value_type lhs, XRPAmount const& rhs)
|
operator*(T lhs, XRPAmount const& rhs)
|
||||||
|
requires std::is_convertible_v<T, value_type>
|
||||||
{
|
{
|
||||||
// multiplication is commutative
|
// multiplication is commutative
|
||||||
return rhs * lhs;
|
return rhs.operator*(lhs);
|
||||||
}
|
}
|
||||||
|
|
||||||
XRPAmount&
|
XRPAmount&
|
||||||
@@ -127,6 +131,12 @@ public:
|
|||||||
{
|
{
|
||||||
return drops_ == other;
|
return drops_ == other;
|
||||||
}
|
}
|
||||||
|
friend bool
|
||||||
|
operator==(value_type lhs, XRPAmount const& rhs)
|
||||||
|
{
|
||||||
|
// multiplication is commutative
|
||||||
|
return rhs.operator==(lhs);
|
||||||
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
operator<(XRPAmount const& other) const
|
operator<(XRPAmount const& other) const
|
||||||
@@ -143,7 +153,7 @@ public:
|
|||||||
|
|
||||||
operator Number() const noexcept
|
operator Number() const noexcept
|
||||||
{
|
{
|
||||||
return drops();
|
return Number{drops()};
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Return the sign of the amount */
|
/** Return the sign of the amount */
|
||||||
|
|||||||
@@ -2884,7 +2884,7 @@ assetsToSharesDeposit(
|
|||||||
Number(assets.mantissa(), assets.exponent() + vault->at(sfScale))
|
Number(assets.mantissa(), assets.exponent() + vault->at(sfScale))
|
||||||
.truncate()};
|
.truncate()};
|
||||||
|
|
||||||
Number const shareTotal = issuance->at(sfOutstandingAmount);
|
Number const shareTotal = Number{issuance->at(sfOutstandingAmount)};
|
||||||
shares = ((shareTotal * assets) / assetTotal).truncate();
|
shares = ((shareTotal * assets) / assetTotal).truncate();
|
||||||
return shares;
|
return shares;
|
||||||
}
|
}
|
||||||
@@ -2913,7 +2913,7 @@ sharesToAssetsDeposit(
|
|||||||
shares.exponent() - vault->at(sfScale),
|
shares.exponent() - vault->at(sfScale),
|
||||||
false};
|
false};
|
||||||
|
|
||||||
Number const shareTotal = issuance->at(sfOutstandingAmount);
|
Number const shareTotal{issuance->at(sfOutstandingAmount)};
|
||||||
assets = (assetTotal * shares) / shareTotal;
|
assets = (assetTotal * shares) / shareTotal;
|
||||||
return assets;
|
return assets;
|
||||||
}
|
}
|
||||||
@@ -2939,7 +2939,7 @@ assetsToSharesWithdraw(
|
|||||||
STAmount shares{vault->at(sfShareMPTID)};
|
STAmount shares{vault->at(sfShareMPTID)};
|
||||||
if (assetTotal == 0)
|
if (assetTotal == 0)
|
||||||
return shares;
|
return shares;
|
||||||
Number const shareTotal = issuance->at(sfOutstandingAmount);
|
Number const shareTotal{issuance->at(sfOutstandingAmount)};
|
||||||
Number result = (shareTotal * assets) / assetTotal;
|
Number result = (shareTotal * assets) / assetTotal;
|
||||||
if (truncate == TruncateShares::yes)
|
if (truncate == TruncateShares::yes)
|
||||||
result = result.truncate();
|
result = result.truncate();
|
||||||
@@ -2967,7 +2967,7 @@ sharesToAssetsWithdraw(
|
|||||||
STAmount assets{vault->at(sfAsset)};
|
STAmount assets{vault->at(sfAsset)};
|
||||||
if (assetTotal == 0)
|
if (assetTotal == 0)
|
||||||
return assets;
|
return assets;
|
||||||
Number const shareTotal = issuance->at(sfOutstandingAmount);
|
Number const shareTotal{issuance->at(sfOutstandingAmount)};
|
||||||
assets = (assetTotal * shares) / shareTotal;
|
assets = (assetTotal * shares) / shareTotal;
|
||||||
return assets;
|
return assets;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,6 +16,12 @@ QualityFunction::QualityFunction(
|
|||||||
{
|
{
|
||||||
if (quality.rate() <= beast::zero)
|
if (quality.rate() <= beast::zero)
|
||||||
Throw<std::runtime_error>("QualityFunction quality rate is 0.");
|
Throw<std::runtime_error>("QualityFunction quality rate is 0.");
|
||||||
|
|
||||||
|
static_assert(std::is_arithmetic_v<std::remove_reference_t<int>>);
|
||||||
|
static_assert(std::is_convertible_v<ripple::STAmount, Number>);
|
||||||
|
static_assert(ripple::OneNumberParam<int, ripple::STAmount>);
|
||||||
|
static_assert(!ripple::OneNumberParam<Number, Number>);
|
||||||
|
|
||||||
b_ = 1 / quality.rate();
|
b_ = 1 / quality.rate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -142,6 +142,34 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
template <class T1, class T2>
|
||||||
|
concept STAmountParams =
|
||||||
|
std::is_convertible_v<T1, STAmount> && std::is_convertible_v<T2, STAmount>;
|
||||||
|
|
||||||
|
template <class T1, class T2>
|
||||||
|
STAmount
|
||||||
|
operator-(T2&& lhs, T1&& rhs)
|
||||||
|
requires STAmountParams<T1, T2>
|
||||||
|
{
|
||||||
|
return STAmount(lhs) - STAmount(rhs);
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
STAmount
|
||||||
|
operator-(PrettyAmount&& lhs, STAmount const& rhs)
|
||||||
|
{
|
||||||
|
return STAmount(lhs) - rhs;
|
||||||
|
}
|
||||||
|
|
||||||
|
STAmount
|
||||||
|
operator-(STAmount const& lhs, PrettyAmount&& rhs)
|
||||||
|
{
|
||||||
|
return lhs - STAmount(rhs);
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
inline bool
|
inline bool
|
||||||
operator==(PrettyAmount const& lhs, PrettyAmount const& rhs)
|
operator==(PrettyAmount const& lhs, PrettyAmount const& rhs)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -370,6 +370,7 @@ public:
|
|||||||
env(pay(alice, bob, USD(1)), sendmax(USD(10)));
|
env(pay(alice, bob, USD(1)), sendmax(USD(10)));
|
||||||
env.close();
|
env.close();
|
||||||
|
|
||||||
|
auto const ten = USD(10);
|
||||||
env.require(balance(alice, USD(10) - amountWithRate));
|
env.require(balance(alice, USD(10) - amountWithRate));
|
||||||
env.require(balance(bob, USD(1)));
|
env.require(balance(bob, USD(1)));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -731,6 +731,7 @@ class Simulate_test : public beast::unit_test::suite
|
|||||||
{
|
{
|
||||||
auto validateOutput = [&](Json::Value const& resp,
|
auto validateOutput = [&](Json::Value const& resp,
|
||||||
Json::Value const& tx) {
|
Json::Value const& tx) {
|
||||||
|
static_assert(ArithmeticWithNumber<XRPAmount, int>);
|
||||||
auto result = resp[jss::result];
|
auto result = resp[jss::result];
|
||||||
checkBasicReturnValidity(
|
checkBasicReturnValidity(
|
||||||
result,
|
result,
|
||||||
|
|||||||
Reference in New Issue
Block a user