rippled
Loading...
Searching...
No Matches
XRPAmount.h
1//------------------------------------------------------------------------------
2/*
3 This file is part of rippled: https://github.com/ripple/rippled
4 Copyright (c) 2012, 2013 Ripple Labs Inc.
5
6 Permission to use, copy, modify, and/or distribute this software for any
7 purpose with or without fee is hereby granted, provided that the above
8 copyright notice and this permission notice appear in all copies.
9
10 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17*/
18//==============================================================================
19
20#ifndef RIPPLE_PROTOCOL_XRPAMOUNT_H_INCLUDED
21#define RIPPLE_PROTOCOL_XRPAMOUNT_H_INCLUDED
22
23#include <xrpl/basics/Number.h>
24#include <xrpl/basics/contract.h>
25#include <xrpl/beast/utility/Zero.h>
26#include <xrpl/json/json_value.h>
27#include <xrpl/protocol/Units.h>
28
29#include <boost/multiprecision/cpp_int.hpp>
30#include <boost/operators.hpp>
31
32#include <cstdint>
33#include <optional>
34#include <string>
35#include <type_traits>
36
37namespace ripple {
38
39class XRPAmount : private boost::totally_ordered<XRPAmount>,
40 private boost::additive<XRPAmount>,
41 private boost::equality_comparable<XRPAmount, std::int64_t>,
42 private boost::additive<XRPAmount, std::int64_t>
43{
44public:
45 using unit_type = unit::dropTag;
47
48private:
50
51public:
52 XRPAmount() = default;
53 constexpr XRPAmount(XRPAmount const& other) = default;
54 constexpr XRPAmount&
55 operator=(XRPAmount const& other) = default;
56
57 // Round to nearest, even on tie.
58 explicit XRPAmount(Number const& x) : XRPAmount(static_cast<value_type>(x))
59 {
60 }
61
63 {
64 }
65
66 constexpr XRPAmount&
68 {
69 drops_ = 0;
70 return *this;
71 }
72
73 constexpr explicit XRPAmount(value_type drops) : drops_(drops)
74 {
75 }
76
79 {
80 drops_ = drops;
81 return *this;
82 }
83
84 constexpr XRPAmount
85 operator*(value_type const& rhs) const
86 {
87 return XRPAmount{drops_ * rhs};
88 }
89
90 friend constexpr XRPAmount
92 {
93 // multiplication is commutative
94 return rhs * lhs;
95 }
96
98 operator+=(XRPAmount const& other)
99 {
100 drops_ += other.drops();
101 return *this;
102 }
103
104 XRPAmount&
105 operator-=(XRPAmount const& other)
106 {
107 drops_ -= other.drops();
108 return *this;
109 }
110
111 XRPAmount&
113 {
114 drops_ += rhs;
115 return *this;
116 }
117
118 XRPAmount&
120 {
121 drops_ -= rhs;
122 return *this;
123 }
124
125 XRPAmount&
127 {
128 drops_ *= rhs;
129 return *this;
130 }
131
133 operator-() const
134 {
135 return XRPAmount{-drops_};
136 }
137
138 bool
139 operator==(XRPAmount const& other) const
140 {
141 return drops_ == other.drops_;
142 }
143
144 bool
146 {
147 return drops_ == other;
148 }
149
150 bool
151 operator<(XRPAmount const& other) const
152 {
153 return drops_ < other.drops_;
154 }
155
157 explicit constexpr
158 operator bool() const noexcept
159 {
160 return drops_ != 0;
161 }
162
163 operator Number() const noexcept
164 {
165 return drops();
166 }
167
169 constexpr int
170 signum() const noexcept
171 {
172 return (drops_ < 0) ? -1 : (drops_ ? 1 : 0);
173 }
174
176 constexpr value_type
177 drops() const
178 {
179 return drops_;
180 }
181
182 constexpr double
183 decimalXRP() const;
184
185 template <class Dest>
187 dropsAs() const
188 {
193 {
194 return std::nullopt;
195 }
196 return static_cast<Dest>(drops_);
197 }
198
199 template <class Dest>
200 Dest
201 dropsAs(Dest defaultValue) const
202 {
203 return dropsAs<Dest>().value_or(defaultValue);
204 }
205
206 template <class Dest>
207 Dest
208 dropsAs(XRPAmount defaultValue) const
209 {
210 return dropsAs<Dest>().value_or(defaultValue.drops());
211 }
212
213 /* Clips a 64-bit value to a 32-bit JSON number. It is only used
214 * in contexts that don't expect the value to ever approach
215 * the 32-bit limits (i.e. fees and reserves).
216 */
219 {
220 static_assert(
222 "Expected XRPAmount to be a signed integral type");
223
224 constexpr auto min = std::numeric_limits<Json::Int>::min();
225 constexpr auto max = std::numeric_limits<Json::Int>::max();
226
227 if (drops_ < min)
228 return min;
229 if (drops_ > max)
230 return max;
231 return static_cast<Json::Int>(drops_);
232 }
233
238 constexpr value_type
239 value() const
240 {
241 return drops_;
242 }
243
244 friend std::istream&
246 {
247 s >> val.drops_;
248 return s;
249 }
250
251 static XRPAmount
253 {
254 return XRPAmount{1};
255 }
256};
257
259constexpr XRPAmount DROPS_PER_XRP{1'000'000};
260
261constexpr double
263{
264 return static_cast<double>(drops_) / DROPS_PER_XRP.drops();
265}
266
267// Output XRPAmount as just the drops value.
268template <class Char, class Traits>
271{
272 return os << q.drops();
273}
274
275inline std::string
276to_string(XRPAmount const& amount)
277{
278 return std::to_string(amount.drops());
279}
280
281inline XRPAmount
283 XRPAmount const& amt,
284 std::uint32_t num,
285 std::uint32_t den,
286 bool roundUp)
287{
288 using namespace boost::multiprecision;
289
290 if (!den)
291 Throw<std::runtime_error>("division by zero");
292
293 int128_t const amt128(amt.drops());
294 auto const neg = amt.drops() < 0;
295 auto const m = amt128 * num;
296 auto r = m / den;
297 if (m % den)
298 {
299 if (!neg && roundUp)
300 r += 1;
301 if (neg && !roundUp)
302 r -= 1;
303 }
305 Throw<std::overflow_error>("XRP mulRatio overflow");
306 return XRPAmount(r.convert_to<XRPAmount::value_type>());
307}
308
309} // namespace ripple
310
311#endif // RIPPLE_BASICS_XRPAMOUNT_H_INCLUDED
Represents a JSON value.
Definition json_value.h:149
constexpr XRPAmount(beast::Zero)
Definition XRPAmount.h:62
XRPAmount & operator=(value_type drops)
Definition XRPAmount.h:78
Dest dropsAs(Dest defaultValue) const
Definition XRPAmount.h:201
XRPAmount()=default
constexpr value_type value() const
Returns the underlying value.
Definition XRPAmount.h:239
std::int64_t value_type
Definition XRPAmount.h:46
bool operator==(XRPAmount const &other) const
Definition XRPAmount.h:139
std::optional< Dest > dropsAs() const
Definition XRPAmount.h:187
constexpr int signum() const noexcept
Return the sign of the amount.
Definition XRPAmount.h:170
friend std::istream & operator>>(std::istream &s, XRPAmount &val)
Definition XRPAmount.h:245
XRPAmount & operator-=(XRPAmount const &other)
Definition XRPAmount.h:105
XRPAmount operator-() const
Definition XRPAmount.h:133
constexpr XRPAmount operator*(value_type const &rhs) const
Definition XRPAmount.h:85
XRPAmount & operator+=(value_type const &rhs)
Definition XRPAmount.h:112
constexpr value_type drops() const
Returns the number of drops.
Definition XRPAmount.h:177
XRPAmount & operator*=(value_type const &rhs)
Definition XRPAmount.h:126
constexpr XRPAmount & operator=(XRPAmount const &other)=default
value_type drops_
Definition XRPAmount.h:49
XRPAmount & operator-=(value_type const &rhs)
Definition XRPAmount.h:119
static XRPAmount minPositiveAmount()
Definition XRPAmount.h:252
Dest dropsAs(XRPAmount defaultValue) const
Definition XRPAmount.h:208
constexpr XRPAmount(value_type drops)
Definition XRPAmount.h:73
XRPAmount & operator+=(XRPAmount const &other)
Definition XRPAmount.h:98
bool operator<(XRPAmount const &other) const
Definition XRPAmount.h:151
constexpr double decimalXRP() const
Definition XRPAmount.h:262
constexpr XRPAmount & operator=(beast::Zero)
Definition XRPAmount.h:67
Json::Value jsonClipped() const
Definition XRPAmount.h:218
unit::dropTag unit_type
Definition XRPAmount.h:45
bool operator==(value_type other) const
Definition XRPAmount.h:145
XRPAmount(Number const &x)
Definition XRPAmount.h:58
friend constexpr XRPAmount operator*(value_type lhs, XRPAmount const &rhs)
Definition XRPAmount.h:91
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:25
std::ostream & operator<<(std::ostream &out, base_uint< Bits, Tag > const &u)
Definition base_uint.h:647
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:630
constexpr XRPAmount DROPS_PER_XRP
Number of drops per 1 XRP.
Definition XRPAmount.h:259
Zero allows classes to offer efficient comparisons to zero.
Definition Zero.h:43
T to_string(T... args)