rippled
Loading...
Searching...
No Matches
AmountSpec.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_PATH_IMPL_AMOUNTSPEC_H_INCLUDED
21#define RIPPLE_PATH_IMPL_AMOUNTSPEC_H_INCLUDED
22
23#include <xrpl/protocol/IOUAmount.h>
24#include <xrpl/protocol/STAmount.h>
25#include <xrpl/protocol/XRPAmount.h>
26
27#include <optional>
28
29namespace ripple {
30
32{
33 explicit AmountSpec() = default;
34
35 bool native;
36 union
37 {
40 };
43
45 operator<<(std::ostream& stream, AmountSpec const& amt)
46 {
47 if (amt.native)
48 stream << to_string(amt.xrp);
49 else
50 stream << to_string(amt.iou);
51 if (amt.currency)
52 stream << "/(" << *amt.currency << ")";
53 if (amt.issuer)
54 stream << "/" << *amt.issuer << "";
55 return stream;
56 }
57};
58
60{
61#ifndef NDEBUG
62 bool native = false;
63#endif
64
65 union
66 {
69 };
70
71 EitherAmount() = default;
72
73 explicit EitherAmount(IOUAmount const& a) : iou(a)
74 {
75 }
76
77#if defined(__GNUC__) && !defined(__clang__)
78#pragma GCC diagnostic push
79 // ignore warning about half of iou amount being uninitialized
80#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
81#endif
82 explicit EitherAmount(XRPAmount const& a) : xrp(a)
83 {
84#ifndef NDEBUG
85 native = true;
86#endif
87 }
88#if defined(__GNUC__) && !defined(__clang__)
89#pragma GCC diagnostic pop
90#endif
91
92 explicit EitherAmount(AmountSpec const& a)
93 {
94#ifndef NDEBUG
95 native = a.native;
96#endif
97 if (a.native)
98 xrp = a.xrp;
99 else
100 iou = a.iou;
101 }
102
103#ifndef NDEBUG
105 operator<<(std::ostream& stream, EitherAmount const& amt)
106 {
107 if (amt.native)
108 stream << to_string(amt.xrp);
109 else
110 stream << to_string(amt.iou);
111 return stream;
112 }
113#endif
114};
115
116template <class T>
117T&
119{
120 static_assert(sizeof(T) == -1, "Must used specialized function");
121 return T(0);
122}
123
124template <>
127{
128 XRPL_ASSERT(
129 !amt.native, "ripple::get<IOUAmount>(EitherAmount&) : is not XRP");
130 return amt.iou;
131}
132
133template <>
136{
137 XRPL_ASSERT(amt.native, "ripple::get<XRPAmount>(EitherAmount&) : is XRP");
138 return amt.xrp;
139}
140
141template <class T>
142T const&
143get(EitherAmount const& amt)
144{
145 static_assert(sizeof(T) == -1, "Must used specialized function");
146 return T(0);
147}
148
149template <>
150inline IOUAmount const&
152{
153 XRPL_ASSERT(
154 !amt.native,
155 "ripple::get<IOUAmount>(EitherAmount const&) : is not XRP");
156 return amt.iou;
157}
158
159template <>
160inline XRPAmount const&
162{
163 XRPL_ASSERT(
164 amt.native, "ripple::get<XRPAmount>(EitherAmount const&) : is XRP");
165 return amt.xrp;
166}
167
168inline AmountSpec
170{
171 XRPL_ASSERT(
173 "ripple::toAmountSpec(STAmount const&) : maximum mantissa");
174 bool const isNeg = amt.negative();
175 std::int64_t const sMant =
176 isNeg ? -std::int64_t(amt.mantissa()) : amt.mantissa();
177 AmountSpec result;
178
179 result.native = isXRP(amt);
180 if (result.native)
181 {
182 result.xrp = XRPAmount(sMant);
183 }
184 else
185 {
186 result.iou = IOUAmount(sMant, amt.exponent());
187 result.issuer = amt.issue().account;
188 result.currency = amt.issue().currency;
189 }
190
191 return result;
192}
193
194inline EitherAmount
196{
197 if (isXRP(amt))
198 return EitherAmount{amt.xrp()};
199 return EitherAmount{amt.iou()};
200}
201
202inline AmountSpec
204{
205 AmountSpec r;
206 r.native = (!c || isXRP(*c));
207 r.currency = c;
208 XRPL_ASSERT(
209 ea.native == r.native,
210 "ripple::toAmountSpec(EitherAmount const&&, std::optional<Currency>) : "
211 "matching native");
212 if (r.native)
213 {
214 r.xrp = ea.xrp;
215 }
216 else
217 {
218 r.iou = ea.iou;
219 }
220 return r;
221}
222
223} // namespace ripple
224
225#endif
Floating point representation of amounts with high dynamic range.
Definition IOUAmount.h:46
AccountID account
Definition Issue.h:36
Currency currency
Definition Issue.h:35
IOUAmount iou() const
Definition STAmount.cpp:299
int exponent() const noexcept
Definition STAmount.h:452
XRPAmount xrp() const
Definition STAmount.cpp:283
bool negative() const noexcept
Definition STAmount.h:471
Issue const & issue() const
Definition STAmount.h:496
std::uint64_t mantissa() const noexcept
Definition STAmount.h:477
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition algorithm.h:25
IOUAmount & get< IOUAmount >(EitherAmount &amt)
Definition AmountSpec.h:126
bool isXRP(AccountID const &c)
Definition AccountID.h:90
XRPAmount & get< XRPAmount >(EitherAmount &amt)
Definition AmountSpec.h:135
AmountSpec toAmountSpec(STAmount const &amt)
Definition AmountSpec.h:169
std::string to_string(base_uint< Bits, Tag > const &a)
Definition base_uint.h:630
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:195
AmountSpec()=default
std::optional< Currency > currency
Definition AmountSpec.h:42
std::optional< AccountID > issuer
Definition AmountSpec.h:41
friend std::ostream & operator<<(std::ostream &stream, AmountSpec const &amt)
Definition AmountSpec.h:45
EitherAmount(XRPAmount const &a)
Definition AmountSpec.h:82
friend std::ostream & operator<<(std::ostream &stream, EitherAmount const &amt)
Definition AmountSpec.h:105
EitherAmount(IOUAmount const &a)
Definition AmountSpec.h:73
EitherAmount(AmountSpec const &a)
Definition AmountSpec.h:92