xrpld
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/Indexes.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#include <utility>
17
18namespace xrpl {
19namespace detail {
20
25
26} // namespace detail
27
28namespace test::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 kJtxDropsPerXrp{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
78 : amount_(std::move(amount)), name_(std::move(name))
79 {
80 }
81
83 template <class T>
85 T v,
87 sizeof(T) >= sizeof(int) && std::is_integral_v<T> && std::is_signed_v<T>>* = nullptr)
88 : amount_((v > 0) ? v : -v, v < 0)
89 {
90 }
91
93 template <class T>
95 T v,
96 std::enable_if_t<sizeof(T) >= sizeof(int) && std::is_unsigned_v<T>>* = nullptr)
97 : amount_(v)
98 {
99 }
100
103 {
104 }
105
106 [[nodiscard]] std::string const&
107 name() const
108 {
109 return name_;
110 }
111
112 [[nodiscard]] STAmount const&
113 value() const
114 {
115 return amount_;
116 }
117
118 [[nodiscard]] Number
119 number() const
120 {
121 return amount_;
122 }
123
124 [[nodiscard]] int
125 signum() const
126 {
127 return amount_.signum();
128 }
129
130 operator STAmount const&() const
131 {
132 return amount_;
133 }
134
135 operator AnyAmount() const;
136
137 operator json::Value() const
138 {
139 return toJson(value());
140 }
141};
142
143inline bool
144operator==(PrettyAmount const& lhs, PrettyAmount const& rhs)
145{
146 return lhs.value() == rhs.value();
147}
148
149inline bool
150operator!=(PrettyAmount const& lhs, PrettyAmount const& rhs)
151{
152 return !operator==(lhs, rhs);
153}
154
156operator<<(std::ostream& os, PrettyAmount const& amount);
157
159{
160private:
163
164public:
165 template <typename A>
166 requires std::convertible_to<A, Asset>
167 PrettyAsset(A const& asset, std::uint32_t scale = 1) : PrettyAsset{Asset{asset}, scale}
168 {
169 }
170
171 PrettyAsset(Asset const& asset, std::uint32_t scale = 1) : asset_(asset), scale_(scale)
172 {
173 }
174
175 [[nodiscard]] Asset const&
176 raw() const
177 {
178 return asset_;
179 }
180
181 operator Asset const&() const
182 {
183 return asset_;
184 }
185
186 operator json::Value() const
187 {
188 return toJson(asset_);
189 }
190
191 template <std::integral T>
194 {
195 return operator()(Number(v), rounding);
196 }
197
200 {
201 NumberRoundModeGuard const mg(rounding);
202 STAmount const amount{asset_, v * scale_};
203 return {amount, ""};
204 }
205
206 None
208 {
209 return {asset_};
210 }
211
212 [[nodiscard]] bool
213 integral() const
214 {
215 return asset_.integral();
216 }
217
218 [[nodiscard]] bool
219 native() const
220 {
221 return asset_.native();
222 }
223
224 template <ValidIssueType TIss>
225 [[nodiscard]] bool
226 holds() const
227 {
228 return asset_.holds<TIss>();
229 }
230};
231//------------------------------------------------------------------------------
232
233// Specifies an order book
235{
237
239 {
240 }
241};
242
243//------------------------------------------------------------------------------
244
245struct XrpT
246{
252 operator Issue() const
253 {
254 return xrpIssue();
255 }
256 operator Asset() const
257 {
258 return xrpIssue();
259 }
260
261 static bool
263 {
264 return true;
265 }
266
273 template <class T, class = std::enable_if_t<std::is_integral_v<T>>>
275 operator()(T v) const
276 {
278 return {TOut{v} * kJtxDropsPerXrp};
279 }
280
288 {
289 auto const c = kJtxDropsPerXrp.drops();
290 auto const d = std::int64_t(v * c);
291 if (Number(d) / c != v)
292 Throw<std::domain_error>("unrepresentable");
293 return {d};
294 }
295
297 operator()(double v) const
298 {
299 auto const c = kJtxDropsPerXrp.drops();
300 if (v >= 0)
301 {
302 auto const d = std::uint64_t(std::round(v * c));
303 if (double(d) / c != v)
304 Throw<std::domain_error>("unrepresentable");
305 return {d};
306 }
307 auto const d = std::int64_t(std::round(v * c));
308 if (double(d) / c != v)
309 Throw<std::domain_error>("unrepresentable");
310 return {d};
311 }
312
313
315 None
317 {
318 return {xrpIssue()};
319 }
320
321 friend BookSpec
323 {
324 return BookSpec(Issue{xrpCurrency(), xrpAccount()});
325 }
326};
327
334extern XrpT const XRP; // NOLINT(readability-identifier-naming)
335
341template <class Integer, class = std::enable_if_t<std::is_integral_v<Integer>>>
343drops(Integer i)
344{
345 return {i};
346}
347
353inline PrettyAmount
355{
356 return {i};
357}
358
359//------------------------------------------------------------------------------
360
361// The smallest possible IOU STAmount
363{
364 EpsilonT() = default;
365
368 {
369 return {n};
370 }
371};
372
373static EpsilonT const kEpsilon;
374
382class IOU
383{
384public:
387
392
393 [[nodiscard]] Issue
394 issue() const
395 {
396 return {currency, account.id()};
397 }
398 [[nodiscard]] Asset
399 asset() const
400 {
401 return issue();
402 }
403 [[nodiscard]] bool
404 integral() const
405 {
406 return issue().integral();
407 }
408
414 operator Issue() const
415 {
416 return issue();
417 }
418 operator Asset() const
419 {
420 return asset();
421 }
422 operator PrettyAsset() const
423 {
424 return asset();
425 }
426
427 template <
428 class T,
429 class = std::enable_if_t<sizeof(T) >= sizeof(int) && std::is_arithmetic_v<T>>>
431 operator()(T v) const
432 {
433 // VFALCO NOTE Should throw if the
434 // representation of v is not exact.
435 return {amountFromString(issue(), std::to_string(v)), account.name()};
436 }
437
439 operator()(EpsilonT) const;
442
443 // VFALCO TODO
444 // STAmount operator()(char const* s) const;
445
447 None
449 {
450 return {issue()};
451 }
452
453 friend BookSpec
454 operator~(IOU const& iou)
455 {
456 return BookSpec(Issue{iou.currency, iou.account.id()});
457 }
458};
459
461operator<<(std::ostream& os, IOU const& iou);
462
463//------------------------------------------------------------------------------
464
472class MPT
473{
474public:
477
479 {
480 }
481 MPT(std::string n = "") : name(std::move(n)), issuanceID(noMPT())
482 {
483 }
485 {
486 }
487 MPT(AccountID const& account, std::int32_t seq = 0) : issuanceID(makeMptID(seq, account))
488 {
489 }
490
491 [[nodiscard]] xrpl::MPTID const&
492 mpt() const
493 {
494 return issuanceID;
495 }
496
499 [[nodiscard]] xrpl::MPTIssue
500 mptIssue() const
501 {
502 return MPTIssue{issuanceID};
503 }
504 [[nodiscard]] Asset
505 asset() const
506 {
507 return mptIssue();
508 }
509 static bool
511 {
512 return true;
513 }
514
520 operator xrpl::MPTIssue() const
521 {
522 return mptIssue();
523 }
524
525 operator PrettyAsset() const
526 {
527 return asset();
528 }
529 operator xrpl::Asset() const
530 {
531 return mpt();
532 }
533 operator xrpl::MPTID() const
534 {
535 return mpt();
536 }
537
538 template <class T>
539 requires(sizeof(T) >= sizeof(int) && std::is_arithmetic_v<T>)
541 operator()(T v) const
542 {
543 return {amountFromString(mpt(), std::to_string(v)), name};
544 }
545
550
552 None
554 {
555 return {noMPT()};
556 }
557
558 friend BookSpec
560 {
561 return BookSpec{Asset{mpt}};
562 }
563};
564
566operator<<(std::ostream& os, MPT const& mpt);
567
568//------------------------------------------------------------------------------
569
570struct AnyT
571{
572 inline AnyAmount
573 operator()(STAmount const& sta) const;
574};
575
578{
579 bool isAny;
581
582 AnyAmount() = delete;
583 AnyAmount(AnyAmount const&) = default;
584 AnyAmount&
585 operator=(AnyAmount const&) = default;
586
587 AnyAmount(STAmount amount) : isAny(false), value(std::move(amount))
588 {
589 }
590
591 AnyAmount(STAmount amount, AnyT const*) : isAny(true), value(std::move(amount))
592 {
593 }
594
595 // Reset the issue to a specific account
596 void
597 to(AccountID const& id)
598 {
599 if (!isAny)
600 return;
601 value.get<Issue>().account = id;
602 }
603};
604
605inline AnyAmount
606AnyT::operator()(STAmount const& sta) const
607{
608 return AnyAmount(sta, this);
609}
610
614extern AnyT const kAny;
615
616} // namespace test::jtx
617
618} // namespace xrpl
Represents a JSON value.
Definition json_value.h:130
A currency issued by an account.
Definition Issue.h:13
bool integral() const
Definition Issue.cpp:60
Number is a floating point type that can represent a wide range of values.
Definition Number.h:306
static RoundingMode getround()
Definition Number.cpp:105
Immutable cryptographic account descriptor.
Definition jtx/Account.h:17
AccountID id() const
Returns the Account ID.
Definition jtx/Account.h:85
Converts to IOU Issue or STAmount.
IOU(Account account, xrpl::Currency const &currency)
None operator()(NoneT) const
Returns None-of-Issue.
PrettyAmount operator()(T v) const
friend BookSpec operator~(IOU const &iou)
Converts to MPT Issue or STAmount.
operator xrpl::MPTIssue() const
Implicit conversion to MPTIssue or asset.
friend BookSpec operator~(MPT const &mpt)
xrpl::MPTIssue mptIssue() const
Explicit conversion to MPTIssue or asset.
PrettyAmount operator()(detail::EpsilonMultiple) const
MPT(AccountID const &account, std::int32_t seq=0)
PrettyAmount operator()(EpsilonT) const
xrpl::MPTID const & mpt() const
MPT(std::string n, xrpl::MPTID const &issuanceID)
MPT(Asset const &asset)
operator xrpl::Asset() const
None operator()(NoneT) const
Returns None-of-Issue.
T is_arithmetic_v
T is_integral_v
T is_signed_v
T is_unsigned_v
STL namespace.
static EpsilonT const kEpsilon
constexpr XRPAmount kJtxDropsPerXrp
XrpT const XRP
Converts to XRP Issue or STAmount.
Definition amount.cpp:92
std::ostream & operator<<(std::ostream &os, PrettyAmount const &amount)
Definition amount.cpp:46
AnyT const kAny
Returns an amount representing "any issuer".
Definition amount.cpp:120
bool operator!=(PrettyAmount const &lhs, PrettyAmount const &rhs)
bool operator==(Account const &lhs, Account const &rhs) noexcept
PrettyAmount drops(Integer i)
Returns an XRP PrettyAmount, which is trivially convertible to STAmount.
constexpr XRPAmount
Convert XRP to drops (integral types).
Definition TxTest.h:48
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
T get(Section const &section, std::string const &name, T const &defaultValue=T{})
Retrieve a key/value pair from a section.
int scale(Number const &number, Asset const &asset)
Get the scale of a Number for a given asset.
Definition STAmount.h:779
BaseUInt< 160, detail::CurrencyTag > Currency
Currency is a hash representing a specific currency.
Definition UintTypes.h:36
STAmount amountFromString(Asset const &asset, std::string const &amount)
Definition STAmount.cpp:907
Currency const & xrpCurrency()
XRP currency.
Definition UintTypes.cpp:99
json::Value toJson(Asset const &asset)
Definition Asset.h:157
MPTID noMPT()
Definition MPTIssue.h:103
BaseUInt< 192 > MPTID
MPTID is a 192-bit value representing MPT Issuance ID, which is a concatenation of a 32-bit sequence ...
Definition UintTypes.h:44
BaseUInt< 160, detail::AccountIDTag > AccountID
A 160-bit unsigned that uniquely identifies an account.
Definition AccountID.h:28
AccountID const & xrpAccount()
Compute AccountID from public key.
MPTID makeMptID(std::uint32_t sequence, AccountID const &account)
Definition Indexes.cpp:172
XRPL_NO_SANITIZE_ADDRESS void Throw(Args &&... args)
Definition contract.h:49
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 amount, AnyT const *)
AnyAmount operator()(STAmount const &sta) const
BookSpec(xrpl::Asset const &asset)
detail::EpsilonMultiple operator()(std::size_t n) const
Represents an XRP, IOU, or MPT quantity This customizes the string conversion and supports XRP conver...
PrettyAmount(STAmount amount, std::string name)
std::string const & name() const
PrettyAmount(T v, std::enable_if_t< sizeof(T) >=sizeof(int) &&std::is_unsigned_v< T > > *=nullptr)
drops
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(A const &asset, std::uint32_t scale=1)
PrettyAsset(Asset const &asset, std::uint32_t scale=1)
PrettyAmount operator()(Number v, Number::RoundingMode rounding=Number::getround()) const
PrettyAmount operator()(T v, Number::RoundingMode rounding=Number::getround()) const
PrettyAmount operator()(double v) const
PrettyAmount operator()(Number v) const
Returns an amount of XRP as PrettyAmount, which is trivially convertible to STAmount.
None operator()(NoneT) const
Returns None-of-XRP.
friend BookSpec operator~(XrpT const &)
PrettyAmount operator()(T v) const
Returns an amount of XRP as PrettyAmount, which is trivially convertible to STAmount.
T to_string(T... args)