rippled
Loading...
Searching...
No Matches
XRPAmount.h
1#ifndef XRPL_PROTOCOL_XRPAMOUNT_H_INCLUDED
2#define XRPL_PROTOCOL_XRPAMOUNT_H_INCLUDED
3
4#include <xrpl/basics/Number.h>
5#include <xrpl/basics/contract.h>
6#include <xrpl/beast/utility/Zero.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 <optional>
15#include <string>
16#include <type_traits>
17
18namespace ripple {
19
20class XRPAmount : private boost::totally_ordered<XRPAmount>,
21 private boost::additive<XRPAmount>,
22 private boost::equality_comparable<XRPAmount, std::int64_t>,
23 private boost::additive<XRPAmount, std::int64_t>
24{
25public:
26 using unit_type = unit::dropTag;
28
29private:
31
32public:
33 XRPAmount() = default;
34 constexpr XRPAmount(XRPAmount const& other) = default;
35 constexpr XRPAmount&
36 operator=(XRPAmount const& other) = default;
37
38 // Round to nearest, even on tie.
39 explicit XRPAmount(Number const& x) : XRPAmount(static_cast<value_type>(x))
40 {
41 }
42
44 {
45 }
46
47 constexpr XRPAmount&
49 {
50 drops_ = 0;
51 return *this;
52 }
53
54 constexpr explicit XRPAmount(value_type drops) : drops_(drops)
55 {
56 }
57
60 {
61 drops_ = drops;
62 return *this;
63 }
64
65 constexpr XRPAmount
66 operator*(value_type const& rhs) const
67 {
68 return XRPAmount{drops_ * rhs};
69 }
70
71 friend constexpr XRPAmount
73 {
74 // multiplication is commutative
75 return rhs * lhs;
76 }
77
79 operator+=(XRPAmount const& other)
80 {
81 drops_ += other.drops();
82 return *this;
83 }
84
86 operator-=(XRPAmount const& other)
87 {
88 drops_ -= other.drops();
89 return *this;
90 }
91
94 {
95 drops_ += rhs;
96 return *this;
97 }
98
101 {
102 drops_ -= rhs;
103 return *this;
104 }
105
106 XRPAmount&
108 {
109 drops_ *= rhs;
110 return *this;
111 }
112
114 operator-() const
115 {
116 return XRPAmount{-drops_};
117 }
118
119 bool
120 operator==(XRPAmount const& other) const
121 {
122 return drops_ == other.drops_;
123 }
124
125 bool
127 {
128 return drops_ == other;
129 }
130
131 bool
132 operator<(XRPAmount const& other) const
133 {
134 return drops_ < other.drops_;
135 }
136
138 explicit constexpr
139 operator bool() const noexcept
140 {
141 return drops_ != 0;
142 }
143
144 operator Number() const noexcept
145 {
146 return drops();
147 }
148
150 constexpr int
151 signum() const noexcept
152 {
153 return (drops_ < 0) ? -1 : (drops_ ? 1 : 0);
154 }
155
157 constexpr value_type
158 drops() const
159 {
160 return drops_;
161 }
162
163 constexpr double
164 decimalXRP() const;
165
166 template <class Dest>
168 dropsAs() const
169 {
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 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 */
200 {
201 static_assert(
203 "Expected XRPAmount to be a signed integral type");
204
205 constexpr auto min = std::numeric_limits<Json::Int>::min();
206 constexpr auto max = std::numeric_limits<Json::Int>::max();
207
208 if (drops_ < min)
209 return min;
210 if (drops_ > max)
211 return max;
212 return static_cast<Json::Int>(drops_);
213 }
214
219 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 DROPS_PER_XRP{1'000'000};
241
242constexpr double
244{
245 return static_cast<double>(drops_) / DROPS_PER_XRP.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
264 XRPAmount const& amt,
265 std::uint32_t num,
266 std::uint32_t den,
267 bool roundUp)
268{
269 using namespace boost::multiprecision;
270
271 if (!den)
272 Throw<std::runtime_error>("division by zero");
273
274 int128_t const amt128(amt.drops());
275 auto const neg = amt.drops() < 0;
276 auto const m = amt128 * num;
277 auto r = m / den;
278 if (m % den)
279 {
280 if (!neg && roundUp)
281 r += 1;
282 if (neg && !roundUp)
283 r -= 1;
284 }
286 Throw<std::overflow_error>("XRP mulRatio overflow");
287 return XRPAmount(r.convert_to<XRPAmount::value_type>());
288}
289
290} // namespace ripple
291
292#endif // XRPL_BASICS_XRPAMOUNT_H_INCLUDED
Represents a JSON value.
Definition json_value.h:131
constexpr XRPAmount(beast::Zero)
Definition XRPAmount.h:43
XRPAmount & operator=(value_type drops)
Definition XRPAmount.h:59
Dest dropsAs(Dest defaultValue) const
Definition XRPAmount.h:182
XRPAmount()=default
constexpr value_type value() const
Returns the underlying value.
Definition XRPAmount.h:220
std::int64_t value_type
Definition XRPAmount.h:27
bool operator==(XRPAmount const &other) const
Definition XRPAmount.h:120
std::optional< Dest > dropsAs() const
Definition XRPAmount.h:168
constexpr int signum() const noexcept
Return the sign of the amount.
Definition XRPAmount.h:151
friend std::istream & operator>>(std::istream &s, XRPAmount &val)
Definition XRPAmount.h:226
XRPAmount & operator-=(XRPAmount const &other)
Definition XRPAmount.h:86
XRPAmount operator-() const
Definition XRPAmount.h:114
constexpr XRPAmount operator*(value_type const &rhs) const
Definition XRPAmount.h:66
XRPAmount & operator+=(value_type const &rhs)
Definition XRPAmount.h:93
constexpr value_type drops() const
Returns the number of drops.
Definition XRPAmount.h:158
XRPAmount & operator*=(value_type const &rhs)
Definition XRPAmount.h:107
constexpr XRPAmount & operator=(XRPAmount const &other)=default
value_type drops_
Definition XRPAmount.h:30
XRPAmount & operator-=(value_type const &rhs)
Definition XRPAmount.h:100
static XRPAmount minPositiveAmount()
Definition XRPAmount.h:233
Dest dropsAs(XRPAmount defaultValue) const
Definition XRPAmount.h:189
constexpr XRPAmount(value_type drops)
Definition XRPAmount.h:54
XRPAmount & operator+=(XRPAmount const &other)
Definition XRPAmount.h:79
bool operator<(XRPAmount const &other) const
Definition XRPAmount.h:132
constexpr double decimalXRP() const
Definition XRPAmount.h:243
constexpr XRPAmount & operator=(beast::Zero)
Definition XRPAmount.h:48
Json::Value jsonClipped() const
Definition XRPAmount.h:199
unit::dropTag unit_type
Definition XRPAmount.h:26
bool operator==(value_type other) const
Definition XRPAmount.h:126
XRPAmount(Number const &x)
Definition XRPAmount.h:39
friend constexpr XRPAmount operator*(value_type lhs, XRPAmount const &rhs)
Definition XRPAmount.h:72
constexpr XRPAmount(XRPAmount const &other)=default
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:6
std::ostream & operator<<(std::ostream &out, base_uint< Bits, Tag > const &u)
Definition base_uint.h:628
IOUAmount mulRatio(IOUAmount const &amt, std::uint32_t num, std::uint32_t den, bool roundUp)
std::string to_string(base_uint< Bits, Tag > const &a)
Definition base_uint.h:611
constexpr XRPAmount DROPS_PER_XRP
Number of drops per 1 XRP.
Definition XRPAmount.h:240
Zero allows classes to offer efficient comparisons to zero.
Definition Zero.h:26
T to_string(T... args)