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