1#ifndef XRPL_PROTOCOL_QUALITY_H_INCLUDED
2#define XRPL_PROTOCOL_QUALITY_H_INCLUDED
4#include <xrpl/protocol/AmountConversions.h>
5#include <xrpl/protocol/IOUAmount.h>
6#include <xrpl/protocol/STAmount.h>
7#include <xrpl/protocol/XRPAmount.h>
24template <
class In,
class Out>
33 TAmounts(In
const& in_, Out
const& out_) :
in(in_),
out(out_)
39 empty() const noexcept
41 return in <= beast::zero ||
out <= beast::zero;
45 operator+=(TAmounts
const& rhs)
53 operator-=(TAmounts
const& rhs)
64using Amounts = TAmounts<STAmount, STAmount>;
66template <
class In,
class Out>
68operator==(TAmounts<In, Out>
const& lhs, TAmounts<In, Out>
const& rhs)
noexcept
70 return lhs.in == rhs.in && lhs.out == rhs.out;
73template <
class In,
class Out>
75operator!=(TAmounts<In, Out>
const& lhs, TAmounts<In, Out>
const& rhs)
noexcept
83#define QUALITY_ONE 1'000'000'000
97 static int const minTickSize = 3;
98 static int const maxTickSize = 16;
114 explicit Quality(Amounts
const& amount);
117 template <
class In,
class Out>
118 explicit Quality(TAmounts<In, Out>
const& amount)
124 template <
class In,
class Out>
125 Quality(Out
const& out, In
const& in)
159 round(
int tickSize)
const;
165 [[nodiscard]] Amounts
166 ceil_in(Amounts
const& amount, STAmount
const& limit)
const;
168 template <
class In,
class Out>
169 [[nodiscard]] TAmounts<In, Out>
170 ceil_in(TAmounts<In, Out>
const& amount, In
const& limit)
const;
175 [[nodiscard]] Amounts
176 ceil_in_strict(Amounts
const& amount, STAmount
const& limit,
bool roundUp)
179 template <
class In,
class Out>
180 [[nodiscard]] TAmounts<In, Out>
182 TAmounts<In, Out>
const& amount,
190 [[nodiscard]] Amounts
191 ceil_out(Amounts
const& amount, STAmount
const& limit)
const;
193 template <
class In,
class Out>
194 [[nodiscard]] TAmounts<In, Out>
195 ceil_out(TAmounts<In, Out>
const& amount, Out
const& limit)
const;
200 [[nodiscard]] Amounts
201 ceil_out_strict(Amounts
const& amount, STAmount
const& limit,
bool roundUp)
204 template <
class In,
class Out>
205 [[nodiscard]] TAmounts<In, Out>
207 TAmounts<In, Out>
const& amount,
221 [[nodiscard]] TAmounts<In, Out>
222 ceil_TAmounts_helper(
223 TAmounts<In, Out>
const& amount,
225 Lim
const& limit_cmp,
227 Round... round)
const;
235 operator<(Quality
const& lhs, Quality
const& rhs)
noexcept
237 return lhs.m_value > rhs.m_value;
241 operator>(Quality
const& lhs, Quality
const& rhs)
noexcept
243 return lhs.m_value < rhs.m_value;
247 operator<=(Quality
const& lhs, Quality
const& rhs)
noexcept
253 operator>=(Quality
const& lhs, Quality
const& rhs)
noexcept
259 operator==(Quality
const& lhs, Quality
const& rhs)
noexcept
261 return lhs.m_value == rhs.m_value;
265 operator!=(Quality
const& lhs, Quality
const& rhs)
noexcept
267 return !(lhs == rhs);
280 relativeDistance(Quality
const& q1, Quality
const& q2)
283 q1.m_value > 0 && q2.m_value > 0,
284 "ripple::Quality::relativeDistance : minimum inputs");
286 if (q1.m_value == q2.m_value)
289 auto const [minV, maxV] =
std::minmax(q1.m_value, q2.m_value);
292 return rate & ~(255ull << (64 - 8));
295 return static_cast<int>(
rate >> (64 - 8)) - 100;
298 auto const minVMantissa = mantissa(minV);
299 auto const maxVMantissa = mantissa(maxV);
300 auto const expDiff = exponent(maxV) - exponent(minV);
302 double const minVD =
static_cast<double>(minVMantissa);
303 double const maxVD = expDiff ? maxVMantissa *
pow(10, expDiff)
304 : static_cast<double>(maxVMantissa);
309 return (maxVD - minVD) / minVD;
320Quality::ceil_TAmounts_helper(
321 TAmounts<In, Out>
const& amount,
323 Lim
const& limit_cmp,
325 Round... roundUp)
const
327 if (limit_cmp <= limit)
334 Amounts
const stRes = ((*this).*ceil_function)(stAmt, stLim, roundUp...);
335 return TAmounts<In, Out>(toAmount<In>(stRes.in), toAmount<Out>(stRes.out));
338template <
class In,
class Out>
340Quality::ceil_in(TAmounts<In, Out>
const& amount, In
const& limit)
const
343 static constexpr Amounts (Quality::*ceil_in_fn_ptr)(
344 Amounts const&, STAmount const&) const = &Quality::ceil_in;
346 return ceil_TAmounts_helper(amount, limit, amount.in, ceil_in_fn_ptr);
349template <
class In,
class Out>
351Quality::ceil_in_strict(
352 TAmounts<In, Out>
const& amount,
357 static constexpr Amounts (Quality::*ceil_in_fn_ptr)(
358 Amounts const&, STAmount const&, bool) const = &Quality::ceil_in_strict;
360 return ceil_TAmounts_helper(
361 amount, limit, amount.in, ceil_in_fn_ptr, roundUp);
364template <
class In,
class Out>
366Quality::ceil_out(TAmounts<In, Out>
const& amount, Out
const& limit)
const
369 static constexpr Amounts (Quality::*ceil_out_fn_ptr)(
370 Amounts const&, STAmount const&) const = &Quality::ceil_out;
372 return ceil_TAmounts_helper(amount, limit, amount.out, ceil_out_fn_ptr);
375template <
class In,
class Out>
377Quality::ceil_out_strict(
378 TAmounts<In, Out>
const& amount,
383 static constexpr Amounts (Quality::*ceil_out_fn_ptr)(
384 Amounts const&, STAmount const&, bool) const =
385 &Quality::ceil_out_strict;
387 return ceil_TAmounts_helper(
388 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!=(Buffer const &lhs, Buffer const &rhs) noexcept
STAmount toSTAmount(IOUAmount const &iou, Issue const &iss)
STAmount amountFromQuality(std::uint64_t rate)
std::ostream & operator<<(std::ostream &out, base_uint< Bits, Tag > const &u)
Quality composed_quality(Quality const &lhs, Quality const &rhs)
bool operator<(Slice const &lhs, Slice const &rhs) noexcept
constexpr bool operator==(base_uint< Bits, Tag > const &lhs, base_uint< Bits, Tag > const &rhs)
Zero allows classes to offer efficient comparisons to zero.