rippled
Loading...
Searching...
No Matches
src/test/jtx/amount.h
1//------------------------------------------------------------------------------
2/*
3 This file is part of rippled: https://github.com/ripple/rippled
4 Copyright (c) 2012-2015 Ripple Labs Inc.
5
6 Permission to use, copy, modify, and/or distribute this software for any
7 purpose with or without fee is hereby granted, provided that the above
8 copyright notice and this permission notice appear in all copies.
9
10 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17*/
18//==============================================================================
19
20#ifndef RIPPLE_TEST_JTX_AMOUNT_H_INCLUDED
21#define RIPPLE_TEST_JTX_AMOUNT_H_INCLUDED
22
23#include <test/jtx/Account.h>
24#include <test/jtx/tags.h>
25
26#include <xrpl/basics/contract.h>
27#include <xrpl/protocol/Issue.h>
28#include <xrpl/protocol/STAmount.h>
29#include <xrpl/protocol/Units.h>
30
31#include <cstdint>
32#include <ostream>
33#include <string>
34#include <type_traits>
35
36namespace ripple {
37namespace detail {
38
43
44} // namespace detail
45
46namespace test {
47namespace jtx {
48
49/*
50
51The decision was made to accept amounts of drops and XRP
52using an int type, since the range of XRP is 100 billion
53and having both signed and unsigned overloads creates
54tricky code leading to overload resolution ambiguities.
55
56*/
57
58struct AnyAmount;
59
60// Represents "no amount" of a currency
61// This is distinct from zero or a balance.
62// For example, no USD means the trust line
63// doesn't even exist. Using this in an
64// inappropriate context will generate a
65// compile error.
66//
67struct None
68{
70};
71
72//------------------------------------------------------------------------------
73
74// This value is also defined in SystemParameters.h. It's
75// duplicated here to catch any possible future errors that
76// could change that value (however unlikely).
77constexpr XRPAmount dropsPerXRP{1'000'000};
78
84{
85private:
86 // VFALCO TODO should be Amount
89
90public:
91 PrettyAmount() = default;
92 PrettyAmount(PrettyAmount const&) = default;
94 operator=(PrettyAmount const&) = default;
95
96 PrettyAmount(STAmount const& amount, std::string const& name)
97 : amount_(amount), name_(name)
98 {
99 }
100
102 template <class T>
104 T v,
106 sizeof(T) >= sizeof(int) && std::is_integral_v<T> &&
107 std::is_signed_v<T>>* = nullptr)
108 : amount_((v > 0) ? v : -v, v < 0)
109 {
110 }
111
113 template <class T>
115 T v,
116 std::enable_if_t<sizeof(T) >= sizeof(int) && std::is_unsigned_v<T>>* =
117 nullptr)
118 : amount_(v)
119 {
120 }
121
124 {
125 }
126
127 std::string const&
128 name() const
129 {
130 return name_;
131 }
132
133 STAmount const&
134 value() const
135 {
136 return amount_;
137 }
138
139 Number
140 number() const
141 {
142 return amount_;
143 }
144
145 inline int
146 signum() const
147 {
148 return amount_.signum();
149 }
150
151 operator STAmount const&() const
152 {
153 return amount_;
154 }
155
156 operator AnyAmount() const;
157
158 operator Json::Value() const
159 {
160 return to_json(value());
161 }
162};
163
164inline bool
165operator==(PrettyAmount const& lhs, PrettyAmount const& rhs)
166{
167 return lhs.value() == rhs.value();
168}
169
170inline bool
171operator!=(PrettyAmount const& lhs, PrettyAmount const& rhs)
172{
173 return !operator==(lhs, rhs);
174}
175
177operator<<(std::ostream& os, PrettyAmount const& amount);
178
180{
181private:
184
185public:
186 template <typename A>
188 PrettyAsset(A const& asset, std::uint32_t scale = 1)
189 : PrettyAsset{Asset{asset}, scale}
190 {
191 }
192
193 PrettyAsset(Asset const& asset, std::uint32_t scale = 1)
194 : asset_(asset), scale_(scale)
195 {
196 }
197
198 Asset const&
199 raw() const
200 {
201 return asset_;
202 }
203
204 operator Asset const&() const
205 {
206 return asset_;
207 }
208
209 operator Json::Value() const
210 {
211 return to_json(asset_);
212 }
213
214 template <std::integral T>
216 operator()(T v) const
217 {
218 return operator()(Number(v));
219 }
220
223 {
224 STAmount amount{asset_, v * scale_};
225 return {amount, ""};
226 }
227
228 None
230 {
231 return {asset_};
232 }
233};
234//------------------------------------------------------------------------------
235
236// Specifies an order book
238{
241
242 BookSpec(AccountID const& account_, ripple::Currency const& currency_)
243 : account(account_), currency(currency_)
244 {
245 }
246};
247
248//------------------------------------------------------------------------------
249
250struct XRP_t
251{
257 operator Issue() const
258 {
259 return xrpIssue();
260 }
261
268 template <class T, class = std::enable_if_t<std::is_integral_v<T>>>
270 operator()(T v) const
271 {
272 using TOut = std::
274 return {TOut{v} * dropsPerXRP};
275 }
276
278 operator()(double v) const
279 {
280 auto const c = dropsPerXRP.drops();
281 if (v >= 0)
282 {
283 auto const d = std::uint64_t(std::round(v * c));
284 if (double(d) / c != v)
285 Throw<std::domain_error>("unrepresentable");
286 return {d};
287 }
288 auto const d = std::int64_t(std::round(v * c));
289 if (double(d) / c != v)
290 Throw<std::domain_error>("unrepresentable");
291 return {d};
292 }
296 None
298 {
299 return {xrpIssue()};
300 }
301
302 friend BookSpec
304 {
305 return BookSpec(xrpAccount(), xrpCurrency());
306 }
307};
308
315extern XRP_t const XRP;
316
322template <class Integer, class = std::enable_if_t<std::is_integral_v<Integer>>>
324drops(Integer i)
325{
326 return {i};
327}
328
334inline PrettyAmount
336{
337 return {i};
338}
339
340//------------------------------------------------------------------------------
341
342// The smallest possible IOU STAmount
344{
346 {
347 }
348
351 {
352 return {n};
353 }
354};
355
356static epsilon_t const epsilon;
357
365class IOU
366{
367public:
370
371 IOU(Account const& account_, ripple::Currency const& currency_)
372 : account(account_), currency(currency_)
373 {
374 }
375
376 Issue
377 issue() const
378 {
379 return {currency, account.id()};
380 }
381 Asset
382 asset() const
383 {
384 return issue();
385 }
386
392 operator Issue() const
393 {
394 return issue();
395 }
396 operator PrettyAsset() const
397 {
398 return asset();
399 }
400
401 template <
402 class T,
403 class = std::enable_if_t<
404 sizeof(T) >= sizeof(int) && std::is_arithmetic<T>::value>>
406 operator()(T v) const
407 {
408 // VFALCO NOTE Should throw if the
409 // representation of v is not exact.
411 }
412
414 operator()(epsilon_t) const;
417
418 // VFALCO TODO
419 // STAmount operator()(char const* s) const;
420
422 None
424 {
425 return {issue()};
426 }
427
428 friend BookSpec
429 operator~(IOU const& iou)
430 {
431 return BookSpec(iou.account.id(), iou.currency);
432 }
433};
434
436operator<<(std::ostream& os, IOU const& iou);
437
438//------------------------------------------------------------------------------
439
447class MPT
448{
449public:
452
453 MPT(std::string const& n, ripple::MPTID const& issuanceID_)
454 : name(n), issuanceID(issuanceID_)
455 {
456 }
457
458 ripple::MPTID const&
459 mpt() const
460 {
461 return issuanceID;
462 }
463
467 mptIssue() const
468 {
469 return MPTIssue{issuanceID};
470 }
471 Asset
472 asset() const
473 {
474 return mptIssue();
475 }
476
482 operator ripple::MPTIssue() const
483 {
484 return mptIssue();
485 }
486
487 operator PrettyAsset() const
488 {
489 return asset();
490 }
491
492 template <class T>
493 requires(sizeof(T) >= sizeof(int) && std::is_arithmetic_v<T>)
495 operator()(T v) const
496 {
497 return {amountFromString(mpt(), std::to_string(v)), name};
498 }
499
504
506 None
508 {
509 return {mptIssue()};
510 }
511
512 friend BookSpec
514 {
515 assert(false);
516 Throw<std::logic_error>("MPT is not supported");
517 return BookSpec{beast::zero, noCurrency()};
518 }
519};
520
522operator<<(std::ostream& os, MPT const& mpt);
523
524//------------------------------------------------------------------------------
525
526struct any_t
527{
528 inline AnyAmount
529 operator()(STAmount const& sta) const;
530};
531
534{
535 bool is_any;
537
538 AnyAmount() = delete;
539 AnyAmount(AnyAmount const&) = default;
540 AnyAmount&
541 operator=(AnyAmount const&) = default;
542
543 AnyAmount(STAmount const& amount) : is_any(false), value(amount)
544 {
545 }
546
547 AnyAmount(STAmount const& amount, any_t const*)
548 : is_any(true), value(amount)
549 {
550 }
551
552 // Reset the issue to a specific account
553 void
554 to(AccountID const& id)
555 {
556 if (!is_any)
557 return;
558 value.setIssuer(id);
559 }
560};
561
562inline AnyAmount
564{
565 return AnyAmount(sta, this);
566}
567
571extern any_t const any;
572
573} // namespace jtx
574} // namespace test
575} // namespace ripple
576
577#endif
Represents a JSON value.
Definition json_value.h:149
A currency issued by an account.
Definition Issue.h:33
void setIssuer(AccountID const &uIssuer)
Definition STAmount.h:588
int signum() const noexcept
Definition STAmount.h:514
constexpr value_type drops() const
Returns the number of drops.
Definition XRPAmount.h:177
Immutable cryptographic account descriptor.
Definition Account.h:39
AccountID id() const
Returns the Account ID.
Definition Account.h:111
std::string const & name() const
Return the name.
Definition Account.h:87
Converts to IOU Issue or STAmount.
IOU(Account const &account_, ripple::Currency const &currency_)
friend BookSpec operator~(IOU const &iou)
None operator()(none_t) const
Returns None-of-Issue.
PrettyAmount operator()(T v) const
Converts to MPT Issue or STAmount.
friend BookSpec operator~(MPT const &mpt)
PrettyAmount operator()(epsilon_t) const
MPT(std::string const &n, ripple::MPTID const &issuanceID_)
ripple::MPTIssue mptIssue() const
Explicit conversion to MPTIssue or asset.
None operator()(none_t) const
Returns None-of-Issue.
ripple::MPTID const & mpt() const
PrettyAmount operator()(detail::epsilon_multiple) const
T is_same_v
PrettyAmount drops(Integer i)
Returns an XRP PrettyAmount, which is trivially convertible to STAmount.
std::ostream & operator<<(std::ostream &os, PrettyAmount const &amount)
Definition amount.cpp:73
constexpr XRPAmount dropsPerXRP
bool operator!=(PrettyAmount const &lhs, PrettyAmount const &rhs)
static epsilon_t const epsilon
any_t const any
Returns an amount representing "any issuer".
Definition amount.cpp:133
bool operator==(Account const &lhs, Account const &rhs) noexcept
Definition Account.h:154
XRP_t const XRP
Converts to XRP Issue or STAmount.
Definition amount.cpp:111
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition algorithm.h:25
Issue const & xrpIssue()
Returns an asset specifier that represents XRP.
Definition Issue.h:115
AccountID const & xrpAccount()
Compute AccountID from public key.
Currency const & noCurrency()
A placeholder for empty currencies.
Json::Value to_json(Asset const &asset)
Definition Asset.h:123
Currency const & xrpCurrency()
XRP currency.
STAmount amountFromString(Asset const &asset, std::string const &amount)
T round(T... args)
Amount specifier with an option for any issuer.
void to(AccountID const &id)
AnyAmount(STAmount const &amount)
AnyAmount(STAmount const &amount, any_t const *)
AnyAmount & operator=(AnyAmount const &)=default
AnyAmount(AnyAmount const &)=default
BookSpec(AccountID const &account_, ripple::Currency const &currency_)
Represents an XRP or IOU quantity This customizes the string conversion and supports XRP conversions ...
PrettyAmount(PrettyAmount const &)=default
PrettyAmount(STAmount const &amount, std::string const &name)
PrettyAmount(T v, std::enable_if_t< sizeof(T) >=sizeof(int) &&std::is_integral_v< T > &&std::is_signed_v< T > > *=nullptr)
drops
std::string const & name() const
PrettyAmount(T v, std::enable_if_t< sizeof(T) >=sizeof(int) &&std::is_unsigned_v< T > > *=nullptr)
drops
PrettyAmount & operator=(PrettyAmount const &)=default
PrettyAmount operator()(Number v) const
PrettyAmount operator()(T v) const
PrettyAsset(A const &asset, std::uint32_t scale=1)
PrettyAsset(Asset const &asset, std::uint32_t scale=1)
friend BookSpec operator~(XRP_t const &)
None operator()(none_t) const
Returns None-of-XRP.
PrettyAmount operator()(double v) const
PrettyAmount operator()(T v) const
Returns an amount of XRP as PrettyAmount, which is trivially convertable to STAmount.
AnyAmount operator()(STAmount const &sta) const
detail::epsilon_multiple operator()(std::size_t n) const
T to_string(T... args)