20 #ifndef RIPPLE_PROTOCOL_QUALITY_H_INCLUDED
21 #define RIPPLE_PROTOCOL_QUALITY_H_INCLUDED
23 #include <ripple/basics/IOUAmount.h>
24 #include <ripple/basics/XRPAmount.h>
25 #include <ripple/protocol/AmountConversions.h>
26 #include <ripple/protocol/STAmount.h>
43 template <
class In,
class Out>
52 TAmounts(In
const& in_, Out
const& out_) :
in(in_),
out(out_)
58 empty() const noexcept
60 return in <= beast::zero ||
out <= beast::zero;
64 operator+=(TAmounts
const& rhs)
72 operator-=(TAmounts
const& rhs)
83 using Amounts = TAmounts<STAmount, STAmount>;
85 template <
class In,
class Out>
87 operator==(TAmounts<In, Out>
const& lhs, TAmounts<In, Out>
const& rhs) noexcept
89 return lhs.in == rhs.in && lhs.out == rhs.out;
92 template <
class In,
class Out>
94 operator!=(TAmounts<In, Out>
const& lhs, TAmounts<In, Out>
const& rhs) noexcept
102 #define QUALITY_ONE 1'000'000'000
116 static const int minTickSize = 3;
117 static const int maxTickSize = 16;
133 explicit Quality(Amounts
const& amount);
136 template <
class In,
class Out>
137 explicit Quality(TAmounts<In, Out>
const& amount)
143 template <
class In,
class Out>
144 Quality(Out
const& out, In
const& in)
178 round(
int tickSize)
const;
185 ceil_in(Amounts
const& amount, STAmount
const& limit)
const;
187 template <
class In,
class Out>
189 ceil_in(TAmounts<In, Out>
const& amount, In
const& limit)
const
191 if (amount.in <= limit)
198 auto const stRes = ceil_in(stAmt, stLim);
199 return TAmounts<In, Out>(
200 toAmount<In>(stRes.in), toAmount<Out>(stRes.out));
208 ceil_out(Amounts
const& amount, STAmount
const& limit)
const;
210 template <
class In,
class Out>
212 ceil_out(TAmounts<In, Out>
const& amount, Out
const& limit)
const
214 if (amount.out <= limit)
221 auto const stRes = ceil_out(stAmt, stLim);
222 return TAmounts<In, Out>(
223 toAmount<In>(stRes.in), toAmount<Out>(stRes.out));
227 ceil_out_strict(Amounts
const& amount, STAmount
const& limit,
bool roundUp)
230 template <
class In,
class Out>
233 TAmounts<In, Out>
const& amount,
237 if (amount.out <= limit)
244 auto const stRes = ceil_out_strict(stAmt, stLim, roundUp);
245 return TAmounts<In, Out>(
246 toAmount<In>(stRes.in), toAmount<Out>(stRes.out));
254 operator<(Quality
const& lhs, Quality
const& rhs) noexcept
256 return lhs.m_value > rhs.m_value;
260 operator>(Quality
const& lhs, Quality
const& rhs) noexcept
262 return lhs.m_value < rhs.m_value;
266 operator<=(Quality
const& lhs, Quality
const& rhs) noexcept
272 operator>=(Quality
const& lhs, Quality
const& rhs) noexcept
278 operator==(Quality
const& lhs, Quality
const& rhs) noexcept
280 return lhs.m_value == rhs.m_value;
284 operator!=(Quality
const& lhs, Quality
const& rhs) noexcept
286 return !(lhs == rhs);
299 relativeDistance(Quality
const& q1, Quality
const& q2)
301 assert(q1.m_value > 0 && q2.m_value > 0);
303 if (q1.m_value == q2.m_value)
306 auto const [minV, maxV] =
std::minmax(q1.m_value, q2.m_value);
309 return rate & ~(255ull << (64 - 8));
312 return static_cast<int>(
rate >> (64 - 8)) - 100;
315 auto const minVMantissa = mantissa(minV);
316 auto const maxVMantissa = mantissa(maxV);
317 auto const expDiff = exponent(maxV) - exponent(minV);
319 double const minVD =
static_cast<double>(minVMantissa);
320 double const maxVD = expDiff ? maxVMantissa *
pow(10, expDiff)
321 : static_cast<double>(maxVMantissa);
326 return (maxVD - minVD) / minVD;