rippled
amount.h
1 //------------------------------------------------------------------------------
2 /*
3  This file is part of rippled: https://github.com/ripple/rippled
4  Copyright (c) 2012-2015 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_TEST_JTX_AMOUNT_H_INCLUDED
21 #define RIPPLE_TEST_JTX_AMOUNT_H_INCLUDED
22 
23 #include <ripple/basics/FeeUnits.h>
24 #include <ripple/basics/contract.h>
25 #include <ripple/protocol/Issue.h>
26 #include <ripple/protocol/STAmount.h>
27 #include <cstdint>
28 #include <ostream>
29 #include <string>
30 #include <test/jtx/Account.h>
31 #include <test/jtx/amount.h>
32 #include <test/jtx/tags.h>
33 #include <type_traits>
34 
35 namespace ripple {
36 namespace test {
37 namespace jtx {
38 
39 /*
40 
41 The decision was made to accept amounts of drops and XRP
42 using an int type, since the range of XRP is 100 billion
43 and having both signed and unsigned overloads creates
44 tricky code leading to overload resolution ambiguities.
45 
46 */
47 
48 struct AnyAmount;
49 
50 // Represents "no amount" of a currency
51 // This is distinct from zero or a balance.
52 // For example, no USD means the trust line
53 // doesn't even exist. Using this in an
54 // inappropriate context will generate a
55 // compile error.
56 //
57 struct None
58 {
60 };
61 
62 //------------------------------------------------------------------------------
63 
64 // This value is also defined in SystemParameters.h. It's
65 // duplicated here to catch any possible future errors that
66 // could change that value (however unlikely).
67 constexpr XRPAmount dropsPerXRP{1'000'000};
68 
74 {
75 private:
76  // VFALCO TODO should be Amount
79 
80 public:
81  PrettyAmount() = default;
82  PrettyAmount(PrettyAmount const&) = default;
84  operator=(PrettyAmount const&) = default;
85 
86  PrettyAmount(STAmount const& amount, std::string const& name)
87  : amount_(amount), name_(name)
88  {
89  }
90 
92  template <class T>
94  T v,
96  sizeof(T) >= sizeof(int) && std::is_integral_v<T> &&
97  std::is_signed_v<T>>* = nullptr)
98  : amount_((v > 0) ? v : -v, v < 0)
99  {
100  }
101 
103  template <class T>
105  T v,
106  std::enable_if_t<sizeof(T) >= sizeof(int) && std::is_unsigned_v<T>>* =
107  nullptr)
108  : amount_(v)
109  {
110  }
111 
114  {
115  }
116 
117  std::string const&
118  name() const
119  {
120  return name_;
121  }
122 
123  STAmount const&
124  value() const
125  {
126  return amount_;
127  }
128 
129  operator STAmount const &() const
130  {
131  return amount_;
132  }
133 
134  operator AnyAmount() const;
135 };
136 
137 inline bool
138 operator==(PrettyAmount const& lhs, PrettyAmount const& rhs)
139 {
140  return lhs.value() == rhs.value();
141 }
142 
143 inline bool
144 operator!=(PrettyAmount const& lhs, PrettyAmount const& rhs)
145 {
146  return !operator==(lhs, rhs);
147 }
148 
150 operator<<(std::ostream& os, PrettyAmount const& amount);
151 
152 //------------------------------------------------------------------------------
153 
154 // Specifies an order book
155 struct BookSpec
156 {
159 
160  BookSpec(AccountID const& account_, ripple::Currency const& currency_)
161  : account(account_), currency(currency_)
162  {
163  }
164 };
165 
166 //------------------------------------------------------------------------------
167 
168 struct XRP_t
169 {
175  operator Issue() const
176  {
177  return xrpIssue();
178  }
179 
186  template <class T, class = std::enable_if_t<std::is_integral_v<T>>>
188  operator()(T v) const
189  {
190  using TOut = std::
191  conditional_t<std::is_signed_v<T>, std::int64_t, std::uint64_t>;
192  return {TOut{v} * dropsPerXRP};
193  }
194 
196  operator()(double v) const
197  {
198  auto const c = dropsPerXRP.drops();
199  if (v >= 0)
200  {
201  auto const d = std::uint64_t(std::round(v * c));
202  if (double(d) / c != v)
203  Throw<std::domain_error>("unrepresentable");
204  return {d};
205  }
206  auto const d = std::int64_t(std::round(v * c));
207  if (double(d) / c != v)
208  Throw<std::domain_error>("unrepresentable");
209  return {d};
210  }
215  {
216  return {xrpIssue()};
217  }
218 
219  friend BookSpec
220  operator~(XRP_t const&)
221  {
222  return BookSpec(xrpAccount(), xrpCurrency());
223  }
224 };
225 
232 extern XRP_t const XRP;
233 
239 template <class Integer, class = std::enable_if_t<std::is_integral_v<Integer>>>
241 drops(Integer i)
242 {
243  return {i};
244 }
245 
251 inline PrettyAmount
253 {
254  return {i};
255 }
256 
257 //------------------------------------------------------------------------------
258 
259 namespace detail {
260 
262 {
264 };
265 
266 } // namespace detail
267 
268 // The smallest possible IOU STAmount
269 struct epsilon_t
270 {
272  {
273  }
274 
277  {
278  return {n};
279  }
280 };
281 
282 static epsilon_t const epsilon;
283 
291 class IOU
292 {
293 public:
296 
297  IOU(Account const& account_, ripple::Currency const& currency_)
298  : account(account_), currency(currency_)
299  {
300  }
301 
302  Issue
303  issue() const
304  {
305  return {currency, account.id()};
306  }
307 
313  operator Issue() const
314  {
315  return issue();
316  }
317 
318  template <
319  class T,
320  class = std::enable_if_t<
321  sizeof(T) >= sizeof(int) && std::is_arithmetic<T>::value>>
323  operator()(T v) const
324  {
325  // VFALCO NOTE Should throw if the
326  // representation of v is not exact.
327  return {amountFromString(issue(), std::to_string(v)), account.name()};
328  }
329 
332 
333  // VFALCO TODO
334  // STAmount operator()(char const* s) const;
335 
338  {
339  return {issue()};
340  }
341 
342  friend BookSpec
343  operator~(IOU const& iou)
344  {
345  return BookSpec(iou.account.id(), iou.currency);
346  }
347 };
348 
350 operator<<(std::ostream& os, IOU const& iou);
351 
352 //------------------------------------------------------------------------------
353 
354 struct any_t
355 {
356  inline AnyAmount
357  operator()(STAmount const& sta) const;
358 };
359 
361 struct AnyAmount
362 {
363  bool is_any;
365 
366  AnyAmount() = delete;
367  AnyAmount(AnyAmount const&) = default;
368  AnyAmount&
369  operator=(AnyAmount const&) = default;
370 
371  AnyAmount(STAmount const& amount) : is_any(false), value(amount)
372  {
373  }
374 
375  AnyAmount(STAmount const& amount, any_t const*)
376  : is_any(true), value(amount)
377  {
378  }
379 
380  // Reset the issue to a specific account
381  void
382  to(AccountID const& id)
383  {
384  if (!is_any)
385  return;
386  value.setIssuer(id);
387  }
388 };
389 
390 inline AnyAmount
391 any_t::operator()(STAmount const& sta) const
392 {
393  return AnyAmount(sta, this);
394 }
395 
399 extern any_t const any;
400 
401 } // namespace jtx
402 } // namespace test
403 } // namespace ripple
404 
405 #endif
ripple::test::jtx::Account::name
std::string const & name() const
Return the name.
Definition: Account.h:82
ripple::test::jtx::XRP_t::operator~
friend BookSpec operator~(XRP_t const &)
Definition: amount.h:220
ripple::test::jtx::epsilon_t::epsilon_t
epsilon_t()
Definition: amount.h:271
ripple::test::jtx::PrettyAmount::PrettyAmount
PrettyAmount(T v, std::enable_if_t< sizeof(T) >=sizeof(int) &&std::is_unsigned_v< T >> *=nullptr)
drops
Definition: amount.h:104
ripple::test::jtx::epsilon_t
Definition: amount.h:269
ripple::test::jtx::XRP
const XRP_t XRP
Converts to XRP Issue or STAmount.
Definition: amount.cpp:105
ripple::test::jtx::PrettyAmount::PrettyAmount
PrettyAmount(T v, std::enable_if_t< sizeof(T) >=sizeof(int) &&std::is_integral_v< T > &&std::is_signed_v< T >> *=nullptr)
drops
Definition: amount.h:93
ripple::test::jtx::PrettyAmount::PrettyAmount
PrettyAmount(XRPAmount v)
drops
Definition: amount.h:113
ripple::test::jtx::dropsPerXRP
constexpr XRPAmount dropsPerXRP
Definition: amount.h:67
ripple::Issue
A currency issued by an account.
Definition: Issue.h:34
std::string
STL class.
ripple::test::jtx::any_t
Definition: amount.h:354
ripple::test::jtx::operator<<
std::ostream & operator<<(std::ostream &os, PrettyAmount const &amount)
Definition: amount.cpp:73
ripple::test::jtx::XRP_t::operator()
PrettyAmount operator()(double v) const
Definition: amount.h:196
ripple::test::jtx::AnyAmount::AnyAmount
AnyAmount()=delete
ripple::test::jtx::drops
PrettyAmount drops(Integer i)
Returns an XRP PrettyAmount, which is trivially convertible to STAmount.
Definition: amount.h:241
ripple::test::jtx::detail::epsilon_multiple::n
std::size_t n
Definition: amount.h:263
ripple::XRPAmount::drops
constexpr value_type drops() const
Returns the number of drops.
Definition: XRPAmount.h:172
ripple::test::jtx::BookSpec::currency
ripple::Currency currency
Definition: amount.h:158
ripple::test::jtx::PrettyAmount::PrettyAmount
PrettyAmount()=default
ripple::test::jtx::AnyAmount
Amount specifier with an option for any issuer.
Definition: amount.h:361
ripple::test::jtx::IOU::operator()
None operator()(none_t) const
Returns None-of-Issue.
Definition: amount.h:337
ripple::test::jtx::epsilon_t::operator()
detail::epsilon_multiple operator()(std::size_t n) const
Definition: amount.h:276
ripple::test::jtx::any_t::operator()
AnyAmount operator()(STAmount const &sta) const
Definition: amount.h:391
ripple::test::jtx::PrettyAmount::operator=
PrettyAmount & operator=(PrettyAmount const &)=default
ripple::test::jtx::detail::epsilon_multiple
Definition: amount.h:261
ripple::test::jtx::IOU::issue
Issue issue() const
Definition: amount.h:303
ripple::test::jtx::none_t
Definition: tags.h:28
ripple::test::jtx::AnyAmount::operator=
AnyAmount & operator=(AnyAmount const &)=default
ripple::STAmount::setIssuer
void setIssuer(AccountID const &uIssuer)
Definition: STAmount.h:433
ripple::test::jtx::IOU::account
Account account
Definition: amount.h:294
ripple::test::jtx::XRP_t
Definition: amount.h:168
ripple::test::jtx::BookSpec
Definition: amount.h:155
ripple::test::jtx::AnyAmount::is_any
bool is_any
Definition: amount.h:363
ripple::test::jtx::Account::id
AccountID id() const
Returns the Account ID.
Definition: Account.h:106
ripple::base_uint< 160, detail::AccountIDTag >
ripple::test::jtx::IOU::operator()
PrettyAmount operator()(T v) const
Definition: amount.h:323
ripple::test::jtx::AnyAmount::AnyAmount
AnyAmount(STAmount const &amount)
Definition: amount.h:371
std::is_arithmetic
ripple::test::jtx::IOU::operator~
friend BookSpec operator~(IOU const &iou)
Definition: amount.h:343
ripple::test::jtx::AnyAmount::to
void to(AccountID const &id)
Definition: amount.h:382
ripple::test::jtx::IOU::IOU
IOU(Account const &account_, ripple::Currency const &currency_)
Definition: amount.h:297
ripple::test::jtx::BookSpec::BookSpec
BookSpec(AccountID const &account_, ripple::Currency const &currency_)
Definition: amount.h:160
std::enable_if_t
ripple::test::jtx::any
const any_t any
Returns an amount representing "any issuer".
Definition: amount.cpp:126
std::ostream
STL class.
std::to_string
T to_string(T... args)
ripple::test::jtx::IOU::currency
ripple::Currency currency
Definition: amount.h:295
ripple::STAmount
Definition: STAmount.h:45
ripple::xrpAccount
AccountID const & xrpAccount()
Compute AccountID from public key.
Definition: AccountID.cpp:168
cstdint
std::int64_t
ripple::test::jtx::operator!=
bool operator!=(PrettyAmount const &lhs, PrettyAmount const &rhs)
Definition: amount.h:144
ripple::test::jtx::None::issue
Issue issue
Definition: amount.h:59
ripple::test::jtx::XRP_t::operator()
PrettyAmount operator()(T v) const
Returns an amount of XRP as PrettyAmount, which is trivially convertable to STAmount.
Definition: amount.h:188
ripple::test::jtx::PrettyAmount::name_
std::string name_
Definition: amount.h:78
ripple::test::jtx::None
Definition: amount.h:57
ripple::test::jtx::BookSpec::account
AccountID account
Definition: amount.h:157
ripple
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition: RCLCensorshipDetector.h:29
std::round
T round(T... args)
ripple::test::jtx::PrettyAmount::name
std::string const & name() const
Definition: amount.h:118
ripple::amountFromString
STAmount amountFromString(Issue const &issue, std::string const &amount)
Definition: STAmount.cpp:864
ripple::test::jtx::IOU
Converts to IOU Issue or STAmount.
Definition: amount.h:291
ripple::test::jtx::epsilon
static const epsilon_t epsilon
Definition: amount.h:282
ripple::xrpIssue
Issue const & xrpIssue()
Returns an asset specifier that represents XRP.
Definition: Issue.h:95
ripple::test::jtx::PrettyAmount::value
STAmount const & value() const
Definition: amount.h:124
std::size_t
ripple::test::jtx::PrettyAmount::amount_
STAmount amount_
Definition: amount.h:77
ripple::test::jtx::AnyAmount::AnyAmount
AnyAmount(STAmount const &amount, any_t const *)
Definition: amount.h:375
ripple::test::jtx::Account
Immutable cryptographic account descriptor.
Definition: Account.h:37
ripple::test::jtx::operator==
bool operator==(Account const &lhs, Account const &rhs) noexcept
Definition: Account.h:149
ripple::test::jtx::AnyAmount::value
STAmount value
Definition: amount.h:364
ripple::test::jtx::XRP_t::operator()
None operator()(none_t) const
Returns None-of-XRP.
Definition: amount.h:214
ostream
ripple::test::jtx::PrettyAmount::PrettyAmount
PrettyAmount(STAmount const &amount, std::string const &name)
Definition: amount.h:86
type_traits
ripple::xrpCurrency
Currency const & xrpCurrency()
XRP currency.
Definition: UintTypes.cpp:121
ripple::test::jtx::PrettyAmount
Represents an XRP or IOU quantity This customizes the string conversion and supports XRP conversions ...
Definition: amount.h:73
ripple::XRPAmount
Definition: XRPAmount.h:46
string