xrpld
Loading...
Searching...
No Matches
AmountConversions.h
1#pragma once
2
3#include <xrpl/basics/Number.h>
4#include <xrpl/basics/contract.h>
5#include <xrpl/beast/utility/instrumentation.h>
6#include <xrpl/protocol/Asset.h>
7#include <xrpl/protocol/IOUAmount.h>
8#include <xrpl/protocol/Issue.h>
9#include <xrpl/protocol/MPTAmount.h>
10#include <xrpl/protocol/MPTIssue.h>
11#include <xrpl/protocol/Protocol.h>
12#include <xrpl/protocol/STAmount.h>
13#include <xrpl/protocol/XRPAmount.h>
14
15#include <cstdint>
16#include <limits> // IWYU pragma: keep
17#include <stdexcept>
18#include <type_traits>
19
20namespace xrpl {
21
22inline STAmount
23toSTAmount(IOUAmount const& iou, Asset const& asset)
24{
25 XRPL_ASSERT(asset.holds<Issue>(), "xrpl::toSTAmount : is Issue");
26 bool const isNeg = iou.signum() < 0;
27 std::uint64_t const umant = isNeg ? -iou.mantissa() : iou.mantissa();
28 return STAmount(asset, umant, iou.exponent(), isNeg, STAmount::Unchecked());
29}
30
31inline STAmount
33{
34 return toSTAmount(iou, noIssue());
35}
36
37inline STAmount
39{
40 bool const isNeg = xrp.signum() < 0;
41 std::uint64_t const umant = isNeg ? -xrp.drops() : xrp.drops();
42 return STAmount(umant, isNeg);
43}
44
45inline STAmount
46toSTAmount(XRPAmount const& xrp, Asset const& asset)
47{
48 XRPL_ASSERT(isXRP(asset), "xrpl::toSTAmount : is XRP");
49 return toSTAmount(xrp);
50}
51
52inline STAmount
54{
55 return STAmount(mpt, noMPT());
56}
57
58inline STAmount
59toSTAmount(MPTAmount const& mpt, Asset const& asset)
60{
61 XRPL_ASSERT(asset.holds<MPTIssue>(), "xrpl::toSTAmount : is MPT");
62 return STAmount(mpt, asset.get<MPTIssue>());
63}
64
65template <class T>
66T
67toAmount(STAmount const& amt) = delete;
68
69template <>
72{
73 return amt;
74}
75
76template <>
79{
80 XRPL_ASSERT(
82 "xrpl::toAmount<IOUAmount> : maximum mantissa");
83 bool const isNeg = amt.negative();
84 std::int64_t const sMant = isNeg ? -std::int64_t(amt.mantissa()) : amt.mantissa();
85
86 XRPL_ASSERT(!isXRP(amt), "xrpl::toAmount<IOUAmount> : is not XRP");
87 return IOUAmount(sMant, amt.exponent());
88}
89
90template <>
93{
94 XRPL_ASSERT(
96 "xrpl::toAmount<XRPAmount> : maximum mantissa");
97 bool const isNeg = amt.negative();
98 std::int64_t const sMant = isNeg ? -std::int64_t(amt.mantissa()) : amt.mantissa();
99
100 XRPL_ASSERT(isXRP(amt), "xrpl::toAmount<XRPAmount> : is XRP");
101 return XRPAmount(sMant);
102}
103
104template <>
107{
108 XRPL_ASSERT(
109 amt.holds<MPTIssue>() && amt.mantissa() <= kMaxMpTokenAmount && amt.exponent() == 0,
110 "xrpl::toAmount<MPTAmount> : maximum mantissa");
111 if (amt.mantissa() > kMaxMpTokenAmount || amt.exponent() != 0)
112 Throw<std::runtime_error>("toAmount<MPTAmount>: invalid mantissa or exponent");
113 bool const isNeg = amt.negative();
114 std::int64_t const sMant = isNeg ? -std::int64_t(amt.mantissa()) : amt.mantissa();
115
116 return MPTAmount(sMant);
117}
118
119template <class T>
120T
121toAmount(IOUAmount const& amt) = delete;
122
123template <>
126{
127 return amt;
128}
129
130template <class T>
131T
132toAmount(XRPAmount const& amt) = delete;
133
134template <>
137{
138 return amt;
139}
140
141template <class T>
142T
143toAmount(MPTAmount const& amt) = delete;
144
145template <>
148{
149 return amt;
150}
151
152template <typename T>
153T
155{
157 if (asset.integral())
158 Number::setround(mode);
159
160 if constexpr (std::is_same_v<IOUAmount, T>)
161 {
162 return IOUAmount(n);
163 }
164 else if constexpr (std::is_same_v<XRPAmount, T>)
165 {
166 return XRPAmount(static_cast<std::int64_t>(n));
167 }
168 else if constexpr (std::is_same_v<MPTAmount, T>)
169 {
170 return MPTAmount(static_cast<std::int64_t>(n));
171 }
172 else if constexpr (std::is_same_v<STAmount, T>)
173 {
174 if (isXRP(asset))
175 return STAmount(asset, static_cast<std::int64_t>(n));
176 return STAmount(asset, n);
177 }
178 else
179 {
180 static constexpr bool kAlwaysFalse = !std::is_same_v<T, T>;
181 static_assert(kAlwaysFalse, "Unsupported type for toAmount");
182 }
183}
184
185template <typename T>
186T
187toMaxAmount(Asset const& asset)
188{
189 if constexpr (std::is_same_v<IOUAmount, T>)
190 {
192 }
193 else if constexpr (std::is_same_v<XRPAmount, T>)
194 {
195 return XRPAmount(static_cast<std::int64_t>(STAmount::kMaxNativeN));
196 }
197 else if constexpr (std::is_same_v<MPTAmount, T>)
198 {
200 }
201 else if constexpr (std::is_same_v<STAmount, T>)
202 {
203 return asset.visit(
204 [](Issue const& issue) {
205 if (isXRP(issue))
206 return STAmount(issue, static_cast<std::int64_t>(STAmount::kMaxNativeN));
208 },
209 [](MPTIssue const& issue) { return STAmount(issue, kMaxMpTokenAmount); });
210 }
211 else
212 {
213 static constexpr bool kAlwaysFalse = !std::is_same_v<T, T>;
214 static_assert(kAlwaysFalse, "Unsupported type for toMaxAmount");
215 }
216}
217
218inline STAmount
220{
221 return toAmount<STAmount>(asset, n, mode);
222}
223
224template <typename T>
225Asset
226getAsset(T const& amt)
227{
228 if constexpr (std::is_same_v<IOUAmount, T>)
229 {
230 return noIssue();
231 }
232 else if constexpr (std::is_same_v<XRPAmount, T>)
233 {
234 return xrpIssue();
235 }
236 else if constexpr (std::is_same_v<MPTAmount, T>)
237 {
238 return noMPT();
239 }
240 else if constexpr (std::is_same_v<STAmount, T>)
241 {
242 return amt.asset();
243 }
244 else
245 {
246 static constexpr bool kAlwaysFalse = !std::is_same_v<T, T>;
247 static_assert(kAlwaysFalse, "Unsupported type for getIssue");
248 }
249}
250
251template <typename T>
252constexpr T
253get(STAmount const& a)
254{
255 if constexpr (std::is_same_v<IOUAmount, T>)
256 {
257 return a.iou();
258 }
259 else if constexpr (std::is_same_v<XRPAmount, T>)
260 {
261 return a.xrp();
262 }
263 else if constexpr (std::is_same_v<MPTAmount, T>)
264 {
265 return a.mpt();
266 }
267 else if constexpr (std::is_same_v<STAmount, T>)
268 {
269 return a;
270 }
271 else
272 {
273 constexpr bool kAlwaysFalse = !std::is_same_v<T, T>;
274 static_assert(kAlwaysFalse, "Unsupported type for get");
275 }
276}
277
278} // namespace xrpl
constexpr auto visit(Visitors &&... visitors) const -> decltype(auto)
Definition Asset.h:117
constexpr TIss const & get() const
bool integral() const
Definition Asset.h:133
constexpr bool holds() const
Definition Asset.h:177
Floating point representation of amounts with high dynamic range.
Definition IOUAmount.h:26
mantissa_type mantissa() const noexcept
Definition IOUAmount.h:172
exponent_type exponent() const noexcept
Definition IOUAmount.h:166
int signum() const noexcept
Return the sign of the amount.
Definition IOUAmount.h:158
A currency issued by an account.
Definition Issue.h:18
Number is a floating point type that can represent a wide range of values.
Definition Number.h:351
static RoundingMode setround(RoundingMode inMode)
static RoundingMode getround()
constexpr bool holds() const noexcept
Definition STAmount.h:478
std::uint64_t mantissa() const noexcept
Definition STAmount.h:490
IOUAmount iou() const
Definition STAmount.cpp:286
bool negative() const noexcept
Definition STAmount.h:484
static constexpr std::uint64_t kMaxNativeN
Definition STAmount.h:72
MPTAmount mpt() const
Definition STAmount.cpp:301
int exponent() const noexcept
Definition STAmount.h:459
static constexpr std::uint64_t kMaxValue
Definition STAmount.h:67
XRPAmount xrp() const
Definition STAmount.cpp:271
static constexpr int kMaxOffset
Definition STAmount.h:62
constexpr value_type drops() const
Returns the number of drops.
Definition XRPAmount.h:170
constexpr int signum() const noexcept
Return the sign of the amount.
Definition XRPAmount.h:159
T is_same_v
T max(T... args)
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition algorithm.h:5
Issue const & xrpIssue()
Returns an asset specifier that represents XRP.
Definition Issue.h:108
bool isXRP(AccountID const &c)
Definition AccountID.h:84
T toMaxAmount(Asset const &asset)
MPTAmount toAmount< MPTAmount >(STAmount const &amt)
T get(Section const &section, std::string const &name, T const &defaultValue=T{})
Retrieve a key/value pair from a section.
T toAmount(STAmount const &amt)=delete
XRPAmount toAmount< XRPAmount >(STAmount const &amt)
Asset getAsset(T const &amt)
MPTID noMPT()
Definition MPTIssue.h:114
IOUAmount toAmount< IOUAmount >(STAmount const &amt)
Issue const & noIssue()
Returns an asset specifier that represents no account and currency.
Definition Issue.h:118
constexpr std::uint64_t kMaxMpTokenAmount
The maximum amount of MPTokenIssuance.
Definition Protocol.h:296
XRPL_NO_SANITIZE_ADDRESS void Throw(Args &&... args)
Definition contract.h:52
STAmount toSTAmount(IOUAmount const &iou, Asset const &asset)
STAmount toAmount< STAmount >(STAmount const &amt)