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/Number.h>
7#include <xrpl/basics/contract.h>
8#include <xrpl/json/json_value.h>
9#include <xrpl/protocol/AccountID.h>
10#include <xrpl/protocol/Asset.h>
11#include <xrpl/protocol/Concepts.h>
12#include <xrpl/protocol/Indexes.h>
13#include <xrpl/protocol/Issue.h>
14#include <xrpl/protocol/MPTIssue.h>
15#include <xrpl/protocol/STAmount.h>
16#include <xrpl/protocol/STBase.h>
17#include <xrpl/protocol/UintTypes.h>
18#include <xrpl/protocol/XRPAmount.h>
19
20#include <cmath>
21#include <concepts>
22#include <cstddef>
23#include <cstdint>
24#include <ostream>
25#include <stdexcept>
26#include <string>
27#include <type_traits>
28#include <utility>
29
30namespace xrpl {
31namespace detail {
32
37
38} // namespace detail
39
40namespace test::jtx {
41
42/*
43
44The decision was made to accept amounts of drops and XRP
45using an int type, since the range of XRP is 100 billion
46and having both signed and unsigned overloads creates
47tricky code leading to overload resolution ambiguities.
48
49*/
50
51struct AnyAmount;
52
53// Represents "no amount" of a currency
54// This is distinct from zero or a balance.
55// For example, no USD means the trust line
56// doesn't even exist. Using this in an
57// inappropriate context will generate a
58// compile error.
59//
60struct None
61{
63};
64
65//------------------------------------------------------------------------------
66
67// This value is also defined in SystemParameters.h. It's
68// duplicated here to catch any possible future errors that
69// could change that value (however unlikely).
70constexpr XRPAmount kJtxDropsPerXrp{1'000'000};
71
78{
79private:
80 // VFALCO TODO should be Amount
83
84public:
85 PrettyAmount() = default;
86 PrettyAmount(PrettyAmount const&) = default;
88 operator=(PrettyAmount const&) = default;
89
91 : amount_(std::move(amount)), name_(std::move(name))
92 {
93 }
94
98 template <class T>
100 requires(sizeof(T) >= sizeof(int) && std::is_integral_v<T> && std::is_signed_v<T>)
101 : amount_((v > 0) ? v : -v, v < 0)
102 {
103 }
104
108 template <class T>
110 requires(sizeof(T) >= sizeof(int) && std::is_unsigned_v<T>)
111 : amount_(v)
112 {
113 }
114
119 {
120 }
121
122 [[nodiscard]] std::string const&
123 name() const
124 {
125 return name_;
126 }
127
128 [[nodiscard]] STAmount const&
129 value() const
130 {
131 return amount_;
132 }
133
134 [[nodiscard]] Number
135 number() const
136 {
137 return amount_;
138 }
139
140 [[nodiscard]] int
141 signum() const
142 {
143 return amount_.signum();
144 }
145
146 operator STAmount const&() const
147 {
148 return amount_;
149 }
150
151 operator AnyAmount() const;
152
153 operator json::Value() const
154 {
155 return toJson(value());
156 }
157};
158
159inline bool
160operator==(PrettyAmount const& lhs, PrettyAmount const& rhs)
161{
162 return lhs.value() == rhs.value();
163}
164
166operator<<(std::ostream& os, PrettyAmount const& amount);
167
169{
170private:
173
174public:
175 template <typename A>
176 requires std::convertible_to<A, Asset>
177 PrettyAsset(A const& asset, std::uint32_t scale = 1) : PrettyAsset{Asset{asset}, scale}
178 {
179 }
180
181 PrettyAsset(Asset const& asset, std::uint32_t scale = 1) : asset_(asset), scale_(scale)
182 {
183 }
184
185 [[nodiscard]] Asset const&
186 raw() const
187 {
188 return asset_;
189 }
190
191 operator Asset const&() const
192 {
193 return asset_;
194 }
195
196 operator json::Value() const
197 {
198 return toJson(asset_);
199 }
200
201 template <std::integral T>
204 {
205 return operator()(Number(v), rounding);
206 }
207
210 {
211 NumberRoundModeGuard const mg(rounding);
212 STAmount const amount{asset_, v * scale_};
213 return {amount, ""};
214 }
215
216 None
218 {
219 return {asset_};
220 }
221
222 [[nodiscard]] bool
223 integral() const
224 {
225 return asset_.integral();
226 }
227
228 [[nodiscard]] bool
229 native() const
230 {
231 return asset_.native();
232 }
233
234 template <ValidIssueType TIss>
235 [[nodiscard]] bool
236 holds() const
237 {
238 return asset_.holds<TIss>();
239 }
240};
241//------------------------------------------------------------------------------
242
243// Specifies an order book
245{
247
249 {
250 }
251};
252
253//------------------------------------------------------------------------------
254
255struct XrpT
256{
263 operator Issue() const
264 {
265 return xrpIssue();
266 }
267 operator Asset() const
268 {
269 return xrpIssue();
270 }
271
272 static bool
274 {
275 return true;
276 }
277
285 template <class T>
287 operator()(T v) const
288 requires(std::is_integral_v<T>)
289 {
291 return {TOut{v} * kJtxDropsPerXrp};
292 }
293
302 {
303 auto const c = kJtxDropsPerXrp.drops();
304 auto const d = std::int64_t(v * c);
305 if (Number(d) / c != v)
306 Throw<std::domain_error>("unrepresentable");
307 return {d};
308 }
309
311 operator()(double v) const
312 {
313 auto const c = kJtxDropsPerXrp.drops();
314 if (v >= 0)
315 {
316 auto const d = std::uint64_t(std::round(v * c));
317 if (double(d) / c != v)
318 Throw<std::domain_error>("unrepresentable");
319 return {d};
320 }
321 auto const d = std::int64_t(std::round(v * c));
322 if (double(d) / c != v)
323 Throw<std::domain_error>("unrepresentable");
324 return {d};
325 }
326
327
331 None
333 {
334 return {xrpIssue()};
335 }
336
337 friend BookSpec
339 {
340 return BookSpec(Issue{xrpCurrency(), xrpAccount()});
341 }
342};
343
351extern XrpT const XRP; // NOLINT(readability-identifier-naming)
352
359template <class Integer>
361drops(Integer i)
363{
364 return {i};
365}
366
373inline PrettyAmount
375{
376 return {i};
377}
378
379//------------------------------------------------------------------------------
380
381// The smallest possible IOU STAmount
383{
384 EpsilonT() = default;
385
388 {
389 return {n};
390 }
391};
392
393static EpsilonT const kEpsilon;
394
403class IOU
404{
405public:
408
413
414 [[nodiscard]] Issue
415 issue() const
416 {
417 return {currency, account.id()};
418 }
419 [[nodiscard]] Asset
420 asset() const
421 {
422 return issue();
423 }
424 [[nodiscard]] bool
425 integral() const
426 {
427 return issue().integral();
428 }
429
436 operator Issue() const
437 {
438 return issue();
439 }
440 operator Asset() const
441 {
442 return asset();
443 }
444 operator PrettyAsset() const
445 {
446 return asset();
447 }
448
449 template <class T>
451 operator()(T v) const
452 requires(sizeof(T) >= sizeof(int) && std::is_arithmetic_v<T>)
453 {
454 // VFALCO NOTE Should throw if the
455 // representation of v is not exact.
456 return {amountFromString(issue(), std::to_string(v)), account.name()};
457 }
458
460 operator()(EpsilonT) const;
463
464 // VFALCO TODO
465 // STAmount operator()(char const* s) const;
466
470 None
472 {
473 return {issue()};
474 }
475
476 friend BookSpec
477 operator~(IOU const& iou)
478 {
479 return BookSpec(Issue{iou.currency, iou.account.id()});
480 }
481};
482
484operator<<(std::ostream& os, IOU const& iou);
485
486//------------------------------------------------------------------------------
487
496class MPT
497{
498public:
501
503 {
504 }
505 MPT(std::string n = "") : name(std::move(n)), issuanceID(noMPT())
506 {
507 }
509 {
510 }
511 MPT(AccountID const& account, std::int32_t seq = 0) : issuanceID(makeMptID(seq, account))
512 {
513 }
514
515 [[nodiscard]] xrpl::MPTID const&
516 mpt() const
517 {
518 return issuanceID;
519 }
520
524 [[nodiscard]] xrpl::MPTIssue
525 mptIssue() const
526 {
527 return MPTIssue{issuanceID};
528 }
529 [[nodiscard]] Asset
530 asset() const
531 {
532 return mptIssue();
533 }
534 static bool
536 {
537 return true;
538 }
539
546 operator xrpl::MPTIssue() const
547 {
548 return mptIssue();
549 }
550
551 operator PrettyAsset() const
552 {
553 return asset();
554 }
555 operator xrpl::Asset() const
556 {
557 return mpt();
558 }
559 operator xrpl::MPTID() const
560 {
561 return mpt();
562 }
563
564 template <class T>
565 requires(sizeof(T) >= sizeof(int) && std::is_arithmetic_v<T>)
567 operator()(T v) const
568 {
569 return {amountFromString(mpt(), std::to_string(v)), name};
570 }
571
576
580 None
582 {
583 return {noMPT()};
584 }
585
586 friend BookSpec
588 {
589 return BookSpec{Asset{mpt}};
590 }
591};
592
594operator<<(std::ostream& os, MPT const& mpt);
595
596//------------------------------------------------------------------------------
597
598struct AnyT
599{
600 inline AnyAmount
601 operator()(STAmount const& sta) const;
602};
603
608{
609 bool isAny;
611
612 AnyAmount() = delete;
613 AnyAmount(AnyAmount const&) = default;
614 AnyAmount&
615 operator=(AnyAmount const&) = default;
616
617 AnyAmount(STAmount amount) : isAny(false), value(std::move(amount))
618 {
619 }
620
621 AnyAmount(STAmount amount, AnyT const*) : isAny(true), value(std::move(amount))
622 {
623 }
624
625 // Reset the issue to a specific account
626 void
627 to(AccountID const& id)
628 {
629 if (!isAny)
630 return;
631 value.get<Issue>().account = id;
632 }
633};
634
635inline AnyAmount
636AnyT::operator()(STAmount const& sta) const
637{
638 return AnyAmount(sta, this);
639}
640
645extern AnyT const kAny;
646
647} // namespace test::jtx
648
649} // namespace xrpl
Represents a JSON value.
Definition json_value.h:117
A currency issued by an account.
Definition Issue.h:18
bool integral() const
Definition Issue.cpp:60
Number is a floating point type that can represent a wide range of values.
Definition Number.h:351
static RoundingMode getround()
Immutable cryptographic account descriptor.
Definition jtx/Account.h:21
AccountID id() const
Returns the Account ID.
Converts to IOU Issue or STAmount.
IOU(Account account, xrpl::Currency const &currency)
PrettyAmount operator()(T v) const
None operator()(NoneT) const
Returns None-of-Issue.
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==(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:54
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:108
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:794
BaseUInt< 160, detail::CurrencyTag > Currency
Currency is a hash representing a specific currency.
Definition UintTypes.h:42
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:168
MPTID noMPT()
Definition MPTIssue.h:114
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:54
MPTID makeMptID(std::uint32_t const sequence, AccountID const &account)
Definition Indexes.cpp:184
BaseUInt< 160, detail::AccountIDTag > AccountID
A 160-bit unsigned that uniquely identifies an account.
Definition AccountID.h:34
AccountID const & xrpAccount()
Compute AccountID from public key.
XRPL_NO_SANITIZE_ADDRESS void Throw(Args &&... args)
Definition contract.h:52
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(PrettyAmount const &)=default
STAmount const & value() const
PrettyAmount & operator=(PrettyAmount const &)=default
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)