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