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