rippled
Loading...
Searching...
No Matches
src/test/jtx/amount.h
1#pragma once
2
3#include <test/jtx/Account.h>
4#include <test/jtx/tags.h>
5
6#include <xrpl/basics/contract.h>
7#include <xrpl/protocol/Issue.h>
8#include <xrpl/protocol/STAmount.h>
9#include <xrpl/protocol/Units.h>
10
11#include <cstdint>
12#include <ostream>
13#include <string>
14#include <type_traits>
15
16namespace xrpl {
17namespace detail {
18
23
24} // namespace detail
25
26namespace test {
27namespace jtx {
28
29/*
30
31The decision was made to accept amounts of drops and XRP
32using an int type, since the range of XRP is 100 billion
33and having both signed and unsigned overloads creates
34tricky code leading to overload resolution ambiguities.
35
36*/
37
38struct AnyAmount;
39
40// Represents "no amount" of a currency
41// This is distinct from zero or a balance.
42// For example, no USD means the trust line
43// doesn't even exist. Using this in an
44// inappropriate context will generate a
45// compile error.
46//
47struct None
48{
50};
51
52//------------------------------------------------------------------------------
53
54// This value is also defined in SystemParameters.h. It's
55// duplicated here to catch any possible future errors that
56// could change that value (however unlikely).
57constexpr XRPAmount dropsPerXRP{1'000'000};
58
64{
65private:
66 // VFALCO TODO should be Amount
69
70public:
71 PrettyAmount() = default;
72 PrettyAmount(PrettyAmount const&) = default;
74 operator=(PrettyAmount const&) = default;
75
79
81 template <class T>
83 T v,
85 sizeof(T) >= sizeof(int) && std::is_integral_v<T> && std::is_signed_v<T>>* = nullptr)
86 : amount_((v > 0) ? v : -v, v < 0)
87 {
88 }
89
91 template <class T>
93 T v,
94 std::enable_if_t<sizeof(T) >= sizeof(int) && std::is_unsigned_v<T>>* = nullptr)
95 : amount_(v)
96 {
97 }
98
101 {
102 }
103
104 std::string const&
105 name() const
106 {
107 return name_;
108 }
109
110 STAmount const&
111 value() const
112 {
113 return amount_;
114 }
115
116 Number
117 number() const
118 {
119 return amount_;
120 }
121
122 inline int
123 signum() const
124 {
125 return amount_.signum();
126 }
127
128 operator STAmount const&() const
129 {
130 return amount_;
131 }
132
133 operator AnyAmount() const;
134
135 operator Json::Value() const
136 {
137 return to_json(value());
138 }
139};
140
141inline bool
142operator==(PrettyAmount const& lhs, PrettyAmount const& rhs)
143{
144 return lhs.value() == rhs.value();
145}
146
147inline bool
148operator!=(PrettyAmount const& lhs, PrettyAmount const& rhs)
149{
150 return !operator==(lhs, rhs);
151}
152
155
157{
158private:
161
162public:
163 template <typename A>
165 PrettyAsset(A const& asset, std::uint32_t scale = 1) : PrettyAsset{Asset{asset}, scale}
166 {
167 }
168
169 PrettyAsset(Asset const& asset, std::uint32_t scale = 1) : asset_(asset), scale_(scale)
170 {
171 }
172
173 Asset const&
174 raw() const
175 {
176 return asset_;
177 }
178
179 operator Asset const&() const
180 {
181 return asset_;
182 }
183
184 operator Json::Value() const
185 {
186 return to_json(asset_);
187 }
188
189 template <std::integral T>
192 {
193 return operator()(Number(v), rounding);
194 }
195
198 {
199 NumberRoundModeGuard const mg(rounding);
200 STAmount const amount{asset_, v * scale_};
201 return {amount, ""};
202 }
203
204 None
206 {
207 return {asset_};
208 }
209
210 bool
211 integral() const
212 {
213 return asset_.integral();
214 }
215
216 bool
217 native() const
218 {
219 return asset_.native();
220 }
221
222 template <ValidIssueType TIss>
223 bool
224 holds() const
225 {
226 return asset_.holds<TIss>();
227 }
228};
229//------------------------------------------------------------------------------
230
231// Specifies an order book
233{
236
237 BookSpec(AccountID const& account_, xrpl::Currency const& currency_)
238 : account(account_), currency(currency_)
239 {
240 }
241};
242
243//------------------------------------------------------------------------------
244
245struct XRP_t
246{
252 operator Issue() const
253 {
254 return xrpIssue();
255 }
256
257 bool
258 integral() const
259 {
260 return true;
261 }
262
269 template <class T, class = std::enable_if_t<std::is_integral_v<T>>>
271 operator()(T v) const
272 {
274 return {TOut{v} * dropsPerXRP};
275 }
276
284 {
285 auto const c = dropsPerXRP.drops();
286 auto const d = std::int64_t(v * c);
287 if (Number(d) / c != v)
288 Throw<std::domain_error>("unrepresentable");
289 return {d};
290 }
291
293 operator()(double v) const
294 {
295 auto const c = dropsPerXRP.drops();
296 if (v >= 0)
297 {
298 auto const d = std::uint64_t(std::round(v * c));
299 if (double(d) / c != v)
300 Throw<std::domain_error>("unrepresentable");
301 return {d};
302 }
303 auto const d = std::int64_t(std::round(v * c));
304 if (double(d) / c != v)
305 Throw<std::domain_error>("unrepresentable");
306 return {d};
307 }
311 None
313 {
314 return {xrpIssue()};
315 }
316
317 friend BookSpec
319 {
320 return BookSpec(xrpAccount(), xrpCurrency());
321 }
322};
323
330extern XRP_t const XRP;
331
337template <class Integer, class = std::enable_if_t<std::is_integral_v<Integer>>>
339drops(Integer i)
340{
341 return {i};
342}
343
349inline PrettyAmount
351{
352 return {i};
353}
354
355//------------------------------------------------------------------------------
356
357// The smallest possible IOU STAmount
359{
361 {
362 }
363
366 {
367 return {n};
368 }
369};
370
371static epsilon_t const epsilon;
372
380class IOU
381{
382public:
385
386 IOU(Account const& account_, xrpl::Currency const& currency_)
387 : account(account_), currency(currency_)
388 {
389 }
390
391 Issue
392 issue() const
393 {
394 return {currency, account.id()};
395 }
396 Asset
397 asset() const
398 {
399 return issue();
400 }
401 bool
402 integral() const
403 {
404 return issue().integral();
405 }
406
412 operator Issue() const
413 {
414 return issue();
415 }
416 operator PrettyAsset() const
417 {
418 return asset();
419 }
420
421 template <
422 class T,
423 class = std::enable_if_t<sizeof(T) >= sizeof(int) && std::is_arithmetic<T>::value>>
425 operator()(T v) const
426 {
427 // VFALCO NOTE Should throw if the
428 // representation of v is not exact.
430 }
431
433 operator()(epsilon_t) const;
436
437 // VFALCO TODO
438 // STAmount operator()(char const* s) const;
439
441 None
443 {
444 return {issue()};
445 }
446
447 friend BookSpec
448 operator~(IOU const& iou)
449 {
450 return BookSpec(iou.account.id(), iou.currency);
451 }
452};
453
455operator<<(std::ostream& os, IOU const& iou);
456
457//------------------------------------------------------------------------------
458
466class MPT
467{
468public:
471
472 MPT(std::string const& n, xrpl::MPTID const& issuanceID_) : name(n), issuanceID(issuanceID_)
473 {
474 }
475
476 xrpl::MPTID const&
477 mpt() const
478 {
479 return issuanceID;
480 }
481
485 mptIssue() const
486 {
487 return MPTIssue{issuanceID};
488 }
489 Asset
490 asset() const
491 {
492 return mptIssue();
493 }
494 bool
495 integral() const
496 {
497 return true;
498 }
499
505 operator xrpl::MPTIssue() const
506 {
507 return mptIssue();
508 }
509
510 operator PrettyAsset() const
511 {
512 return asset();
513 }
514
515 template <class T>
516 requires(sizeof(T) >= sizeof(int) && std::is_arithmetic_v<T>)
518 operator()(T v) const
519 {
520 return {amountFromString(mpt(), std::to_string(v)), name};
521 }
522
527
529 None
531 {
532 return {mptIssue()};
533 }
534
535 friend BookSpec
537 {
538 assert(false);
539 Throw<std::logic_error>("MPT is not supported");
540 return BookSpec{beast::zero, noCurrency()};
541 }
542};
543
545operator<<(std::ostream& os, MPT const& mpt);
546
547//------------------------------------------------------------------------------
548
549struct any_t
550{
551 inline AnyAmount
552 operator()(STAmount const& sta) const;
553};
554
557{
558 bool is_any;
560
561 AnyAmount() = delete;
562 AnyAmount(AnyAmount const&) = default;
563 AnyAmount&
564 operator=(AnyAmount const&) = default;
565
567 {
568 }
569
570 AnyAmount(STAmount const& amount, any_t const*) : is_any(true), value(amount)
571 {
572 }
573
574 // Reset the issue to a specific account
575 void
576 to(AccountID const& id)
577 {
578 if (!is_any)
579 return;
580 value.setIssuer(id);
581 }
582};
583
584inline AnyAmount
586{
587 return AnyAmount(sta, this);
588}
589
593extern any_t const any;
594
595} // namespace jtx
596} // namespace test
597} // namespace xrpl
Represents a JSON value.
Definition json_value.h:130
bool integral() const
Definition Asset.h:92
bool native() const
Definition Asset.h:79
constexpr bool holds() const
Definition Asset.h:130
A currency issued by an account.
Definition Issue.h:13
bool integral() const
Definition Issue.cpp:59
Number is a floating point type that can represent a wide range of values.
Definition Number.h:207
static rounding_mode getround()
Definition Number.cpp:33
void setIssuer(AccountID const &uIssuer)
Definition STAmount.h:572
int signum() const noexcept
Definition STAmount.h:488
constexpr value_type drops() const
Returns the number of drops.
Definition XRPAmount.h:157
Immutable cryptographic account descriptor.
Definition Account.h:19
std::string const & name() const
Return the name.
Definition Account.h:63
AccountID id() const
Returns the Account ID.
Definition Account.h:87
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:116
static epsilon_t const epsilon
std::ostream & operator<<(std::ostream &os, PrettyAmount const &amount)
Definition amount.cpp:55
XRP_t const XRP
Converts to XRP Issue or STAmount.
Definition amount.cpp:95
constexpr XRPAmount dropsPerXRP
bool operator!=(PrettyAmount const &lhs, PrettyAmount const &rhs)
bool operator==(Account const &lhs, Account const &rhs) noexcept
Definition Account.h:128
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:5
Issue const & xrpIssue()
Returns an asset specifier that represents XRP.
Definition Issue.h:97
STAmount amountFromString(Asset const &asset, std::string const &amount)
Definition STAmount.cpp:987
Currency const & xrpCurrency()
XRP currency.
Definition UintTypes.cpp:98
Json::Value to_json(Asset const &asset)
Definition Asset.h:121
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)