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 ripple {
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, "ripple::get<IOUAmount>(EitherAmount&) : is not XRP");
111 return amt.iou;
112}
113
114template <>
117{
118 XRPL_ASSERT(amt.native, "ripple::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,
136 "ripple::get<IOUAmount>(EitherAmount const&) : is not XRP");
137 return amt.iou;
138}
139
140template <>
141inline XRPAmount const&
143{
144 XRPL_ASSERT(
145 amt.native, "ripple::get<XRPAmount>(EitherAmount const&) : is XRP");
146 return amt.xrp;
147}
148
149inline AmountSpec
151{
152 XRPL_ASSERT(
154 "ripple::toAmountSpec(STAmount const&) : maximum mantissa");
155 bool const isNeg = amt.negative();
156 std::int64_t const sMant =
157 isNeg ? -std::int64_t(amt.mantissa()) : amt.mantissa();
158 AmountSpec result;
159
160 result.native = isXRP(amt);
161 if (result.native)
162 {
163 result.xrp = XRPAmount(sMant);
164 }
165 else
166 {
167 result.iou = IOUAmount(sMant, amt.exponent());
168 result.issuer = amt.issue().account;
169 result.currency = amt.issue().currency;
170 }
171
172 return result;
173}
174
175inline EitherAmount
177{
178 if (isXRP(amt))
179 return EitherAmount{amt.xrp()};
180 return EitherAmount{amt.iou()};
181}
182
183inline AmountSpec
185{
186 AmountSpec r;
187 r.native = (!c || isXRP(*c));
188 r.currency = c;
189 XRPL_ASSERT(
190 ea.native == r.native,
191 "ripple::toAmountSpec(EitherAmount const&&, std::optional<Currency>) : "
192 "matching native");
193 if (r.native)
194 {
195 r.xrp = ea.xrp;
196 }
197 else
198 {
199 r.iou = ea.iou;
200 }
201 return r;
202}
203
204} // namespace ripple
205
206#endif
Floating point representation of amounts with high dynamic range.
Definition IOUAmount.h:27
AccountID account
Definition Issue.h:17
Currency currency
Definition Issue.h:16
IOUAmount iou() const
Definition STAmount.cpp:280
int exponent() const noexcept
Definition STAmount.h:433
XRPAmount xrp() const
Definition STAmount.cpp:264
bool negative() const noexcept
Definition STAmount.h:452
Issue const & issue() const
Definition STAmount.h:477
std::uint64_t mantissa() const noexcept
Definition STAmount.h:458
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
XRPAmount & get< XRPAmount >(EitherAmount &amt)
Definition AmountSpec.h:116
AmountSpec toAmountSpec(STAmount const &amt)
Definition AmountSpec.h:150
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:176
AmountSpec()=default
std::optional< Currency > currency
Definition AmountSpec.h:23
std::optional< AccountID > issuer
Definition AmountSpec.h:22
friend std::ostream & operator<<(std::ostream &stream, AmountSpec const &amt)
Definition AmountSpec.h:26
EitherAmount(XRPAmount const &a)
Definition AmountSpec.h:63
friend std::ostream & operator<<(std::ostream &stream, EitherAmount const &amt)
Definition AmountSpec.h:86
EitherAmount(IOUAmount const &a)
Definition AmountSpec.h:54
EitherAmount(AmountSpec const &a)
Definition AmountSpec.h:73