rippled
Loading...
Searching...
No Matches
src/test/jtx/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 <test/jtx/Account.h>
24#include <test/jtx/amount.h>
25#include <test/jtx/tags.h>
26#include <xrpl/basics/contract.h>
27#include <xrpl/protocol/FeeUnits.h>
28#include <xrpl/protocol/Issue.h>
29#include <xrpl/protocol/STAmount.h>
30#include <cstdint>
31#include <ostream>
32#include <string>
33#include <type_traits>
34
35namespace ripple {
36namespace test {
37namespace jtx {
38
39/*
40
41The decision was made to accept amounts of drops and XRP
42using an int type, since the range of XRP is 100 billion
43and having both signed and unsigned overloads creates
44tricky code leading to overload resolution ambiguities.
45
46*/
47
48struct 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//
57struct 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).
67constexpr XRPAmount dropsPerXRP{1'000'000};
68
74{
75private:
76 // VFALCO TODO should be Amount
79
80public:
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
137inline bool
138operator==(PrettyAmount const& lhs, PrettyAmount const& rhs)
139{
140 return lhs.value() == rhs.value();
141}
142
143inline bool
144operator!=(PrettyAmount const& lhs, PrettyAmount const& rhs)
145{
146 return !operator==(lhs, rhs);
147}
148
150operator<<(std::ostream& os, PrettyAmount const& amount);
151
152//------------------------------------------------------------------------------
153
154// Specifies an order book
156{
159
160 BookSpec(AccountID const& account_, ripple::Currency const& currency_)
161 : account(account_), currency(currency_)
162 {
163 }
164};
165
166//------------------------------------------------------------------------------
167
168struct 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 }
214 None
216 {
217 return {xrpIssue()};
218 }
219
220 friend BookSpec
222 {
223 return BookSpec(xrpAccount(), xrpCurrency());
224 }
225};
226
233extern XRP_t const XRP;
234
240template <class Integer, class = std::enable_if_t<std::is_integral_v<Integer>>>
242drops(Integer i)
243{
244 return {i};
245}
246
252inline PrettyAmount
254{
255 return {i};
256}
257
258//------------------------------------------------------------------------------
259
260namespace detail {
261
263{
265};
266
267} // namespace detail
268
269// The smallest possible IOU STAmount
271{
273 {
274 }
275
278 {
279 return {n};
280 }
281};
282
283static epsilon_t const epsilon;
284
292class IOU
293{
294public:
297
298 IOU(Account const& account_, ripple::Currency const& currency_)
299 : account(account_), currency(currency_)
300 {
301 }
302
303 Issue
304 issue() const
305 {
306 return {currency, account.id()};
307 }
308
314 operator Issue() const
315 {
316 return issue();
317 }
318 operator Asset() const
319 {
320 return issue();
321 }
322
323 template <
324 class T,
325 class = std::enable_if_t<
326 sizeof(T) >= sizeof(int) && std::is_arithmetic<T>::value>>
328 operator()(T v) const
329 {
330 // VFALCO NOTE Should throw if the
331 // representation of v is not exact.
333 }
334
336 operator()(epsilon_t) const;
339
340 // VFALCO TODO
341 // STAmount operator()(char const* s) const;
342
344 None
346 {
347 return {issue()};
348 }
349
350 friend BookSpec
351 operator~(IOU const& iou)
352 {
353 return BookSpec(iou.account.id(), iou.currency);
354 }
355};
356
358operator<<(std::ostream& os, IOU const& iou);
359
360//------------------------------------------------------------------------------
361
369class MPT
370{
371public:
374
375 MPT(std::string const& n, ripple::MPTID const& issuanceID_)
376 : name(n), issuanceID(issuanceID_)
377 {
378 }
379
380 ripple::MPTID const&
381 mpt() const
382 {
383 return issuanceID;
384 }
385
391 operator ripple::MPTIssue() const
392 {
393 return MPTIssue{issuanceID};
394 }
395
396 template <class T>
397 requires(sizeof(T) >= sizeof(int) && std::is_arithmetic_v<T>)
399 operator()(T v) const
400 {
401 return {amountFromString(mpt(), std::to_string(v)), name};
402 }
403
408
409 friend BookSpec
411 {
412 assert(false);
413 Throw<std::logic_error>("MPT is not supported");
414 return BookSpec{beast::zero, noCurrency()};
415 }
416};
417
419operator<<(std::ostream& os, MPT const& mpt);
420
421//------------------------------------------------------------------------------
422
423struct any_t
424{
425 inline AnyAmount
426 operator()(STAmount const& sta) const;
427};
428
431{
432 bool is_any;
434
435 AnyAmount() = delete;
436 AnyAmount(AnyAmount const&) = default;
437 AnyAmount&
438 operator=(AnyAmount const&) = default;
439
440 AnyAmount(STAmount const& amount) : is_any(false), value(amount)
441 {
442 }
443
444 AnyAmount(STAmount const& amount, any_t const*)
445 : is_any(true), value(amount)
446 {
447 }
448
449 // Reset the issue to a specific account
450 void
451 to(AccountID const& id)
452 {
453 if (!is_any)
454 return;
455 value.setIssuer(id);
456 }
457};
458
459inline AnyAmount
461{
462 return AnyAmount(sta, this);
463}
464
468extern any_t const any;
469
470} // namespace jtx
471} // namespace test
472} // namespace ripple
473
474#endif
A currency issued by an account.
Definition: Issue.h:36
void setIssuer(AccountID const &uIssuer)
Definition: STAmount.h:569
constexpr value_type drops() const
Returns the number of drops.
Definition: XRPAmount.h:177
Immutable cryptographic account descriptor.
Definition: Account.h:38
AccountID id() const
Returns the Account ID.
Definition: Account.h:106
std::string const & name() const
Return the name.
Definition: Account.h:82
Converts to IOU Issue or STAmount.
IOU(Account const &account_, ripple::Currency const &currency_)
friend BookSpec operator~(IOU const &iou)
None operator()(none_t) const
Returns None-of-Issue.
PrettyAmount operator()(T v) const
Converts to MPT Issue or STAmount.
friend BookSpec operator~(MPT const &mpt)
PrettyAmount operator()(epsilon_t) const
MPT(std::string const &n, ripple::MPTID const &issuanceID_)
ripple::MPTID const & mpt() const
PrettyAmount operator()(detail::epsilon_multiple) const
PrettyAmount drops(Integer i)
Returns an XRP PrettyAmount, which is trivially convertible to STAmount.
std::ostream & operator<<(std::ostream &os, PrettyAmount const &amount)
Definition: amount.cpp:72
constexpr XRPAmount dropsPerXRP
bool operator!=(PrettyAmount const &lhs, PrettyAmount const &rhs)
static epsilon_t const epsilon
any_t const any
Returns an amount representing "any issuer".
Definition: amount.cpp:126
bool operator==(Account const &lhs, Account const &rhs) noexcept
Definition: Account.h:149
XRP_t const XRP
Converts to XRP Issue or STAmount.
Definition: amount.cpp:104
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition: algorithm.h:26
Issue const & xrpIssue()
Returns an asset specifier that represents XRP.
Definition: Issue.h:118
STAmount amountFromString(Asset const &issue, std::string const &amount)
Definition: STAmount.cpp:834
AccountID const & xrpAccount()
Compute AccountID from public key.
Definition: AccountID.cpp:170
Currency const & noCurrency()
A placeholder for empty currencies.
Definition: UintTypes.cpp:122
Currency const & xrpCurrency()
XRP currency.
Definition: UintTypes.cpp:115
T round(T... args)
Amount specifier with an option for any issuer.
void to(AccountID const &id)
AnyAmount(STAmount const &amount)
AnyAmount(STAmount const &amount, any_t const *)
AnyAmount & operator=(AnyAmount const &)=default
AnyAmount(AnyAmount const &)=default
BookSpec(AccountID const &account_, ripple::Currency const &currency_)
Represents an XRP or IOU quantity This customizes the string conversion and supports XRP conversions ...
PrettyAmount(PrettyAmount const &)=default
STAmount const & value() const
PrettyAmount(STAmount const &amount, std::string const &name)
PrettyAmount(T v, std::enable_if_t< sizeof(T) >=sizeof(int) &&std::is_integral_v< T > &&std::is_signed_v< T > > *=nullptr)
drops
std::string const & name() const
PrettyAmount(T v, std::enable_if_t< sizeof(T) >=sizeof(int) &&std::is_unsigned_v< T > > *=nullptr)
drops
PrettyAmount & operator=(PrettyAmount const &)=default
friend BookSpec operator~(XRP_t const &)
None operator()(none_t) const
Returns None-of-XRP.
PrettyAmount operator()(double v) const
PrettyAmount operator()(T v) const
Returns an amount of XRP as PrettyAmount, which is trivially convertable to STAmount.
AnyAmount operator()(STAmount const &sta) const
detail::epsilon_multiple operator()(std::size_t n) const
T to_string(T... args)