rippled
Loading...
Searching...
No Matches
src/test/jtx/amount.h
1#ifndef XRPL_TEST_JTX_AMOUNT_H_INCLUDED
2#define XRPL_TEST_JTX_AMOUNT_H_INCLUDED
3
4#include <test/jtx/Account.h>
5#include <test/jtx/tags.h>
6
7#include <xrpl/basics/contract.h>
8#include <xrpl/protocol/Issue.h>
9#include <xrpl/protocol/STAmount.h>
10#include <xrpl/protocol/Units.h>
11
12#include <cstdint>
13#include <ostream>
14#include <string>
15#include <type_traits>
16
17namespace ripple {
18namespace detail {
19
24
25} // namespace detail
26
27namespace test {
28namespace jtx {
29
30/*
31
32The decision was made to accept amounts of drops and XRP
33using an int type, since the range of XRP is 100 billion
34and having both signed and unsigned overloads creates
35tricky code leading to overload resolution ambiguities.
36
37*/
38
39struct AnyAmount;
40
41// Represents "no amount" of a currency
42// This is distinct from zero or a balance.
43// For example, no USD means the trust line
44// doesn't even exist. Using this in an
45// inappropriate context will generate a
46// compile error.
47//
48struct None
49{
51};
52
53//------------------------------------------------------------------------------
54
55// This value is also defined in SystemParameters.h. It's
56// duplicated here to catch any possible future errors that
57// could change that value (however unlikely).
58constexpr XRPAmount dropsPerXRP{1'000'000};
59
65{
66private:
67 // VFALCO TODO should be Amount
70
71public:
72 PrettyAmount() = default;
73 PrettyAmount(PrettyAmount const&) = default;
75 operator=(PrettyAmount const&) = default;
76
77 PrettyAmount(STAmount const& amount, std::string const& name)
78 : amount_(amount), name_(name)
79 {
80 }
81
83 template <class T>
85 T v,
87 sizeof(T) >= sizeof(int) && std::is_integral_v<T> &&
88 std::is_signed_v<T>>* = nullptr)
89 : amount_((v > 0) ? v : -v, v < 0)
90 {
91 }
92
94 template <class T>
96 T v,
97 std::enable_if_t<sizeof(T) >= sizeof(int) && std::is_unsigned_v<T>>* =
98 nullptr)
99 : amount_(v)
100 {
101 }
102
105 {
106 }
107
108 std::string const&
109 name() const
110 {
111 return name_;
112 }
113
114 STAmount const&
115 value() const
116 {
117 return amount_;
118 }
119
120 Number
121 number() const
122 {
123 return amount_;
124 }
125
126 inline int
127 signum() const
128 {
129 return amount_.signum();
130 }
131
132 operator STAmount const&() const
133 {
134 return amount_;
135 }
136
137 operator AnyAmount() const;
138
139 operator Json::Value() const
140 {
141 return to_json(value());
142 }
143};
144
145inline bool
146operator==(PrettyAmount const& lhs, PrettyAmount const& rhs)
147{
148 return lhs.value() == rhs.value();
149}
150
151inline bool
152operator!=(PrettyAmount const& lhs, PrettyAmount const& rhs)
153{
154 return !operator==(lhs, rhs);
155}
156
158operator<<(std::ostream& os, PrettyAmount const& amount);
159
161{
162private:
165
166public:
167 template <typename A>
169 PrettyAsset(A const& asset, std::uint32_t scale = 1)
170 : PrettyAsset{Asset{asset}, scale}
171 {
172 }
173
174 PrettyAsset(Asset const& asset, std::uint32_t scale = 1)
175 : asset_(asset), scale_(scale)
176 {
177 }
178
179 Asset const&
180 raw() const
181 {
182 return asset_;
183 }
184
185 operator Asset const&() const
186 {
187 return asset_;
188 }
189
190 operator Json::Value() const
191 {
192 return to_json(asset_);
193 }
194
195 template <std::integral T>
198 {
199 return operator()(Number(v), rounding);
200 }
201
204 const
205 {
206 NumberRoundModeGuard mg(rounding);
207 STAmount amount{asset_, v * scale_};
208 return {amount, ""};
209 }
210
211 None
213 {
214 return {asset_};
215 }
216};
217//------------------------------------------------------------------------------
218
219// Specifies an order book
221{
224
225 BookSpec(AccountID const& account_, ripple::Currency const& currency_)
226 : account(account_), currency(currency_)
227 {
228 }
229};
230
231//------------------------------------------------------------------------------
232
233struct XRP_t
234{
240 operator Issue() const
241 {
242 return xrpIssue();
243 }
244
251 template <class T, class = std::enable_if_t<std::is_integral_v<T>>>
253 operator()(T v) const
254 {
255 using TOut = std::
257 return {TOut{v} * dropsPerXRP};
258 }
259
261 operator()(double v) const
262 {
263 auto const c = dropsPerXRP.drops();
264 if (v >= 0)
265 {
266 auto const d = std::uint64_t(std::round(v * c));
267 if (double(d) / c != v)
268 Throw<std::domain_error>("unrepresentable");
269 return {d};
270 }
271 auto const d = std::int64_t(std::round(v * c));
272 if (double(d) / c != v)
273 Throw<std::domain_error>("unrepresentable");
274 return {d};
275 }
279 None
281 {
282 return {xrpIssue()};
283 }
284
285 friend BookSpec
287 {
288 return BookSpec(xrpAccount(), xrpCurrency());
289 }
290};
291
298extern XRP_t const XRP;
299
305template <class Integer, class = std::enable_if_t<std::is_integral_v<Integer>>>
307drops(Integer i)
308{
309 return {i};
310}
311
317inline PrettyAmount
319{
320 return {i};
321}
322
323//------------------------------------------------------------------------------
324
325// The smallest possible IOU STAmount
327{
329 {
330 }
331
334 {
335 return {n};
336 }
337};
338
339static epsilon_t const epsilon;
340
348class IOU
349{
350public:
353
354 IOU(Account const& account_, ripple::Currency const& currency_)
355 : account(account_), currency(currency_)
356 {
357 }
358
359 Issue
360 issue() const
361 {
362 return {currency, account.id()};
363 }
364 Asset
365 asset() const
366 {
367 return issue();
368 }
369
375 operator Issue() const
376 {
377 return issue();
378 }
379 operator PrettyAsset() const
380 {
381 return asset();
382 }
383
384 template <
385 class T,
386 class = std::enable_if_t<
387 sizeof(T) >= sizeof(int) && std::is_arithmetic<T>::value>>
389 operator()(T v) const
390 {
391 // VFALCO NOTE Should throw if the
392 // representation of v is not exact.
394 }
395
397 operator()(epsilon_t) const;
400
401 // VFALCO TODO
402 // STAmount operator()(char const* s) const;
403
405 None
407 {
408 return {issue()};
409 }
410
411 friend BookSpec
412 operator~(IOU const& iou)
413 {
414 return BookSpec(iou.account.id(), iou.currency);
415 }
416};
417
419operator<<(std::ostream& os, IOU const& iou);
420
421//------------------------------------------------------------------------------
422
430class MPT
431{
432public:
435
436 MPT(std::string const& n, ripple::MPTID const& issuanceID_)
437 : name(n), issuanceID(issuanceID_)
438 {
439 }
440
441 ripple::MPTID const&
442 mpt() const
443 {
444 return issuanceID;
445 }
446
450 mptIssue() const
451 {
452 return MPTIssue{issuanceID};
453 }
454 Asset
455 asset() const
456 {
457 return mptIssue();
458 }
459
465 operator ripple::MPTIssue() const
466 {
467 return mptIssue();
468 }
469
470 operator PrettyAsset() const
471 {
472 return asset();
473 }
474
475 template <class T>
476 requires(sizeof(T) >= sizeof(int) && std::is_arithmetic_v<T>)
478 operator()(T v) const
479 {
480 return {amountFromString(mpt(), std::to_string(v)), name};
481 }
482
487
489 None
491 {
492 return {mptIssue()};
493 }
494
495 friend BookSpec
497 {
498 assert(false);
499 Throw<std::logic_error>("MPT is not supported");
500 return BookSpec{beast::zero, noCurrency()};
501 }
502};
503
505operator<<(std::ostream& os, MPT const& mpt);
506
507//------------------------------------------------------------------------------
508
509struct any_t
510{
511 inline AnyAmount
512 operator()(STAmount const& sta) const;
513};
514
517{
518 bool is_any;
520
521 AnyAmount() = delete;
522 AnyAmount(AnyAmount const&) = default;
523 AnyAmount&
524 operator=(AnyAmount const&) = default;
525
526 AnyAmount(STAmount const& amount) : is_any(false), value(amount)
527 {
528 }
529
530 AnyAmount(STAmount const& amount, any_t const*)
531 : is_any(true), value(amount)
532 {
533 }
534
535 // Reset the issue to a specific account
536 void
537 to(AccountID const& id)
538 {
539 if (!is_any)
540 return;
541 value.setIssuer(id);
542 }
543};
544
545inline AnyAmount
547{
548 return AnyAmount(sta, this);
549}
550
554extern any_t const any;
555
556} // namespace jtx
557} // namespace test
558} // namespace ripple
559
560#endif
Represents a JSON value.
Definition json_value.h:130
A currency issued by an account.
Definition Issue.h:14
static rounding_mode getround()
Definition Number.cpp:28
void setIssuer(AccountID const &uIssuer)
Definition STAmount.h:569
int signum() const noexcept
Definition STAmount.h:495
constexpr value_type drops() const
Returns the number of drops.
Definition XRPAmount.h:158
Immutable cryptographic account descriptor.
Definition Account.h:20
AccountID id() const
Returns the Account ID.
Definition Account.h:92
std::string const & name() const
Return the name.
Definition Account.h:68
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::MPTIssue mptIssue() const
Explicit conversion to MPTIssue or asset.
None operator()(none_t) const
Returns None-of-Issue.
ripple::MPTID const & mpt() const
PrettyAmount operator()(detail::epsilon_multiple) const
T is_same_v
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:54
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:114
bool operator==(Account const &lhs, Account const &rhs) noexcept
Definition Account.h:135
XRP_t const XRP
Converts to XRP Issue or STAmount.
Definition amount.cpp:92
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition algorithm.h:6
Issue const & xrpIssue()
Returns an asset specifier that represents XRP.
Definition Issue.h:96
AccountID const & xrpAccount()
Compute AccountID from public key.
Currency const & noCurrency()
A placeholder for empty currencies.
Json::Value to_json(Asset const &asset)
Definition Asset.h:104
Currency const & xrpCurrency()
XRP currency.
STAmount amountFromString(Asset const &asset, std::string const &amount)
Definition STAmount.cpp:977
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
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
PrettyAmount operator()(Number v, Number::rounding_mode rounding=Number::getround()) const
PrettyAmount operator()(T v, Number::rounding_mode rounding=Number::getround()) const
PrettyAsset(A const &asset, std::uint32_t scale=1)
PrettyAsset(Asset const &asset, std::uint32_t scale=1)
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)