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