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:
Nik Bougalis
2015-04-22 18:56:47 -07:00
parent daf4f8fcde
commit 5a7fa8cfa9
18 changed files with 110 additions and 378 deletions

View File

@@ -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");