rippled
Loading...
Searching...
No Matches
AmountSpec.h
1#ifndef XRPL_PATH_IMPL_AMOUNTSPEC_H_INCLUDED
2#define XRPL_PATH_IMPL_AMOUNTSPEC_H_INCLUDED
3
4#include <xrpl/protocol/IOUAmount.h>
5#include <xrpl/protocol/STAmount.h>
6#include <xrpl/protocol/XRPAmount.h>
7
8#include <optional>
9
10namespace xrpl {
11
13{
14 explicit AmountSpec() = default;
15
16 bool native;
17 union
18 {
21 };
24
26 operator<<(std::ostream& stream, AmountSpec const& amt)
27 {
28 if (amt.native)
29 stream << to_string(amt.xrp);
30 else
31 stream << to_string(amt.iou);
32 if (amt.currency)
33 stream << "/(" << *amt.currency << ")";
34 if (amt.issuer)
35 stream << "/" << *amt.issuer << "";
36 return stream;
37 }
38};
39
41{
42#ifndef NDEBUG
43 bool native = false;
44#endif
45
46 union
47 {
50 };
51
52 EitherAmount() = default;
53
54 explicit EitherAmount(IOUAmount const& a) : iou(a)
55 {
56 }
57
58#if defined(__GNUC__) && !defined(__clang__)
59#pragma GCC diagnostic push
60 // ignore warning about half of iou amount being uninitialized
61#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
62#endif
63 explicit EitherAmount(XRPAmount const& a) : xrp(a)
64 {
65#ifndef NDEBUG
66 native = true;
67#endif
68 }
69#if defined(__GNUC__) && !defined(__clang__)
70#pragma GCC diagnostic pop
71#endif
72
73 explicit EitherAmount(AmountSpec const& a)
74 {
75#ifndef NDEBUG
76 native = a.native;
77#endif
78 if (a.native)
79 xrp = a.xrp;
80 else
81 iou = a.iou;
82 }
83
84#ifndef NDEBUG
86 operator<<(std::ostream& stream, EitherAmount const& amt)
87 {
88 if (amt.native)
89 stream << to_string(amt.xrp);
90 else
91 stream << to_string(amt.iou);
92 return stream;
93 }
94#endif
95};
96
97template <class T>
98T&
100{
101 static_assert(sizeof(T) == -1, "Must used specialized function");
102 return T(0);
103}
104
105template <>
108{
109 XRPL_ASSERT(
110 !amt.native, "xrpl::get<IOUAmount>(EitherAmount&) : is not XRP");
111 return amt.iou;
112}
113
114template <>
117{
118 XRPL_ASSERT(amt.native, "xrpl::get<XRPAmount>(EitherAmount&) : is XRP");
119 return amt.xrp;
120}
121
122template <class T>
123T const&
124get(EitherAmount const& amt)
125{
126 static_assert(sizeof(T) == -1, "Must used specialized function");
127 return T(0);
128}
129
130template <>
131inline IOUAmount const&
133{
134 XRPL_ASSERT(
135 !amt.native, "xrpl::get<IOUAmount>(EitherAmount const&) : is not XRP");
136 return amt.iou;
137}
138
139template <>
140inline XRPAmount const&
142{
143 XRPL_ASSERT(
144 amt.native, "xrpl::get<XRPAmount>(EitherAmount const&) : is XRP");
145 return amt.xrp;
146}
147
148inline AmountSpec
150{
151 XRPL_ASSERT(
153 "xrpl::toAmountSpec(STAmount const&) : maximum mantissa");
154 bool const isNeg = amt.negative();
155 std::int64_t const sMant =
156 isNeg ? -std::int64_t(amt.mantissa()) : amt.mantissa();
157 AmountSpec result;
158
159 result.native = isXRP(amt);
160 if (result.native)
161 {
162 result.xrp = XRPAmount(sMant);
163 }
164 else
165 {
166 result.iou = IOUAmount(sMant, amt.exponent());
167 result.issuer = amt.issue().account;
168 result.currency = amt.issue().currency;
169 }
170
171 return result;
172}
173
174inline EitherAmount
176{
177 if (isXRP(amt))
178 return EitherAmount{amt.xrp()};
179 return EitherAmount{amt.iou()};
180}
181
182inline AmountSpec
184{
185 AmountSpec r;
186 r.native = (!c || isXRP(*c));
187 r.currency = c;
188 XRPL_ASSERT(
189 ea.native == r.native,
190 "xrpl::toAmountSpec(EitherAmount const&&, std::optional<Currency>) : "
191 "matching native");
192 if (r.native)
193 {
194 r.xrp = ea.xrp;
195 }
196 else
197 {
198 r.iou = ea.iou;
199 }
200 return r;
201}
202
203} // namespace xrpl
204
205#endif
Floating point representation of amounts with high dynamic range.
Definition IOUAmount.h:27
Currency currency
Definition Issue.h:16
AccountID account
Definition Issue.h:17
Issue const & issue() const
Definition STAmount.h:488
std::uint64_t mantissa() const noexcept
Definition STAmount.h:469
IOUAmount iou() const
Definition STAmount.cpp:280
bool negative() const noexcept
Definition STAmount.h:463
int exponent() const noexcept
Definition STAmount.h:438
XRPAmount xrp() const
Definition STAmount.cpp:264
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition algorithm.h:6
IOUAmount & get< IOUAmount >(EitherAmount &amt)
Definition AmountSpec.h:107
bool isXRP(AccountID const &c)
Definition AccountID.h:71
std::string to_string(base_uint< Bits, Tag > const &a)
Definition base_uint.h:611
T get(Section const &section, std::string const &name, T const &defaultValue=T{})
Retrieve a key/value pair from a section.
EitherAmount toEitherAmount(STAmount const &amt)
Definition AmountSpec.h:175
XRPAmount & get< XRPAmount >(EitherAmount &amt)
Definition AmountSpec.h:116
AmountSpec toAmountSpec(STAmount const &amt)
Definition AmountSpec.h:149
IOUAmount iou
Definition AmountSpec.h:20
AmountSpec()=default
XRPAmount xrp
Definition AmountSpec.h:19
std::optional< AccountID > issuer
Definition AmountSpec.h:22
friend std::ostream & operator<<(std::ostream &stream, AmountSpec const &amt)
Definition AmountSpec.h:26
std::optional< Currency > currency
Definition AmountSpec.h:23
EitherAmount(XRPAmount const &a)
Definition AmountSpec.h:63
EitherAmount()=default
friend std::ostream & operator<<(std::ostream &stream, EitherAmount const &amt)
Definition AmountSpec.h:86
EitherAmount(AmountSpec const &a)
Definition AmountSpec.h:73
EitherAmount(IOUAmount const &a)
Definition AmountSpec.h:54