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>
217 {
218 return operator()(Number(v), rounding);
219 }
220
223 const
224 {
225 NumberRoundModeGuard mg(rounding);
226 STAmount amount{asset_, v * scale_};
227 return {amount, ""};
228 }
229
230 None
232 {
233 return {asset_};
234 }
235};
236//------------------------------------------------------------------------------
237
238// Specifies an order book
240{
243
244 BookSpec(AccountID const& account_, ripple::Currency const& currency_)
245 : account(account_), currency(currency_)
246 {
247 }
248};
249
250//------------------------------------------------------------------------------
251
252struct XRP_t
253{
259 operator Issue() const
260 {
261 return xrpIssue();
262 }
263
270 template <class T, class = std::enable_if_t<std::is_integral_v<T>>>
272 operator()(T v) const
273 {
274 using TOut = std::
276 return {TOut{v} * dropsPerXRP};
277 }
278
280 operator()(double v) const
281 {
282 auto const c = dropsPerXRP.drops();
283 if (v >= 0)
284 {
285 auto const d = std::uint64_t(std::round(v * c));
286 if (double(d) / c != v)
287 Throw<std::domain_error>("unrepresentable");
288 return {d};
289 }
290 auto const d = std::int64_t(std::round(v * c));
291 if (double(d) / c != v)
292 Throw<std::domain_error>("unrepresentable");
293 return {d};
294 }
298 None
300 {
301 return {xrpIssue()};
302 }
303
304 friend BookSpec
306 {
307 return BookSpec(xrpAccount(), xrpCurrency());
308 }
309};
310
317extern XRP_t const XRP;
318
324template <class Integer, class = std::enable_if_t<std::is_integral_v<Integer>>>
326drops(Integer i)
327{
328 return {i};
329}
330
336inline PrettyAmount
338{
339 return {i};
340}
341
342//------------------------------------------------------------------------------
343
344// The smallest possible IOU STAmount
346{
348 {
349 }
350
353 {
354 return {n};
355 }
356};
357
358static epsilon_t const epsilon;
359
367class IOU
368{
369public:
372
373 IOU(Account const& account_, ripple::Currency const& currency_)
374 : account(account_), currency(currency_)
375 {
376 }
377
378 Issue
379 issue() const
380 {
381 return {currency, account.id()};
382 }
383 Asset
384 asset() const
385 {
386 return issue();
387 }
388
394 operator Issue() const
395 {
396 return issue();
397 }
398 operator PrettyAsset() const
399 {
400 return asset();
401 }
402
403 template <
404 class T,
405 class = std::enable_if_t<
406 sizeof(T) >= sizeof(int) && std::is_arithmetic<T>::value>>
408 operator()(T v) const
409 {
410 // VFALCO NOTE Should throw if the
411 // representation of v is not exact.
413 }
414
416 operator()(epsilon_t) const;
419
420 // VFALCO TODO
421 // STAmount operator()(char const* s) const;
422
424 None
426 {
427 return {issue()};
428 }
429
430 friend BookSpec
431 operator~(IOU const& iou)
432 {
433 return BookSpec(iou.account.id(), iou.currency);
434 }
435};
436
438operator<<(std::ostream& os, IOU const& iou);
439
440//------------------------------------------------------------------------------
441
449class MPT
450{
451public:
454
455 MPT(std::string const& n, ripple::MPTID const& issuanceID_)
456 : name(n), issuanceID(issuanceID_)
457 {
458 }
459
460 ripple::MPTID const&
461 mpt() const
462 {
463 return issuanceID;
464 }
465
469 mptIssue() const
470 {
471 return MPTIssue{issuanceID};
472 }
473 Asset
474 asset() const
475 {
476 return mptIssue();
477 }
478
484 operator ripple::MPTIssue() const
485 {
486 return mptIssue();
487 }
488
489 operator PrettyAsset() const
490 {
491 return asset();
492 }
493
494 template <class T>
495 requires(sizeof(T) >= sizeof(int) && std::is_arithmetic_v<T>)
497 operator()(T v) const
498 {
499 return {amountFromString(mpt(), std::to_string(v)), name};
500 }
501
506
508 None
510 {
511 return {mptIssue()};
512 }
513
514 friend BookSpec
516 {
517 assert(false);
518 Throw<std::logic_error>("MPT is not supported");
519 return BookSpec{beast::zero, noCurrency()};
520 }
521};
522
524operator<<(std::ostream& os, MPT const& mpt);
525
526//------------------------------------------------------------------------------
527
528struct any_t
529{
530 inline AnyAmount
531 operator()(STAmount const& sta) const;
532};
533
536{
537 bool is_any;
539
540 AnyAmount() = delete;
541 AnyAmount(AnyAmount const&) = default;
542 AnyAmount&
543 operator=(AnyAmount const&) = default;
544
545 AnyAmount(STAmount const& amount) : is_any(false), value(amount)
546 {
547 }
548
549 AnyAmount(STAmount const& amount, any_t const*)
550 : is_any(true), value(amount)
551 {
552 }
553
554 // Reset the issue to a specific account
555 void
556 to(AccountID const& id)
557 {
558 if (!is_any)
559 return;
560 value.setIssuer(id);
561 }
562};
563
564inline AnyAmount
566{
567 return AnyAmount(sta, this);
568}
569
573extern any_t const any;
574
575} // namespace jtx
576} // namespace test
577} // namespace ripple
578
579#endif
Represents a JSON value.
Definition json_value.h:149
A currency issued by an account.
Definition Issue.h:33
static rounding_mode getround()
Definition Number.cpp:47
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)
Definition STAmount.cpp:996
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, Number::rounding_mode rounding=Number::getround()) const
PrettyAmount operator()(T v, Number::rounding_mode rounding=Number::getround()) 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)