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 xrpl {
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
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
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);
208 return {amount, ""};
209 }
210
211 None
213 {
214 return {asset_};
215 }
216
217 bool
218 integral() const
219 {
220 return asset_.integral();
221 }
222
223 bool
224 native() const
225 {
226 return asset_.native();
227 }
228
229 template <ValidIssueType TIss>
230 bool
231 holds() const
232 {
233 return asset_.holds<TIss>();
234 }
235};
236//------------------------------------------------------------------------------
237
238// Specifies an order book
240{
243
244 BookSpec(AccountID const& account_, xrpl::Currency const& currency_)
245 : account(account_), currency(currency_)
246 {
247 }
248};
249
250//------------------------------------------------------------------------------
251
252struct XRP_t
253{
259 operator Issue() const
260 {
261 return xrpIssue();
262 }
263
270 template <class T, class = std::enable_if_t<std::is_integral_v<T>>>
272 operator()(T v) const
273 {
274 using TOut = std::
276 return {TOut{v} * dropsPerXRP};
277 }
278
286 {
287 auto const c = dropsPerXRP.drops();
288 auto const d = std::int64_t(v * c);
289 if (Number(d) / c != v)
290 Throw<std::domain_error>("unrepresentable");
291 return {d};
292 }
293
295 operator()(double v) const
296 {
297 auto const c = dropsPerXRP.drops();
298 if (v >= 0)
299 {
300 auto const d = std::uint64_t(std::round(v * c));
301 if (double(d) / c != v)
302 Throw<std::domain_error>("unrepresentable");
303 return {d};
304 }
305 auto const d = std::int64_t(std::round(v * c));
306 if (double(d) / c != v)
307 Throw<std::domain_error>("unrepresentable");
308 return {d};
309 }
313 None
315 {
316 return {xrpIssue()};
317 }
318
319 friend BookSpec
321 {
322 return BookSpec(xrpAccount(), xrpCurrency());
323 }
324};
325
332extern XRP_t const XRP;
333
339template <class Integer, class = std::enable_if_t<std::is_integral_v<Integer>>>
341drops(Integer i)
342{
343 return {i};
344}
345
351inline PrettyAmount
353{
354 return {i};
355}
356
357//------------------------------------------------------------------------------
358
359// The smallest possible IOU STAmount
361{
363 {
364 }
365
368 {
369 return {n};
370 }
371};
372
373static epsilon_t const epsilon;
374
382class IOU
383{
384public:
387
388 IOU(Account const& account_, xrpl::Currency const& currency_)
389 : account(account_), currency(currency_)
390 {
391 }
392
393 Issue
394 issue() const
395 {
396 return {currency, account.id()};
397 }
398 Asset
399 asset() const
400 {
401 return issue();
402 }
403
409 operator Issue() const
410 {
411 return issue();
412 }
413 operator PrettyAsset() const
414 {
415 return asset();
416 }
417
418 template <
419 class T,
420 class = std::enable_if_t<
421 sizeof(T) >= sizeof(int) && std::is_arithmetic<T>::value>>
423 operator()(T v) const
424 {
425 // VFALCO NOTE Should throw if the
426 // representation of v is not exact.
428 }
429
431 operator()(epsilon_t) const;
434
435 // VFALCO TODO
436 // STAmount operator()(char const* s) const;
437
439 None
441 {
442 return {issue()};
443 }
444
445 friend BookSpec
446 operator~(IOU const& iou)
447 {
448 return BookSpec(iou.account.id(), iou.currency);
449 }
450};
451
453operator<<(std::ostream& os, IOU const& iou);
454
455//------------------------------------------------------------------------------
456
464class MPT
465{
466public:
469
470 MPT(std::string const& n, xrpl::MPTID const& issuanceID_)
471 : name(n), issuanceID(issuanceID_)
472 {
473 }
474
475 xrpl::MPTID const&
476 mpt() const
477 {
478 return issuanceID;
479 }
480
484 mptIssue() const
485 {
486 return MPTIssue{issuanceID};
487 }
488 Asset
489 asset() const
490 {
491 return mptIssue();
492 }
493
499 operator xrpl::MPTIssue() const
500 {
501 return mptIssue();
502 }
503
504 operator PrettyAsset() const
505 {
506 return asset();
507 }
508
509 template <class T>
510 requires(sizeof(T) >= sizeof(int) && std::is_arithmetic_v<T>)
512 operator()(T v) const
513 {
514 return {amountFromString(mpt(), std::to_string(v)), name};
515 }
516
521
523 None
525 {
526 return {mptIssue()};
527 }
528
529 friend BookSpec
531 {
532 assert(false);
533 Throw<std::logic_error>("MPT is not supported");
534 return BookSpec{beast::zero, noCurrency()};
535 }
536};
537
539operator<<(std::ostream& os, MPT const& mpt);
540
541//------------------------------------------------------------------------------
542
543struct any_t
544{
545 inline AnyAmount
546 operator()(STAmount const& sta) const;
547};
548
551{
552 bool is_any;
554
555 AnyAmount() = delete;
556 AnyAmount(AnyAmount const&) = default;
557 AnyAmount&
558 operator=(AnyAmount const&) = default;
559
561 {
562 }
563
565 : is_any(true), value(amount)
566 {
567 }
568
569 // Reset the issue to a specific account
570 void
571 to(AccountID const& id)
572 {
573 if (!is_any)
574 return;
575 value.setIssuer(id);
576 }
577};
578
579inline AnyAmount
581{
582 return AnyAmount(sta, this);
583}
584
588extern any_t const any;
589
590} // namespace jtx
591} // namespace test
592} // namespace xrpl
593
594#endif
Represents a JSON value.
Definition json_value.h:131
bool integral() const
Definition Asset.h:95
bool native() const
Definition Asset.h:82
constexpr bool holds() const
Definition Asset.h:133
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:580
int signum() const noexcept
Definition STAmount.h:506
constexpr value_type drops() const
Returns the number of drops.
Definition XRPAmount.h:158
Immutable cryptographic account descriptor.
Definition Account.h:20
std::string const & name() const
Return the name.
Definition Account.h:68
AccountID id() const
Returns the Account ID.
Definition Account.h:92
Converts to IOU Issue or STAmount.
PrettyAmount operator()(T v) const
friend BookSpec operator~(IOU const &iou)
IOU(Account const &account_, xrpl::Currency const &currency_)
None operator()(none_t) const
Returns None-of-Issue.
Converts to MPT Issue or STAmount.
friend BookSpec operator~(MPT const &mpt)
xrpl::MPTIssue mptIssue() const
Explicit conversion to MPTIssue or asset.
MPT(std::string const &n, xrpl::MPTID const &issuanceID_)
PrettyAmount operator()(epsilon_t) const
xrpl::MPTID const & mpt() const
PrettyAmount operator()(detail::epsilon_multiple) const
None operator()(none_t) const
Returns None-of-Issue.
T is_same_v
any_t const any
Returns an amount representing "any issuer".
Definition amount.cpp:114
static epsilon_t const epsilon
std::ostream & operator<<(std::ostream &os, PrettyAmount const &amount)
Definition amount.cpp:54
XRP_t const XRP
Converts to XRP Issue or STAmount.
Definition amount.cpp:92
constexpr XRPAmount dropsPerXRP
bool operator!=(PrettyAmount const &lhs, PrettyAmount const &rhs)
auto const amount
bool operator==(Account const &lhs, Account const &rhs) noexcept
Definition Account.h:135
PrettyAmount drops(Integer i)
Returns an XRP PrettyAmount, which is trivially convertible to STAmount.
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
STAmount amountFromString(Asset const &asset, std::string const &amount)
Definition STAmount.cpp:977
Currency const & xrpCurrency()
XRP currency.
Json::Value to_json(Asset const &asset)
Definition Asset.h:124
Currency const & noCurrency()
A placeholder for empty currencies.
AccountID const & xrpAccount()
Compute AccountID from public key.
T round(T... args)
Amount specifier with an option for any issuer.
AnyAmount(AnyAmount const &)=default
void to(AccountID const &id)
AnyAmount & operator=(AnyAmount const &)=default
AnyAmount(STAmount const &amount, any_t const *)
AnyAmount(STAmount const &amount)
BookSpec(AccountID const &account_, xrpl::Currency const &currency_)
Represents an XRP or IOU quantity This customizes the string conversion and supports XRP conversions ...
std::string const & name() const
PrettyAmount(T v, std::enable_if_t< sizeof(T) >=sizeof(int) &&std::is_unsigned_v< T > > *=nullptr)
drops
PrettyAmount(STAmount const &amount, std::string const &name)
PrettyAmount(PrettyAmount const &)=default
STAmount const & value() const
PrettyAmount & operator=(PrettyAmount const &)=default
PrettyAmount(T v, std::enable_if_t< sizeof(T) >=sizeof(int) &&std::is_integral_v< T > &&std::is_signed_v< T > > *=nullptr)
drops
PrettyAsset(Asset const &asset, std::uint32_t scale=1)
PrettyAmount operator()(T v, Number::rounding_mode rounding=Number::getround()) const
PrettyAsset(A const &asset, std::uint32_t scale=1)
PrettyAmount operator()(Number v, Number::rounding_mode rounding=Number::getround()) const
None operator()(none_t) const
Returns None-of-XRP.
friend BookSpec operator~(XRP_t const &)
PrettyAmount operator()(double v) const
PrettyAmount operator()(Number v) const
Returns an amount of XRP as PrettyAmount, which is trivially convertible to STAmount.
PrettyAmount operator()(T v) const
Returns an amount of XRP as PrettyAmount, which is trivially convertible to STAmount.
AnyAmount operator()(STAmount const &sta) const
detail::epsilon_multiple operator()(std::size_t n) const
T to_string(T... args)