xrpld
Loading...
Searching...
No Matches
XRPAmount.h
1#pragma once
2
3#include <xrpl/basics/Number.h>
4#include <xrpl/basics/contract.h>
5#include <xrpl/beast/utility/Zero.h>
6#include <xrpl/json/json_forwards.h>
7#include <xrpl/json/json_value.h>
8#include <xrpl/protocol/Units.h>
9
10#include <boost/multiprecision/cpp_int.hpp>
11#include <boost/operators.hpp>
12
13#include <cstdint>
14#include <istream>
15#include <limits>
16#include <optional>
17#include <ostream>
18#include <stdexcept>
19#include <string>
20#include <type_traits>
21
22namespace xrpl {
23
24class XRPAmount : private boost::totally_ordered<XRPAmount>,
25 private boost::additive<XRPAmount>,
26 private boost::equality_comparable<XRPAmount, std::int64_t>,
27 private boost::additive<XRPAmount, std::int64_t>
28{
29public:
30 using unit_type = unit::dropTag;
32
33private:
35
36public:
37 XRPAmount() = default;
38 constexpr XRPAmount(XRPAmount const& other) = default;
39 constexpr XRPAmount&
40 operator=(XRPAmount const& other) = default;
41
42 // Round to nearest, even on tie.
43 explicit XRPAmount(Number const& x) : XRPAmount(static_cast<value_type>(x))
44 {
45 }
46
48 {
49 }
50
51 constexpr XRPAmount&
53 {
54 drops_ = 0;
55 return *this;
56 }
57
58 constexpr explicit XRPAmount(value_type drops) : drops_(drops)
59 {
60 }
61
64 {
65 drops_ = drops;
66 return *this;
67 }
68
69 constexpr XRPAmount
70 operator*(value_type const& rhs) const
71 {
72 return XRPAmount{drops_ * rhs};
73 }
74
75 friend constexpr XRPAmount
77 {
78 // multiplication is commutative
79 return rhs * lhs;
80 }
81
83 operator+=(XRPAmount const& other)
84 {
85 drops_ += other.drops();
86 return *this;
87 }
88
90 operator-=(XRPAmount const& other)
91 {
92 drops_ -= other.drops();
93 return *this;
94 }
95
98 {
99 drops_ += rhs;
100 return *this;
101 }
102
103 XRPAmount&
105 {
106 drops_ -= rhs;
107 return *this;
108 }
109
110 XRPAmount&
112 {
113 drops_ *= rhs;
114 return *this;
115 }
116
118 operator-() const
119 {
120 return XRPAmount{-drops_};
121 }
122
123 bool
124 operator==(XRPAmount const& other) const
125 {
126 return drops_ == other.drops_;
127 }
128
129 bool
131 {
132 return drops_ == other;
133 }
134
135 bool
136 operator<(XRPAmount const& other) const
137 {
138 return drops_ < other.drops_;
139 }
140
144 explicit constexpr
145 operator bool() const noexcept
146 {
147 return drops_ != 0;
148 }
149
150 operator Number() const noexcept
151 {
152 return drops();
153 }
154
158 [[nodiscard]] constexpr int
159 signum() const noexcept
160 {
161 if (drops_ < 0)
162 return -1;
163 return (drops_ != 0) ? 1 : 0;
164 }
165
169 [[nodiscard]] constexpr value_type
170 drops() const
171 {
172 return drops_;
173 }
174
175 [[nodiscard]] constexpr double
176 decimalXRP() const;
177
178 template <class Dest>
179 [[nodiscard]] std::optional<Dest>
180 dropsAs() const
181 {
185 {
186 return std::nullopt;
187 }
188 return static_cast<Dest>(drops_);
189 }
190
191 template <class Dest>
192 Dest
193 dropsAs(Dest defaultValue) const
194 {
195 return dropsAs<Dest>().value_or(defaultValue);
196 }
197
198 template <class Dest>
199 [[nodiscard]] Dest
200 dropsAs(XRPAmount defaultValue) const
201 {
202 return dropsAs<Dest>().value_or(defaultValue.drops());
203 }
204
205 /* Clips a 64-bit value to a 32-bit JSON number. It is only used
206 * in contexts that don't expect the value to ever approach
207 * the 32-bit limits (i.e. fees and reserves).
208 */
209 [[nodiscard]] json::Value
211 {
212 static_assert(
214 "Expected XRPAmount to be a signed integral type");
215
216 constexpr auto kMin = std::numeric_limits<json::Int>::min();
217 constexpr auto kMax = std::numeric_limits<json::Int>::max();
218
219 if (drops_ < kMin)
220 return kMin;
221 if (drops_ > kMax)
222 return kMax;
223 return static_cast<json::Int>(drops_);
224 }
225
231 [[nodiscard]] constexpr value_type
232 value() const
233 {
234 return drops_;
235 }
236
237 friend std::istream&
239 {
240 s >> val.drops_;
241 return s;
242 }
243
244 static XRPAmount
246 {
247 return XRPAmount{1};
248 }
249};
250
254constexpr XRPAmount kDropsPerXrp{1'000'000};
255
256constexpr double
258{
259 return static_cast<double>(drops_) / kDropsPerXrp.drops();
260}
261
262// Output XRPAmount as just the drops value.
263template <class Char, class Traits>
266{
267 return os << q.drops();
268}
269
270inline std::string
271to_string(XRPAmount const& amount)
272{
273 return std::to_string(amount.drops());
274}
275
276inline XRPAmount
277mulRatio(XRPAmount const& amt, std::uint32_t num, std::uint32_t den, bool roundUp)
278{
279 using namespace boost::multiprecision;
280
281 if (den == 0u)
282 Throw<std::runtime_error>("division by zero");
283
284 int128_t const amt128(amt.drops());
285 auto const neg = amt.drops() < 0;
286 auto const m = amt128 * num;
287 auto r = m / den;
288 if (m % den)
289 {
290 if (!neg && roundUp)
291 r += 1;
292 if (neg && !roundUp)
293 r -= 1;
294 }
296 Throw<std::overflow_error>("XRP mulRatio overflow");
297 return XRPAmount(r.convert_to<XRPAmount::value_type>());
298}
299
300} // namespace xrpl
Represents a JSON value.
Definition json_value.h:117
Number is a floating point type that can represent a wide range of values.
Definition Number.h:351
json::Value jsonClipped() const
Definition XRPAmount.h:210
static XRPAmount minPositiveAmount()
Definition XRPAmount.h:245
XRPAmount & operator-=(XRPAmount const &other)
Definition XRPAmount.h:90
XRPAmount & operator-=(value_type const &rhs)
Definition XRPAmount.h:104
constexpr XRPAmount(beast::Zero)
Definition XRPAmount.h:47
XRPAmount & operator+=(value_type const &rhs)
Definition XRPAmount.h:97
bool operator<(XRPAmount const &other) const
Definition XRPAmount.h:136
XRPAmount()=default
constexpr XRPAmount(value_type drops)
Definition XRPAmount.h:58
constexpr value_type value() const
Returns the underlying value.
Definition XRPAmount.h:232
friend std::istream & operator>>(std::istream &s, XRPAmount &val)
Definition XRPAmount.h:238
Dest dropsAs(XRPAmount defaultValue) const
Definition XRPAmount.h:200
constexpr value_type drops() const
Returns the number of drops.
Definition XRPAmount.h:170
std::int64_t value_type
Definition XRPAmount.h:31
value_type drops_
Definition XRPAmount.h:34
constexpr XRPAmount(XRPAmount const &other)=default
XRPAmount(Number const &x)
Definition XRPAmount.h:43
constexpr XRPAmount operator*(value_type const &rhs) const
Definition XRPAmount.h:70
bool operator==(XRPAmount const &other) const
Definition XRPAmount.h:124
bool operator==(value_type other) const
Definition XRPAmount.h:130
XRPAmount & operator+=(XRPAmount const &other)
Definition XRPAmount.h:83
unit::dropTag unit_type
Definition XRPAmount.h:30
constexpr XRPAmount & operator=(XRPAmount const &other)=default
Dest dropsAs(Dest defaultValue) const
Definition XRPAmount.h:193
XRPAmount & operator*=(value_type const &rhs)
Definition XRPAmount.h:111
constexpr XRPAmount & operator=(beast::Zero)
Definition XRPAmount.h:52
XRPAmount operator-() const
Definition XRPAmount.h:118
std::optional< Dest > dropsAs() const
Definition XRPAmount.h:180
friend constexpr XRPAmount operator*(value_type lhs, XRPAmount const &rhs)
Definition XRPAmount.h:76
constexpr double decimalXRP() const
Definition XRPAmount.h:257
XRPAmount & operator=(value_type drops)
Definition XRPAmount.h:63
constexpr int signum() const noexcept
Return the sign of the amount.
Definition XRPAmount.h:159
T is_integral_v
T is_signed_v
T lowest(T... args)
T max(T... args)
T min(T... args)
int Int
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition algorithm.h:5
constexpr XRPAmount kDropsPerXrp
Number of drops per 1 XRP.
Definition XRPAmount.h:254
std::ostream & operator<<(std::ostream &out, BaseUInt< Bits, Tag > const &u)
Definition base_uint.h:666
std::string to_string(BaseUInt< Bits, Tag > const &a)
Definition base_uint.h:651
IOUAmount mulRatio(IOUAmount const &amt, std::uint32_t num, std::uint32_t den, bool roundUp)
XRPL_NO_SANITIZE_ADDRESS void Throw(Args &&... args)
Definition contract.h:52
Zero allows classes to offer efficient comparisons to zero.
Definition Zero.h:26
T to_string(T... args)