mirror of
https://github.com/XRPLF/rippled.git
synced 2025-12-01 16:35:53 +00:00
Reduce STAmount public interface (RIPD-867):
The STAmount class includes a number of functions which serve as thin wrappers, which are unused or used only in one place, or which break encapsulation by exposing internal implemenation details. Removing such functions simplifies the interface of the class and ensures consistency. * getSNValue and getNValue are now free functions * canonicalizeRound is no longer exposed * Removed addRound and subRound * Removed overloads of multiply, mulRound, divide and divRound
This commit is contained in:
@@ -41,6 +41,34 @@ STAmount const saZero (noIssue(), 0u);
|
||||
STAmount const saOne (noIssue(), 1u);
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
static
|
||||
std::int64_t
|
||||
getSNValue (STAmount const& amount)
|
||||
{
|
||||
if (!amount.native ())
|
||||
throw std::runtime_error ("amount is not native!");
|
||||
|
||||
auto ret = static_cast<std::int64_t>(amount.mantissa ());
|
||||
|
||||
assert (static_cast<std::uint64_t>(ret) == amount.mantissa ());
|
||||
|
||||
if (amount.negative ())
|
||||
ret = -ret;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
std::uint64_t
|
||||
getNValue (STAmount const& amount)
|
||||
{
|
||||
if (!amount.native ())
|
||||
throw std::runtime_error ("amount is not native!");
|
||||
|
||||
if (amount.negative ())
|
||||
throw std::runtime_error ("amount is negative!");
|
||||
|
||||
return amount.mantissa ();
|
||||
}
|
||||
|
||||
STAmount::STAmount(SerialIter& sit, SField const& name)
|
||||
: STBase(name)
|
||||
@@ -83,7 +111,7 @@ STAmount::STAmount(SerialIter& sit, SField const& name)
|
||||
throw std::runtime_error ("invalid native account");
|
||||
|
||||
// 10 bits for the offset, sign and "not native" flag
|
||||
int offset = static_cast<int> (value >> (64 - 10));
|
||||
int offset = static_cast<int>(value >> (64 - 10));
|
||||
|
||||
value &= ~ (1023ull << (64 - 10));
|
||||
|
||||
@@ -223,8 +251,8 @@ STAmount
|
||||
STAmount::createFromInt64 (SField const& name, std::int64_t value)
|
||||
{
|
||||
return value >= 0
|
||||
? STAmount (name, static_cast<std::uint64_t> (value), false)
|
||||
: STAmount (name, static_cast<std::uint64_t> (-value), true);
|
||||
? STAmount (name, static_cast<std::uint64_t>(value), false)
|
||||
: STAmount (name, static_cast<std::uint64_t>(-value), true);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
@@ -262,41 +290,6 @@ STAmount& STAmount::operator-= (STAmount const& a)
|
||||
return *this;
|
||||
}
|
||||
|
||||
STAmount& STAmount::operator+= (std::uint64_t v)
|
||||
{
|
||||
assert (mIsNative);
|
||||
if (!mIsNative)
|
||||
throw std::runtime_error ("not native");
|
||||
// VFALCO TODO The cast looks dangerous, is it needed?
|
||||
setSNValue (getSNValue () + static_cast<std::int64_t> (v));
|
||||
return *this;
|
||||
}
|
||||
|
||||
STAmount& STAmount::operator-= (std::uint64_t v)
|
||||
{
|
||||
assert (mIsNative);
|
||||
|
||||
if (!mIsNative)
|
||||
throw std::runtime_error ("not native");
|
||||
|
||||
// VFALCO TODO The cast looks dangerous, is it needed?
|
||||
setSNValue (getSNValue () - static_cast<std::int64_t> (v));
|
||||
return *this;
|
||||
}
|
||||
|
||||
STAmount& STAmount::operator= (std::uint64_t v)
|
||||
{
|
||||
// Does not copy name, does not change currency type.
|
||||
mOffset = 0;
|
||||
mValue = v;
|
||||
mIsNegative = false;
|
||||
if (!mIsNative)
|
||||
canonicalize ();
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
|
||||
STAmount operator+ (STAmount const& v1, STAmount const& v2)
|
||||
{
|
||||
v1.throwComparable (v2);
|
||||
@@ -312,11 +305,11 @@ STAmount operator+ (STAmount const& v1, STAmount const& v2)
|
||||
}
|
||||
|
||||
if (v1.mIsNative)
|
||||
return STAmount (v1.getFName (), v1.getSNValue () + v2.getSNValue ());
|
||||
return STAmount (v1.getFName (), getSNValue (v1) + getSNValue (v2));
|
||||
|
||||
int ov1 = v1.mOffset, ov2 = v2.mOffset;
|
||||
std::int64_t vv1 = static_cast<std::int64_t> (v1.mValue);
|
||||
std::int64_t vv2 = static_cast<std::int64_t> (v2.mValue);
|
||||
std::int64_t vv1 = static_cast<std::int64_t>(v1.mValue);
|
||||
std::int64_t vv2 = static_cast<std::int64_t>(v2.mValue);
|
||||
|
||||
if (v1.mIsNegative)
|
||||
vv1 = -vv1;
|
||||
@@ -360,12 +353,12 @@ STAmount operator- (STAmount const& v1, STAmount const& v2)
|
||||
// XXX This could be better, check for overflow and that maximum range
|
||||
// is covered.
|
||||
return STAmount::createFromInt64 (
|
||||
v1.getFName (), v1.getSNValue () - v2.getSNValue ());
|
||||
v1.getFName (), getSNValue (v1) - getSNValue (v2));
|
||||
}
|
||||
|
||||
int ov1 = v1.mOffset, ov2 = v2.mOffset;
|
||||
auto vv1 = static_cast<std::int64_t> (v1.mValue);
|
||||
auto vv2 = static_cast<std::int64_t> (v2.mValue);
|
||||
auto vv1 = static_cast<std::int64_t>(v1.mValue);
|
||||
auto vv2 = static_cast<std::int64_t>(v2.mValue);
|
||||
|
||||
if (v1.mIsNegative)
|
||||
vv1 = -vv1;
|
||||
@@ -488,27 +481,6 @@ STAmount::setIssue (Issue const& issue)
|
||||
mIsNative = isXRP (*this);
|
||||
}
|
||||
|
||||
std::uint64_t
|
||||
STAmount::getNValue () const
|
||||
{
|
||||
if (!mIsNative)
|
||||
throw std::runtime_error ("not native");
|
||||
return mValue;
|
||||
}
|
||||
|
||||
std::int64_t
|
||||
STAmount::getSNValue () const
|
||||
{
|
||||
// signed native value
|
||||
if (!mIsNative)
|
||||
throw std::runtime_error ("not native");
|
||||
|
||||
if (mIsNegative)
|
||||
return - static_cast<std::int64_t> (mValue);
|
||||
|
||||
return static_cast<std::int64_t> (mValue);
|
||||
}
|
||||
|
||||
std::string STAmount::getHumanCurrency () const
|
||||
{
|
||||
return to_string (mIssue.currency);
|
||||
@@ -522,12 +494,12 @@ STAmount::setSNValue (std::int64_t v)
|
||||
if (v > 0)
|
||||
{
|
||||
mIsNegative = false;
|
||||
mValue = static_cast<std::uint64_t> (v);
|
||||
mValue = static_cast<std::uint64_t>(v);
|
||||
}
|
||||
else
|
||||
{
|
||||
mIsNegative = true;
|
||||
mValue = static_cast<std::uint64_t> (-v);
|
||||
mValue = static_cast<std::uint64_t>(-v);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -591,14 +563,12 @@ void STAmount::roundSelf ()
|
||||
if (valueDigits == 1)
|
||||
{
|
||||
mValue -= 1;
|
||||
|
||||
if (mValue < cMinValue)
|
||||
canonicalize ();
|
||||
}
|
||||
else if (valueDigits == 999999999ull)
|
||||
{
|
||||
mValue += 1;
|
||||
|
||||
if (mValue > cMaxValue)
|
||||
canonicalize ();
|
||||
}
|
||||
@@ -748,9 +718,9 @@ STAmount::add (Serializer& s) const
|
||||
if (*this == zero)
|
||||
s.add64 (cNotNative);
|
||||
else if (mIsNegative) // 512 = not native
|
||||
s.add64 (mValue | (static_cast<std::uint64_t> (mOffset + 512 + 97) << (64 - 10)));
|
||||
s.add64 (mValue | (static_cast<std::uint64_t>(mOffset + 512 + 97) << (64 - 10)));
|
||||
else // 256 = positive
|
||||
s.add64 (mValue | (static_cast<std::uint64_t> (mOffset + 512 + 256 + 97) << (64 - 10)));
|
||||
s.add64 (mValue | (static_cast<std::uint64_t>(mOffset + 512 + 256 + 97) << (64 - 10)));
|
||||
|
||||
s.add160 (mIssue.currency);
|
||||
s.add160 (mIssue.account);
|
||||
@@ -847,12 +817,12 @@ void STAmount::set (std::int64_t v)
|
||||
if (v < 0)
|
||||
{
|
||||
mIsNegative = true;
|
||||
mValue = static_cast<std::uint64_t> (-v);
|
||||
mValue = static_cast<std::uint64_t>(-v);
|
||||
}
|
||||
else
|
||||
{
|
||||
mIsNegative = false;
|
||||
mValue = static_cast<std::uint64_t> (v);
|
||||
mValue = static_cast<std::uint64_t>(v);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -871,7 +841,7 @@ amountFromQuality (std::uint64_t rate)
|
||||
return STAmount (noIssue());
|
||||
|
||||
std::uint64_t mantissa = rate & ~ (255ull << (64 - 8));
|
||||
int exponent = static_cast<int> (rate >> (64 - 8)) - 100;
|
||||
int exponent = static_cast<int>(rate >> (64 - 8)) - 100;
|
||||
|
||||
return STAmount (noIssue(), mantissa, exponent);
|
||||
}
|
||||
@@ -1092,28 +1062,28 @@ bool
|
||||
operator< (STAmount const& lhs, std::uint64_t rhs)
|
||||
{
|
||||
// VFALCO Why the cast?
|
||||
return lhs.getSNValue() < static_cast <std::int64_t> (rhs);
|
||||
return getSNValue (lhs) < static_cast<std::int64_t>(rhs);
|
||||
}
|
||||
|
||||
bool
|
||||
operator> (STAmount const& lhs, std::uint64_t rhs)
|
||||
{
|
||||
// VFALCO Why the cast?
|
||||
return lhs.getSNValue() > static_cast <std::int64_t> (rhs);
|
||||
return getSNValue (lhs) > static_cast<std::int64_t>(rhs);
|
||||
}
|
||||
|
||||
bool
|
||||
operator<= (STAmount const& lhs, std::uint64_t rhs)
|
||||
{
|
||||
// VFALCO TODO The cast looks dangerous, is it needed?
|
||||
return lhs.getSNValue () <= static_cast <std::int64_t> (rhs);
|
||||
return getSNValue (lhs) <= static_cast<std::int64_t>(rhs);
|
||||
}
|
||||
|
||||
bool
|
||||
operator>= (STAmount const& lhs, std::uint64_t rhs)
|
||||
{
|
||||
// VFALCO TODO The cast looks dangerous, is it needed?
|
||||
return lhs.getSNValue() >= static_cast<std::int64_t> (rhs);
|
||||
return getSNValue (lhs) >= static_cast<std::int64_t>(rhs);
|
||||
}
|
||||
|
||||
STAmount
|
||||
@@ -1121,7 +1091,7 @@ operator+ (STAmount const& lhs, std::uint64_t rhs)
|
||||
{
|
||||
// VFALCO TODO The cast looks dangerous, is it needed?
|
||||
return STAmount (lhs.getFName (),
|
||||
lhs.getSNValue () + static_cast <std::int64_t> (rhs));
|
||||
getSNValue (lhs) + static_cast<std::int64_t>(rhs));
|
||||
}
|
||||
|
||||
STAmount
|
||||
@@ -1129,7 +1099,7 @@ operator- (STAmount const& lhs, std::uint64_t rhs)
|
||||
{
|
||||
// VFALCO TODO The cast looks dangerous, is it needed?
|
||||
return STAmount (lhs.getFName (),
|
||||
lhs.getSNValue () - static_cast <std::int64_t> (rhs));
|
||||
getSNValue (lhs) - static_cast<std::int64_t>(rhs));
|
||||
}
|
||||
|
||||
STAmount
|
||||
@@ -1208,10 +1178,10 @@ multiply (STAmount const& v1, STAmount const& v2, Issue const& issue)
|
||||
|
||||
if (v1.native() && v2.native() && isXRP (issue))
|
||||
{
|
||||
std::uint64_t const minV = v1.getSNValue () < v2.getSNValue ()
|
||||
? v1.getSNValue () : v2.getSNValue ();
|
||||
std::uint64_t const maxV = v1.getSNValue () < v2.getSNValue ()
|
||||
? v2.getSNValue () : v1.getSNValue ();
|
||||
std::uint64_t const minV = getSNValue (v1) < getSNValue (v2)
|
||||
? getSNValue (v1) : getSNValue (v2);
|
||||
std::uint64_t const maxV = getSNValue (v1) < getSNValue (v2)
|
||||
? getSNValue (v2) : getSNValue (v1);
|
||||
|
||||
if (minV > 3000000000ull) // sqrt(cMaxNative)
|
||||
throw std::runtime_error ("Native value overflow");
|
||||
@@ -1264,9 +1234,9 @@ multiply (STAmount const& v1, STAmount const& v2, Issue const& issue)
|
||||
offset1 + offset2 + 14, v1.negative() != v2.negative());
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
canonicalizeRound (bool isNative, std::uint64_t& value,
|
||||
int& offset, bool roundUp)
|
||||
canonicalizeRound (bool native, std::uint64_t& value, int& offset, bool roundUp)
|
||||
{
|
||||
if (!roundUp) // canonicalize already rounds down
|
||||
return;
|
||||
@@ -1274,7 +1244,7 @@ canonicalizeRound (bool isNative, std::uint64_t& value,
|
||||
WriteLog (lsTRACE, STAmount)
|
||||
<< "canonicalizeRound< " << value << ":" << offset;
|
||||
|
||||
if (isNative)
|
||||
if (native)
|
||||
{
|
||||
if (offset < 0)
|
||||
{
|
||||
@@ -1309,153 +1279,6 @@ canonicalizeRound (bool isNative, std::uint64_t& value,
|
||||
<< "canonicalizeRound> " << value << ":" << offset;
|
||||
}
|
||||
|
||||
STAmount
|
||||
addRound (STAmount const& v1, STAmount const& v2, bool roundUp)
|
||||
{
|
||||
v1.throwComparable (v2);
|
||||
|
||||
if (v2.mantissa() == 0)
|
||||
return v1;
|
||||
|
||||
if (v1.mantissa() == 0)
|
||||
return STAmount (v1.getFName (), v1.issue(), v2.mantissa(),
|
||||
v2.exponent(), v2.negative());
|
||||
|
||||
if (v1.native())
|
||||
return STAmount (v1.getFName (), v1.getSNValue () + v2.getSNValue ());
|
||||
|
||||
int ov1 = v1.exponent(), ov2 = v2.exponent();
|
||||
auto vv1 = static_cast<std::int64_t> (v1.mantissa());
|
||||
auto vv2 = static_cast<std::int64_t> (v2.mantissa());
|
||||
|
||||
if (v1.negative())
|
||||
vv1 = -vv1;
|
||||
|
||||
if (v2.negative())
|
||||
vv2 = -vv2;
|
||||
|
||||
if (ov1 < ov2)
|
||||
{
|
||||
while (ov1 < (ov2 - 1))
|
||||
{
|
||||
vv1 /= 10;
|
||||
++ov1;
|
||||
}
|
||||
|
||||
if (roundUp)
|
||||
vv1 += 9;
|
||||
|
||||
vv1 /= 10;
|
||||
++ov1;
|
||||
}
|
||||
|
||||
if (ov2 < ov1)
|
||||
{
|
||||
while (ov2 < (ov1 - 1))
|
||||
{
|
||||
vv2 /= 10;
|
||||
++ov2;
|
||||
}
|
||||
|
||||
if (roundUp)
|
||||
vv2 += 9;
|
||||
|
||||
vv2 /= 10;
|
||||
++ov2;
|
||||
}
|
||||
|
||||
std::int64_t fv = vv1 + vv2;
|
||||
|
||||
if ((fv >= -10) && (fv <= 10))
|
||||
return STAmount (v1.getFName (), v1.issue());
|
||||
else if (fv >= 0)
|
||||
{
|
||||
std::uint64_t v = static_cast<std::uint64_t> (fv);
|
||||
canonicalizeRound (false, v, ov1, roundUp);
|
||||
return STAmount (v1.getFName (), v1.issue(), v, ov1, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::uint64_t v = static_cast<std::uint64_t> (-fv);
|
||||
canonicalizeRound (false, v, ov1, !roundUp);
|
||||
return STAmount (v1.getFName (), v1.issue(), v, ov1, true);
|
||||
}
|
||||
}
|
||||
|
||||
STAmount
|
||||
subRound (STAmount const& v1, STAmount const& v2, bool roundUp)
|
||||
{
|
||||
v1.throwComparable (v2);
|
||||
|
||||
if (v2.mantissa() == 0)
|
||||
return v1;
|
||||
|
||||
if (v1.mantissa() == 0)
|
||||
return STAmount (v1.getFName (), v1.issue(), v2.mantissa(),
|
||||
v2.exponent(), !v2.negative());
|
||||
|
||||
if (v1.native())
|
||||
return STAmount (v1.getFName (), v1.getSNValue () - v2.getSNValue ());
|
||||
|
||||
int ov1 = v1.exponent(), ov2 = v2.exponent();
|
||||
auto vv1 = static_cast<std::int64_t> (v1.mantissa());
|
||||
auto vv2 = static_cast<std::int64_t> (v2.mantissa());
|
||||
|
||||
if (v1.negative())
|
||||
vv1 = -vv1;
|
||||
|
||||
if (!v2.negative())
|
||||
vv2 = -vv2;
|
||||
|
||||
if (ov1 < ov2)
|
||||
{
|
||||
while (ov1 < (ov2 - 1))
|
||||
{
|
||||
vv1 /= 10;
|
||||
++ov1;
|
||||
}
|
||||
|
||||
if (roundUp)
|
||||
vv1 += 9;
|
||||
|
||||
vv1 /= 10;
|
||||
++ov1;
|
||||
}
|
||||
|
||||
if (ov2 < ov1)
|
||||
{
|
||||
while (ov2 < (ov1 - 1))
|
||||
{
|
||||
vv2 /= 10;
|
||||
++ov2;
|
||||
}
|
||||
|
||||
if (roundUp)
|
||||
vv2 += 9;
|
||||
|
||||
vv2 /= 10;
|
||||
++ov2;
|
||||
}
|
||||
|
||||
std::int64_t fv = vv1 + vv2;
|
||||
|
||||
if ((fv >= -10) && (fv <= 10))
|
||||
return STAmount (v1.getFName (), v1.issue());
|
||||
|
||||
if (fv >= 0)
|
||||
{
|
||||
std::uint64_t v = static_cast<std::uint64_t> (fv);
|
||||
canonicalizeRound (false, v, ov1, roundUp);
|
||||
return STAmount (v1.getFName (), v1.issue(), v, ov1, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::uint64_t v = static_cast<std::uint64_t> (-fv);
|
||||
canonicalizeRound (false, v, ov1, !roundUp);
|
||||
return STAmount (v1.getFName (), v1.issue(), v, ov1, true);
|
||||
}
|
||||
}
|
||||
|
||||
STAmount
|
||||
mulRound (STAmount const& v1, STAmount const& v2,
|
||||
Issue const& issue, bool roundUp)
|
||||
@@ -1465,10 +1288,10 @@ mulRound (STAmount const& v1, STAmount const& v2,
|
||||
|
||||
if (v1.native() && v2.native() && isXRP (issue))
|
||||
{
|
||||
std::uint64_t minV = (v1.getSNValue () < v2.getSNValue ()) ?
|
||||
v1.getSNValue () : v2.getSNValue ();
|
||||
std::uint64_t maxV = (v1.getSNValue () < v2.getSNValue ()) ?
|
||||
v2.getSNValue () : v1.getSNValue ();
|
||||
std::uint64_t minV = (getSNValue (v1) < getSNValue (v2)) ?
|
||||
getSNValue (v1) : getSNValue (v2);
|
||||
std::uint64_t maxV = (getSNValue (v1) < getSNValue (v2)) ?
|
||||
getSNValue (v2) : getSNValue (v1);
|
||||
|
||||
if (minV > 3000000000ull) // sqrt(cMaxNative)
|
||||
throw std::runtime_error ("Native value overflow");
|
||||
|
||||
Reference in New Issue
Block a user