rippled
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_BASICS_XRPAMOUNT_H_INCLUDED
21 #define RIPPLE_BASICS_XRPAMOUNT_H_INCLUDED
22 
23 #include <ripple/basics/contract.h>
24 #include <ripple/basics/safe_cast.h>
25 #include <ripple/beast/utility/Zero.h>
26 #include <ripple/json/json_value.h>
27 
28 #include <boost/multiprecision/cpp_int.hpp>
29 #include <boost/operators.hpp>
30 
31 #include <cstdint>
32 #include <optional>
33 #include <string>
34 #include <type_traits>
35 
36 namespace ripple {
37 
38 namespace feeunit {
39 
42 struct dropTag;
43 
44 } // namespace feeunit
45 
46 class XRPAmount : private boost::totally_ordered<XRPAmount>,
47  private boost::additive<XRPAmount>,
48  private boost::equality_comparable<XRPAmount, std::int64_t>,
49  private boost::additive<XRPAmount, std::int64_t>
50 {
51 public:
52  using unit_type = feeunit::dropTag;
54 
55 private:
57 
58 public:
59  XRPAmount() = default;
60  constexpr XRPAmount(XRPAmount const& other) = default;
61  constexpr XRPAmount&
62  operator=(XRPAmount const& other) = default;
63 
64  constexpr XRPAmount(beast::Zero) : drops_(0)
65  {
66  }
67 
69  {
70  drops_ = 0;
71  return *this;
72  }
73 
74  constexpr explicit XRPAmount(value_type drops) : drops_(drops)
75  {
76  }
77 
78  XRPAmount&
80  {
81  drops_ = drops;
82  return *this;
83  }
84 
85  constexpr XRPAmount
86  operator*(value_type const& rhs) const
87  {
88  return XRPAmount{drops_ * rhs};
89  }
90 
91  friend constexpr XRPAmount
92  operator*(value_type lhs, XRPAmount const& rhs)
93  {
94  // multiplication is commutative
95  return rhs * lhs;
96  }
97 
98  XRPAmount&
99  operator+=(XRPAmount const& other)
100  {
101  drops_ += other.drops();
102  return *this;
103  }
104 
105  XRPAmount&
106  operator-=(XRPAmount const& other)
107  {
108  drops_ -= other.drops();
109  return *this;
110  }
111 
112  XRPAmount&
113  operator+=(value_type const& rhs)
114  {
115  drops_ += rhs;
116  return *this;
117  }
118 
119  XRPAmount&
120  operator-=(value_type const& rhs)
121  {
122  drops_ -= rhs;
123  return *this;
124  }
125 
126  XRPAmount&
127  operator*=(value_type const& rhs)
128  {
129  drops_ *= rhs;
130  return *this;
131  }
132 
133  XRPAmount
134  operator-() const
135  {
136  return XRPAmount{-drops_};
137  }
138 
139  bool
140  operator==(XRPAmount const& other) const
141  {
142  return drops_ == other.drops_;
143  }
144 
145  bool
146  operator==(value_type other) const
147  {
148  return drops_ == other;
149  }
150 
151  bool
152  operator<(XRPAmount const& other) const
153  {
154  return drops_ < other.drops_;
155  }
156 
158  explicit constexpr operator bool() const noexcept
159  {
160  return drops_ != 0;
161  }
162 
164  constexpr int
165  signum() const noexcept
166  {
167  return (drops_ < 0) ? -1 : (drops_ ? 1 : 0);
168  }
169 
171  constexpr value_type
172  drops() const
173  {
174  return drops_;
175  }
176 
177  constexpr double
178  decimalXRP() const;
179 
180  template <class Dest>
182  dropsAs() const
183  {
188  {
189  return std::nullopt;
190  }
191  return static_cast<Dest>(drops_);
192  }
193 
194  template <class Dest>
195  Dest
196  dropsAs(Dest defaultValue) const
197  {
198  return dropsAs<Dest>().value_or(defaultValue);
199  }
200 
201  template <class Dest>
202  Dest
203  dropsAs(XRPAmount defaultValue) const
204  {
205  return dropsAs<Dest>().value_or(defaultValue.drops());
206  }
207 
209  jsonClipped() const
210  {
211  static_assert(
212  std::is_signed_v<value_type> && std::is_integral_v<value_type>,
213  "Expected XRPAmount to be a signed integral type");
214 
215  constexpr auto min = std::numeric_limits<Json::Int>::min();
216  constexpr auto max = std::numeric_limits<Json::Int>::max();
217 
218  if (drops_ < min)
219  return min;
220  if (drops_ > max)
221  return max;
222  return static_cast<Json::Int>(drops_);
223  }
224 
229  constexpr value_type
230  value() const
231  {
232  return drops_;
233  }
234 
235  friend std::istream&
237  {
238  s >> val.drops_;
239  return s;
240  }
241 
242  static XRPAmount
244  {
245  return XRPAmount{1};
246  }
247 };
248 
250 constexpr XRPAmount DROPS_PER_XRP{1'000'000};
251 
252 constexpr double
254 {
255  return static_cast<double>(drops_) / DROPS_PER_XRP.drops();
256 }
257 
258 // Output XRPAmount as just the drops value.
259 template <class Char, class Traits>
262 {
263  return os << q.drops();
264 }
265 
266 inline std::string
267 to_string(XRPAmount const& amount)
268 {
269  return std::to_string(amount.drops());
270 }
271 
272 inline XRPAmount
274  XRPAmount const& amt,
275  std::uint32_t num,
276  std::uint32_t den,
277  bool roundUp)
278 {
279  using namespace boost::multiprecision;
280 
281  if (!den)
282  Throw<std::runtime_error>("division by zero");
283 
284  int128_t const amt128(amt.drops());
285  auto const neg = amt.drops() < 0;
286  auto const m = amt128 * num;
287  auto r = m / den;
288  if (m % den)
289  {
290  if (!neg && roundUp)
291  r += 1;
292  if (neg && !roundUp)
293  r -= 1;
294  }
296  Throw<std::overflow_error>("XRP mulRatio overflow");
297  return XRPAmount(r.convert_to<XRPAmount::value_type>());
298 }
299 
300 } // namespace ripple
301 
302 #endif // RIPPLE_BASICS_XRPAMOUNT_H_INCLUDED
ripple::mulRatio
IOUAmount mulRatio(IOUAmount const &amt, std::uint32_t num, std::uint32_t den, bool roundUp)
Definition: IOUAmount.cpp:182
ripple::XRPAmount::operator-=
XRPAmount & operator-=(value_type const &rhs)
Definition: XRPAmount.h:120
ripple::XRPAmount::XRPAmount
constexpr XRPAmount(value_type drops)
Definition: XRPAmount.h:74
std::string
STL class.
ripple::XRPAmount::operator==
bool operator==(value_type other) const
Definition: XRPAmount.h:146
ripple::XRPAmount::operator=
constexpr XRPAmount & operator=(XRPAmount const &other)=default
ripple::XRPAmount::operator+=
XRPAmount & operator+=(value_type const &rhs)
Definition: XRPAmount.h:113
ripple::XRPAmount::operator>>
friend std::istream & operator>>(std::istream &s, XRPAmount &val)
Definition: XRPAmount.h:236
ripple::XRPAmount::value
constexpr value_type value() const
Returns the underlying value.
Definition: XRPAmount.h:230
ripple::XRPAmount::drops
constexpr value_type drops() const
Returns the number of drops.
Definition: XRPAmount.h:172
ripple::XRPAmount::operator==
bool operator==(XRPAmount const &other) const
Definition: XRPAmount.h:140
ripple::operator<<
std::ostream & operator<<(std::ostream &os, TOffer< TIn, TOut > const &offer)
Definition: Offer.h:242
ripple::XRPAmount::unit_type
feeunit::dropTag unit_type
Definition: XRPAmount.h:52
ripple::XRPAmount::operator*
constexpr XRPAmount operator*(value_type const &rhs) const
Definition: XRPAmount.h:86
ripple::XRPAmount::operator*=
XRPAmount & operator*=(value_type const &rhs)
Definition: XRPAmount.h:127
ripple::XRPAmount::decimalXRP
constexpr double decimalXRP() const
Definition: XRPAmount.h:253
std::basic_ostream
STL class.
ripple::XRPAmount::value_type
std::int64_t value_type
Definition: XRPAmount.h:53
std::to_string
T to_string(T... args)
ripple::XRPAmount::operator<
bool operator<(XRPAmount const &other) const
Definition: XRPAmount.h:152
ripple::XRPAmount::XRPAmount
XRPAmount()=default
beast::Zero
Zero allows classes to offer efficient comparisons to zero.
Definition: Zero.h:42
ripple::XRPAmount::dropsAs
std::optional< Dest > dropsAs() const
Definition: XRPAmount.h:182
cstdint
std::int64_t
Json::Int
int Int
Definition: json_forwards.h:26
ripple::XRPAmount::dropsAs
Dest dropsAs(XRPAmount defaultValue) const
Definition: XRPAmount.h:203
std::numeric_limits::min
T min(T... args)
ripple::DROPS_PER_XRP
constexpr XRPAmount DROPS_PER_XRP
Number of drops per 1 XRP.
Definition: XRPAmount.h:250
ripple::XRPAmount::operator-
XRPAmount operator-() const
Definition: XRPAmount.h:134
ripple
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition: RCLCensorshipDetector.h:29
ripple::XRPAmount::operator-=
XRPAmount & operator-=(XRPAmount const &other)
Definition: XRPAmount.h:106
ripple::XRPAmount::operator*
constexpr friend XRPAmount operator*(value_type lhs, XRPAmount const &rhs)
Definition: XRPAmount.h:92
ripple::XRPAmount::operator+=
XRPAmount & operator+=(XRPAmount const &other)
Definition: XRPAmount.h:99
ripple::XRPAmount::minPositiveAmount
static XRPAmount minPositiveAmount()
Definition: XRPAmount.h:243
optional
ripple::to_string
std::string to_string(Manifest const &m)
Format the specified manifest to a string for debugging purposes.
Definition: app/misc/impl/Manifest.cpp:41
ripple::XRPAmount::operator=
XRPAmount & operator=(value_type drops)
Definition: XRPAmount.h:79
std::numeric_limits::max
T max(T... args)
ripple::XRPAmount::operator=
constexpr XRPAmount & operator=(beast::Zero)
Definition: XRPAmount.h:68
ripple::XRPAmount::XRPAmount
constexpr XRPAmount(beast::Zero)
Definition: XRPAmount.h:64
std::istream
STL class.
ripple::XRPAmount::drops_
value_type drops_
Definition: XRPAmount.h:56
std::numeric_limits
ripple::XRPAmount::dropsAs
Dest dropsAs(Dest defaultValue) const
Definition: XRPAmount.h:196
type_traits
ripple::XRPAmount::jsonClipped
Json::Value jsonClipped() const
Definition: XRPAmount.h:209
Json::Value
Represents a JSON value.
Definition: json_value.h:145
ripple::XRPAmount::signum
constexpr int signum() const noexcept
Return the sign of the amount.
Definition: XRPAmount.h:165
ripple::XRPAmount
Definition: XRPAmount.h:46
string