3#include <xrpl/protocol/AmountConversions.h>
4#include <xrpl/protocol/IOUAmount.h>
5#include <xrpl/protocol/STAmount.h>
6#include <xrpl/protocol/XRPAmount.h>
23template <
class In,
class Out>
32 TAmounts(In
const& in_, Out
const& out_) :
in(in_),
out(out_)
38 empty() const noexcept
40 return in <= beast::zero ||
out <= beast::zero;
44 operator+=(TAmounts
const& rhs)
52 operator-=(TAmounts
const& rhs)
63using Amounts = TAmounts<STAmount, STAmount>;
65template <
class In,
class Out>
67operator==(TAmounts<In, Out>
const& lhs, TAmounts<In, Out>
const& rhs)
noexcept
69 return lhs.in == rhs.in && lhs.out == rhs.out;
72template <
class In,
class Out>
74operator!=(TAmounts<In, Out>
const& lhs, TAmounts<In, Out>
const& rhs)
noexcept
82#define QUALITY_ONE 1'000'000'000
96 static int const minTickSize = 3;
97 static int const maxTickSize = 16;
113 explicit Quality(Amounts
const& amount);
116 template <
class In,
class Out>
122 template <
class In,
class Out>
156 round(
int tickSize)
const;
162 [[nodiscard]] Amounts
163 ceil_in(Amounts
const& amount, STAmount
const& limit)
const;
165 template <
class In,
class Out>
166 [[nodiscard]] TAmounts<In, Out>
167 ceil_in(TAmounts<In, Out>
const& amount, In
const& limit)
const;
172 [[nodiscard]] Amounts
173 ceil_in_strict(Amounts
const& amount, STAmount
const& limit,
bool roundUp)
const;
175 template <
class In,
class Out>
176 [[nodiscard]] TAmounts<In, Out>
177 ceil_in_strict(TAmounts<In, Out>
const& amount, In
const& limit,
bool roundUp)
const;
183 [[nodiscard]] Amounts
184 ceil_out(Amounts
const& amount, STAmount
const& limit)
const;
186 template <
class In,
class Out>
187 [[nodiscard]] TAmounts<In, Out>
188 ceil_out(TAmounts<In, Out>
const& amount, Out
const& limit)
const;
193 [[nodiscard]] Amounts
194 ceil_out_strict(Amounts
const& amount, STAmount
const& limit,
bool roundUp)
const;
196 template <
class In,
class Out>
197 [[nodiscard]] TAmounts<In, Out>
198 ceil_out_strict(TAmounts<In, Out>
const& amount, Out
const& limit,
bool roundUp)
const;
204 template <
class In,
class Out,
class Lim,
typename FnPtr, std::same_as<
bool>... Round>
205 [[nodiscard]] TAmounts<In, Out>
206 ceil_TAmounts_helper(
207 TAmounts<In, Out>
const& amount,
209 Lim
const& limit_cmp,
211 Round... round)
const;
219 operator<(Quality
const& lhs, Quality
const& rhs)
noexcept
221 return lhs.m_value > rhs.m_value;
225 operator>(Quality
const& lhs, Quality
const& rhs)
noexcept
227 return lhs.m_value < rhs.m_value;
231 operator<=(Quality
const& lhs, Quality
const& rhs)
noexcept
237 operator>=(Quality
const& lhs, Quality
const& rhs)
noexcept
243 operator==(Quality
const& lhs, Quality
const& rhs)
noexcept
245 return lhs.m_value == rhs.m_value;
249 operator!=(Quality
const& lhs, Quality
const& rhs)
noexcept
251 return !(lhs == rhs);
264 relativeDistance(Quality
const& q1, Quality
const& q2)
266 XRPL_ASSERT(q1.m_value > 0 && q2.m_value > 0,
"xrpl::Quality::relativeDistance : minimum inputs");
268 if (q1.m_value == q2.m_value)
271 auto const [minV, maxV] =
std::minmax(q1.m_value, q2.m_value);
276 auto const minVMantissa = mantissa(minV);
277 auto const maxVMantissa = mantissa(maxV);
278 auto const expDiff = exponent(maxV) - exponent(minV);
280 double const minVD =
static_cast<double>(minVMantissa);
281 double const maxVD = expDiff ? maxVMantissa *
pow(10, expDiff) : static_cast<double>(maxVMantissa);
286 return (maxVD - minVD) / minVD;
290template <
class In,
class Out,
class Lim,
typename FnPtr, std::same_as<
bool>... Round>
292Quality::ceil_TAmounts_helper(
293 TAmounts<In, Out>
const& amount,
295 Lim
const& limit_cmp,
297 Round... roundUp)
const
299 if (limit_cmp <= limit)
306 Amounts
const stRes = ((*this).*ceil_function)(stAmt, stLim, roundUp...);
307 return TAmounts<In, Out>(toAmount<In>(stRes.in), toAmount<Out>(stRes.out));
310template <
class In,
class Out>
312Quality::ceil_in(TAmounts<In, Out>
const& amount, In
const& limit)
const
315 static constexpr Amounts (Quality::*ceil_in_fn_ptr)(Amounts const&, STAmount const&) const = &Quality::ceil_in;
317 return ceil_TAmounts_helper(amount, limit,
amount.in, ceil_in_fn_ptr);
320template <
class In,
class Out>
322Quality::ceil_in_strict(TAmounts<In, Out>
const& amount, In
const& limit,
bool roundUp)
const
325 static constexpr Amounts (Quality::*ceil_in_fn_ptr)(Amounts const&, STAmount const&, bool) const =
326 &Quality::ceil_in_strict;
328 return ceil_TAmounts_helper(amount, limit,
amount.in, ceil_in_fn_ptr, roundUp);
331template <
class In,
class Out>
333Quality::ceil_out(TAmounts<In, Out>
const& amount, Out
const& limit)
const
336 static constexpr Amounts (Quality::*ceil_out_fn_ptr)(Amounts const&, STAmount const&) const = &Quality::ceil_out;
338 return ceil_TAmounts_helper(amount, limit,
amount.out, ceil_out_fn_ptr);
341template <
class In,
class Out>
343Quality::ceil_out_strict(TAmounts<In, Out>
const& amount, Out
const& limit,
bool roundUp)
const
346 static constexpr Amounts (Quality::*ceil_out_fn_ptr)(Amounts const&, STAmount const&, bool) const =
347 &Quality::ceil_out_strict;
349 return ceil_TAmounts_helper(amount, limit,
amount.out, ceil_out_fn_ptr, roundUp);
Keylet quality(Keylet const &k, std::uint64_t q) noexcept
The initial directory page for a specific quality.
Rate rate(Env &env, Account const &account, std::uint32_t const &seq)
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
bool operator<(Slice const &lhs, Slice const &rhs) noexcept
Quality composed_quality(Quality const &lhs, Quality const &rhs)
STAmount toSTAmount(IOUAmount const &iou, Issue const &iss)
std::ostream & operator<<(std::ostream &out, base_uint< Bits, Tag > const &u)
constexpr bool operator==(base_uint< Bits, Tag > const &lhs, base_uint< Bits, Tag > const &rhs)
STAmount amountFromQuality(std::uint64_t rate)
bool operator!=(Buffer const &lhs, Buffer const &rhs) noexcept
Zero allows classes to offer efficient comparisons to zero.