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,
84 std::enable_if_t<sizeof(T) >= sizeof(int) && std::is_integral_v<T> && std::is_signed_v<T>>* = nullptr)
85 : amount_((v > 0) ? v : -v, v < 0)
86 {
87 }
88
90 template <class T>
91 PrettyAmount(T v, std::enable_if_t<sizeof(T) >= sizeof(int) && std::is_unsigned_v<T>>* = nullptr) : amount_(v)
92 {
93 }
94
97 {
98 }
99
100 std::string const&
101 name() const
102 {
103 return name_;
104 }
105
106 STAmount const&
107 value() const
108 {
109 return amount_;
110 }
111
112 Number
113 number() const
114 {
115 return amount_;
116 }
117
118 inline int
119 signum() const
120 {
121 return amount_.signum();
122 }
123
124 operator STAmount const&() const
125 {
126 return amount_;
127 }
128
129 operator AnyAmount() const;
130
131 operator Json::Value() const
132 {
133 return to_json(value());
134 }
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
151
153{
154private:
157
158public:
159 template <typename A>
161 PrettyAsset(A const& asset, std::uint32_t scale = 1) : PrettyAsset{Asset{asset}, scale}
162 {
163 }
164
165 PrettyAsset(Asset const& asset, std::uint32_t scale = 1) : asset_(asset), scale_(scale)
166 {
167 }
168
169 Asset const&
170 raw() const
171 {
172 return asset_;
173 }
174
175 operator Asset const&() const
176 {
177 return asset_;
178 }
179
180 operator Json::Value() const
181 {
182 return to_json(asset_);
183 }
184
185 template <std::integral T>
188 {
189 return operator()(Number(v), rounding);
190 }
191
194 {
195 NumberRoundModeGuard mg(rounding);
197 return {amount, ""};
198 }
199
200 None
202 {
203 return {asset_};
204 }
205
206 bool
207 integral() const
208 {
209 return asset_.integral();
210 }
211
212 bool
213 native() const
214 {
215 return asset_.native();
216 }
217
218 template <ValidIssueType TIss>
219 bool
220 holds() const
221 {
222 return asset_.holds<TIss>();
223 }
224};
225//------------------------------------------------------------------------------
226
227// Specifies an order book
229{
232
233 BookSpec(AccountID const& account_, xrpl::Currency const& currency_) : account(account_), currency(currency_)
234 {
235 }
236};
237
238//------------------------------------------------------------------------------
239
240struct XRP_t
241{
247 operator Issue() const
248 {
249 return xrpIssue();
250 }
251
252 bool
253 integral() const
254 {
255 return true;
256 }
257
264 template <class T, class = std::enable_if_t<std::is_integral_v<T>>>
266 operator()(T v) const
267 {
269 return {TOut{v} * dropsPerXRP};
270 }
271
279 {
280 auto const c = dropsPerXRP.drops();
281 auto const d = std::int64_t(v * c);
282 if (Number(d) / c != v)
283 Throw<std::domain_error>("unrepresentable");
284 return {d};
285 }
286
288 operator()(double v) const
289 {
290 auto const c = dropsPerXRP.drops();
291 if (v >= 0)
292 {
293 auto const d = std::uint64_t(std::round(v * c));
294 if (double(d) / c != v)
295 Throw<std::domain_error>("unrepresentable");
296 return {d};
297 }
298 auto const d = std::int64_t(std::round(v * c));
299 if (double(d) / c != v)
300 Throw<std::domain_error>("unrepresentable");
301 return {d};
302 }
306 None
308 {
309 return {xrpIssue()};
310 }
311
312 friend BookSpec
314 {
315 return BookSpec(xrpAccount(), xrpCurrency());
316 }
317};
318
325extern XRP_t const XRP;
326
332template <class Integer, class = std::enable_if_t<std::is_integral_v<Integer>>>
334drops(Integer i)
335{
336 return {i};
337}
338
344inline PrettyAmount
346{
347 return {i};
348}
349
350//------------------------------------------------------------------------------
351
352// The smallest possible IOU STAmount
354{
356 {
357 }
358
361 {
362 return {n};
363 }
364};
365
366static epsilon_t const epsilon;
367
375class IOU
376{
377public:
380
381 IOU(Account const& account_, xrpl::Currency const& currency_) : account(account_), currency(currency_)
382 {
383 }
384
385 Issue
386 issue() const
387 {
388 return {currency, account.id()};
389 }
390 Asset
391 asset() const
392 {
393 return issue();
394 }
395 bool
396 integral() const
397 {
398 return issue().integral();
399 }
400
406 operator Issue() const
407 {
408 return issue();
409 }
410 operator PrettyAsset() const
411 {
412 return asset();
413 }
414
415 template <class T, class = std::enable_if_t<sizeof(T) >= sizeof(int) && std::is_arithmetic<T>::value>>
417 operator()(T v) const
418 {
419 // VFALCO NOTE Should throw if the
420 // representation of v is not exact.
422 }
423
425 operator()(epsilon_t) const;
428
429 // VFALCO TODO
430 // STAmount operator()(char const* s) const;
431
433 None
435 {
436 return {issue()};
437 }
438
439 friend BookSpec
440 operator~(IOU const& iou)
441 {
442 return BookSpec(iou.account.id(), iou.currency);
443 }
444};
445
447operator<<(std::ostream& os, IOU const& iou);
448
449//------------------------------------------------------------------------------
450
458class MPT
459{
460public:
463
464 MPT(std::string const& n, xrpl::MPTID const& issuanceID_) : name(n), issuanceID(issuanceID_)
465 {
466 }
467
468 xrpl::MPTID const&
469 mpt() const
470 {
471 return issuanceID;
472 }
473
477 mptIssue() const
478 {
479 return MPTIssue{issuanceID};
480 }
481 Asset
482 asset() const
483 {
484 return mptIssue();
485 }
486 bool
487 integral() const
488 {
489 return true;
490 }
491
497 operator xrpl::MPTIssue() const
498 {
499 return mptIssue();
500 }
501
502 operator PrettyAsset() const
503 {
504 return asset();
505 }
506
507 template <class T>
508 requires(sizeof(T) >= sizeof(int) && std::is_arithmetic_v<T>)
510 operator()(T v) const
511 {
512 return {amountFromString(mpt(), std::to_string(v)), name};
513 }
514
519
521 None
523 {
524 return {mptIssue()};
525 }
526
527 friend BookSpec
529 {
530 assert(false);
531 Throw<std::logic_error>("MPT is not supported");
532 return BookSpec{beast::zero, noCurrency()};
533 }
534};
535
537operator<<(std::ostream& os, MPT const& mpt);
538
539//------------------------------------------------------------------------------
540
541struct any_t
542{
543 inline AnyAmount
544 operator()(STAmount const& sta) const;
545};
546
549{
550 bool is_any;
552
553 AnyAmount() = delete;
554 AnyAmount(AnyAmount const&) = default;
555 AnyAmount&
556 operator=(AnyAmount const&) = default;
557
559 {
560 }
561
562 AnyAmount(STAmount const& amount, any_t const*) : is_any(true), value(amount)
563 {
564 }
565
566 // Reset the issue to a specific account
567 void
568 to(AccountID const& id)
569 {
570 if (!is_any)
571 return;
572 value.setIssuer(id);
573 }
574};
575
576inline AnyAmount
578{
579 return AnyAmount(sta, this);
580}
581
585extern any_t const any;
586
587} // namespace jtx
588} // namespace test
589} // 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:53
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:554
int signum() const noexcept
Definition STAmount.h:472
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:111
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:90
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: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:939
Currency const & xrpCurrency()
XRP currency.
Definition UintTypes.cpp:96
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)