rippled
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 constexpr int
150 signum() const noexcept
151 {
152 return (drops_ < 0) ? -1 : (drops_ ? 1 : 0);
153 }
154
156 constexpr value_type
157 drops() const
158 {
159 return drops_;
160 }
161
162 constexpr double
163 decimalXRP() const;
164
165 template <class Dest>
167 dropsAs() const
168 {
172 {
173 return std::nullopt;
174 }
175 return static_cast<Dest>(drops_);
176 }
177
178 template <class Dest>
179 Dest
180 dropsAs(Dest defaultValue) const
181 {
182 return dropsAs<Dest>().value_or(defaultValue);
183 }
184
185 template <class Dest>
186 Dest
187 dropsAs(XRPAmount defaultValue) const
188 {
189 return dropsAs<Dest>().value_or(defaultValue.drops());
190 }
191
192 /* Clips a 64-bit value to a 32-bit JSON number. It is only used
193 * in contexts that don't expect the value to ever approach
194 * the 32-bit limits (i.e. fees and reserves).
195 */
198 {
199 static_assert(
201 "Expected XRPAmount to be a signed integral type");
202
203 constexpr auto min = std::numeric_limits<Json::Int>::min();
204 constexpr auto max = std::numeric_limits<Json::Int>::max();
205
206 if (drops_ < min)
207 return min;
208 if (drops_ > max)
209 return max;
210 return static_cast<Json::Int>(drops_);
211 }
212
217 constexpr value_type
218 value() const
219 {
220 return drops_;
221 }
222
223 friend std::istream&
225 {
226 s >> val.drops_;
227 return s;
228 }
229
230 static XRPAmount
232 {
233 return XRPAmount{1};
234 }
235};
236
238constexpr XRPAmount DROPS_PER_XRP{1'000'000};
239
240constexpr double
242{
243 return static_cast<double>(drops_) / DROPS_PER_XRP.drops();
244}
245
246// Output XRPAmount as just the drops value.
247template <class Char, class Traits>
250{
251 return os << q.drops();
252}
253
254inline std::string
255to_string(XRPAmount const& amount)
256{
257 return std::to_string(amount.drops());
258}
259
260inline XRPAmount
261mulRatio(XRPAmount const& amt, std::uint32_t num, std::uint32_t den, bool roundUp)
262{
263 using namespace boost::multiprecision;
264
265 if (!den)
266 Throw<std::runtime_error>("division by zero");
267
268 int128_t const amt128(amt.drops());
269 auto const neg = amt.drops() < 0;
270 auto const m = amt128 * num;
271 auto r = m / den;
272 if (m % den)
273 {
274 if (!neg && roundUp)
275 r += 1;
276 if (neg && !roundUp)
277 r -= 1;
278 }
280 Throw<std::overflow_error>("XRP mulRatio overflow");
281 return XRPAmount(r.convert_to<XRPAmount::value_type>());
282}
283
284} // 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:207
static XRPAmount minPositiveAmount()
Definition XRPAmount.h:231
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:218
friend std::istream & operator>>(std::istream &s, XRPAmount &val)
Definition XRPAmount.h:224
Dest dropsAs(XRPAmount defaultValue) const
Definition XRPAmount.h:187
constexpr value_type drops() const
Returns the number of drops.
Definition XRPAmount.h:157
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
Json::Value jsonClipped() const
Definition XRPAmount.h:197
constexpr XRPAmount & operator=(XRPAmount const &other)=default
Dest dropsAs(Dest defaultValue) const
Definition XRPAmount.h:180
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:167
friend constexpr XRPAmount operator*(value_type lhs, XRPAmount const &rhs)
Definition XRPAmount.h:71
constexpr double decimalXRP() const
Definition XRPAmount.h:241
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_same_v
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
std::string to_string(base_uint< Bits, Tag > const &a)
Definition base_uint.h:602
std::ostream & operator<<(std::ostream &out, base_uint< Bits, Tag > const &u)
Definition base_uint.h:617
IOUAmount mulRatio(IOUAmount const &amt, std::uint32_t num, std::uint32_t den, bool roundUp)
constexpr XRPAmount DROPS_PER_XRP
Number of drops per 1 XRP.
Definition XRPAmount.h:238
Zero allows classes to offer efficient comparisons to zero.
Definition Zero.h:25
T to_string(T... args)