19#ifndef PROTOCOL_UNITS_H_INCLUDED 
   20#define PROTOCOL_UNITS_H_INCLUDED 
   22#include <xrpl/basics/safe_cast.h> 
   23#include <xrpl/beast/utility/Zero.h> 
   24#include <xrpl/beast/utility/instrumentation.h> 
   25#include <xrpl/json/json_value.h> 
   27#include <boost/multiprecision/cpp_int.hpp> 
   28#include <boost/operators.hpp> 
   75template <
class Other, 
class VU>
 
   86template <
class VU1, 
class VU2>
 
   90template <
class UnitTag, 
class T>
 
   91class ValueUnit : 
private boost::totally_ordered<ValueUnit<UnitTag, T>>,
 
   92                  private boost::additive<ValueUnit<UnitTag, T>>,
 
   93                  private boost::equality_comparable<ValueUnit<UnitTag, T>, T>,
 
   94                  private boost::dividable<ValueUnit<UnitTag, T>, T>,
 
   95                  private boost::modable<ValueUnit<UnitTag, T>, T>,
 
   96                  private boost::unit_steppable<ValueUnit<UnitTag, T>>
 
  136    template <Compatible<ValueUnit> Other>
 
  231    template <Integral transparent = value_type>
 
  253    template <Compatible<ValueUnit> Other>
 
  266    template <Compatible<ValueUnit> Other>
 
  281    operator bool() const noexcept
 
 
  301    template <
class Other>
 
  305        return static_cast<double>(
value_) / reference.
value();
 
 
  330            return static_cast<jsontype
>(
value_);
 
 
 
  357template <
class Char, 
class Traits, 
class UnitTag, 
class T>
 
  361    return os << q.value();
 
  364template <
class UnitTag, 
class T>
 
  371template <
class Source>
 
  380template <
class Source2, 
class Source1>
 
  384template <
class Dest, 
class Source1, 
class Source2>
 
  388template <
class Dest, 
class Source1, 
class Source2>
 
  393ValueUnit<unitlessTag, T>
 
  399template <
class Source1, 
class Source2, unit::muldivable<Source1, Source2> Dest>
 
  404    if (value.value() < 0 || mul.value() < 0 || div.value() < 0)
 
  409            value.value() >= 0, 
"ripple::unit::mulDivU : minimum value input");
 
  411            mul.value() >= 0, 
"ripple::unit::mulDivU : minimum mul input");
 
  413            div.value() > 0, 
"ripple::unit::mulDivU : minimum div input");
 
  417    using desttype = 
typename Dest::value_type;
 
  423    if (mul.value() == div.value())
 
  425        if (value.value() > max)
 
  427        return Dest{
static_cast<desttype
>(value.value())};
 
  430    using namespace boost::multiprecision;
 
  438    auto quotient = product / div.value();
 
  443    return Dest{
static_cast<desttype
>(quotient)};
 
 
 
  464template <
class Source1, 
class Source2, unit::muldivable<Source1, Source2> Dest>
 
  466mulDiv(Source1 value, Dest mul, Source2 div)
 
 
  474    unit::muldivCommutable<Source1, Source2> Dest>
 
  476mulDiv(Dest value, Source1 mul, Source2 div)
 
 
  482template <unit::muldivDest Dest>
 
  491template <unit::muldivDest Dest>
 
  496    return mulDiv(mul, value, div);
 
 
  499template <unit::muldivSource Source1, unit::muldivSources<Source1> Source2>
 
  510    return unitresult->value();
 
 
  513template <unit::muldivSource Source1, unit::muldivSources<Source1> Source2>
 
  518    return mulDiv(mul, value, div);
 
 
  521template <unit::IntegralValue Dest, unit::CastableValue<Dest> Src>
 
  526    return Dest{safe_cast<typename Dest::value_type>(s.value())};
 
 
  529template <unit::IntegralValue Dest, unit::Integral Src>
 
  534    return Dest{safe_cast<typename Dest::value_type>(s)};
 
  537template <unit::IntegralValue Dest, unit::CastableValue<Dest> Src>
 
  542    return Dest{unsafe_cast<typename Dest::value_type>(s.value())};
 
 
  545template <unit::IntegralValue Dest, unit::Integral Src>
 
  550    return Dest{unsafe_cast<typename Dest::value_type>(s)};
 
 
constexpr value_type fee() const
Returns the number of drops.
 
friend constexpr ValueUnit operator*(value_type lhs, ValueUnit const &rhs)
 
Json::Value jsonClipped() const
 
constexpr double decimalFromReference(ValueUnit< unit_type, Other > reference) const
 
friend std::istream & operator>>(std::istream &s, ValueUnit &val)
 
constexpr ValueUnit & operator=(beast::Zero)
 
constexpr int signum() const noexcept
Return the sign of the amount.
 
constexpr ValueUnit operator+(value_type const &rhs) const
 
constexpr bool operator!=(ValueUnit< unit_type, Other > const &other) const
 
ValueUnit & operator+=(ValueUnit const &other)
 
ValueUnit & operator-=(ValueUnit const &other)
 
constexpr bool operator<(ValueUnit const &other) const
 
constexpr value_type operator/(ValueUnit const &rhs) const
 
ValueUnit & operator%=(value_type const &rhs)
 
ValueUnit & operator*=(value_type const &rhs)
 
constexpr ValueUnit & operator=(value_type value)
 
constexpr bool operator==(ValueUnit< unit_type, Other > const &other) const
 
constexpr ValueUnit(value_type value)
 
constexpr ValueUnit(ValueUnit< unit_type, Other > const &value)
Instances with the same unit, and a type that is "safe" to convert to this one can be converted impli...
 
constexpr ValueUnit & operator=(ValueUnit const &other)=default
 
constexpr ValueUnit operator*(value_type const &rhs) const
 
constexpr bool operator==(value_type other) const
 
ValueUnit operator-() const
 
constexpr ValueUnit(beast::Zero)
 
ValueUnit & operator/=(value_type const &rhs)
 
constexpr ValueUnit(ValueUnit const &other)=default
 
friend constexpr ValueUnit operator-(value_type lhs, ValueUnit const &rhs)
 
friend constexpr ValueUnit operator+(value_type lhs, ValueUnit const &rhs)
 
constexpr bool operator==(ValueUnit const &other) const
 
constexpr value_type value() const
Returns the underlying value.
 
constexpr ValueUnit operator-(value_type const &rhs) const
 
Usable is checked to ensure that only values with known valid type tags can be used (sometimes transp...
 
std::optional< Dest > mulDivU(Source1 value, Dest mul, Source2 div)
 
ValueUnit< unitlessTag, T > scalar(T value)
 
std::basic_ostream< Char, Traits > & operator<<(std::basic_ostream< Char, Traits > &os, ValueUnit< UnitTag, T > const &q)
 
std::string to_string(ValueUnit< UnitTag, T > const &amount)
 
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
 
constexpr std::enable_if_t< std::is_integral_v< Dest > &&std::is_integral_v< Src >, Dest > safe_cast(Src s) noexcept
 
STAmount multiply(STAmount const &amount, Rate const &rate)
 
std::optional< std::uint64_t > mulDiv(std::uint64_t value, std::uint64_t mul, std::uint64_t div)
Return value*mul/div accurately.
 
constexpr std::enable_if_t< std::is_integral_v< Dest > &&std::is_integral_v< Src >, Dest > unsafe_cast(Src s) noexcept
 
Zero allows classes to offer efficient comparisons to zero.