19 #ifndef BASICS_FEES_H_INCLUDED 
   20 #define BASICS_FEES_H_INCLUDED 
   22 #include <ripple/basics/XRPAmount.h> 
   23 #include <boost/multiprecision/cpp_int.hpp> 
   52     std::is_class_v<T> && std::is_object_v<typename T::unit_type> &&
 
   53     std::is_object_v<typename T::value_type>>;
 
   62 template <
class T, 
class = enable_if_unit_t<T>>
 
   64     std::is_same_v<typename T::unit_type, feeunitTag> ||
 
   65     std::is_same_v<typename T::unit_type, feelevelTag> ||
 
   66     std::is_same_v<typename T::unit_type, unitlessTag> ||
 
   67     std::is_same_v<typename T::unit_type, dropTag>;
 
   69 template <
class UnitTag, 
class T>
 
   70 class TaggedFee : 
private boost::totally_ordered<TaggedFee<UnitTag, T>>,
 
   71                   private boost::additive<TaggedFee<UnitTag, T>>,
 
   72                   private boost::equality_comparable<TaggedFee<UnitTag, T>, T>,
 
   73                   private boost::dividable<TaggedFee<UnitTag, T>, T>,
 
   74                   private boost::modable<TaggedFee<UnitTag, T>, T>,
 
   75                   private boost::unit_steppable<TaggedFee<UnitTag, T>>
 
   85     template <
class Other>
 
   87         std::is_arithmetic_v<Other>&& std::is_arithmetic_v<value_type>&&
 
   88             std::is_convertible_v<Other, value_type>;
 
   90     template <
class OtherFee, 
class = enable_if_unit_t<OtherFee>>
 
   92         is_compatible_v<typename OtherFee::value_type>&&
 
   93             std::is_same_v<UnitTag, typename OtherFee::unit_type>;
 
   95     template <
class Other>
 
   99     template <
class OtherFee>
 
  136             is_compatible_v<Other> &&
 
  137             is_safetocasttovalue_v<value_type, Other>>>
 
  204     template <
class transparent = value_type>
 
  216             std::is_signed_v<T>, 
"- operator illegal on unsigned fee types");
 
  226     template <
class Other, 
class = enable_if_compatible_t<Other>>
 
  236         return fee_ == other;
 
  239     template <
class Other, 
class = enable_if_compatible_t<Other>>
 
  253     explicit constexpr 
operator bool() const noexcept
 
  262         return (
fee_ < 0) ? -1 : (
fee_ ? 1 : 0);
 
  272     template <
class Other>
 
  276         return static_cast<double>(
fee_) / reference.
fee();
 
  286         if constexpr (std::is_integral_v<value_type>)
 
  289                 std::is_signed_v<value_type>,
 
  300             return static_cast<jsontype
>(
fee_);
 
  327 template <
class Char, 
class Traits, 
class UnitTag, 
class T>
 
  331     return os << q.
value();
 
  334 template <
class UnitTag, 
class T>
 
  341 template <
class Source, 
class = enable_if_unit_t<Source>>
 
  343     std::is_convertible_v<typename Source::value_type, std::uint64_t>;
 
  345 template <
class Dest, 
class = enable_if_unit_t<Dest>>
 
  347     can_muldiv_source_v<Dest>&&  
 
  348         std::is_convertible_v<std::uint64_t, typename Dest::value_type> &&
 
  357     can_muldiv_source_v<Source1>&& can_muldiv_source_v<Source2>&& std::
 
  358         is_same_v<typename Source1::unit_type, typename Source2::unit_type>;
 
  368     can_muldiv_sources_v<Source1, Source2>&& can_muldiv_dest_v<Dest>;
 
  379     !std::is_same_v<typename Source1::unit_type, typename Dest::unit_type>;
 
  388 template <
class Source1, 
class Source2>
 
  392 template <
class Source1, 
class Source2, 
class Dest>
 
  396 template <
class Source1, 
class Source2, 
class Dest>
 
  411     class = enable_muldiv_t<Source1, Source2, Dest>>
 
  416     if (value.value() < 0 || mul.value() < 0 || div.value() < 0)
 
  420         assert(value.value() >= 0);
 
  421         assert(mul.value() >= 0);
 
  422         assert(div.value() >= 0);
 
  423         return {
false, Dest{0}};
 
  426     using desttype = 
typename Dest::value_type;
 
  432     if (mul.value() == div.value())
 
  434         if (value.value() > max)
 
  435             return {
false, Dest{max}};
 
  436         return {
true, Dest{
static_cast<desttype
>(value.value())}};
 
  439     using namespace boost::multiprecision;
 
  447     auto quotient = product / div.value();
 
  450         return {
false, Dest{max}};
 
  452     return {
true, Dest{
static_cast<desttype
>(quotient)}};
 
  468 mulDiv(Source1 value, Dest mul, Source2 div)
 
  477     class = feeunit::enable_muldiv_commute_t<Source1, Source2, Dest>>
 
  479 mulDiv(Dest value, Source1 mul, Source2 div)
 
  485 template <
class Dest, 
class = feeunit::enable_muldiv_dest_t<Dest>>
 
  494 template <
class Dest, 
class = feeunit::enable_muldiv_dest_t<Dest>>
 
  499     return mulDiv(mul, value, div);
 
  505     class = feeunit::enable_muldiv_sources_t<Source1, Source2>>
 
  512     return {unitresult.first, unitresult.second.value()};
 
  518     class = feeunit::enable_muldiv_sources_t<Source1, Source2>>
 
  523     return mulDiv(mul, value, div);
 
  526 template <
class Dest, 
class Src>
 
  528     std::is_same_v<typename Dest::unit_type, typename Src::unit_type> &&
 
  529         std::is_integral_v<typename Dest::value_type> &&
 
  530         std::is_integral_v<typename Src::value_type>,
 
  535     return Dest{safe_cast<typename Dest::value_type>(s.value())};
 
  538 template <
class Dest, 
class Src>
 
  540     std::is_same_v<typename Dest::unit_type, typename Src::unit_type> &&
 
  541         std::is_integral_v<typename Dest::value_type> &&
 
  542         std::is_integral_v<typename Src::value_type>,
 
  547     return Dest{unsafe_cast<typename Dest::value_type>(s.value())};
 
  552 #endif  // BASICS_FEES_H_INCLUDED