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/FeeUnits.h>
28#include <xrpl/protocol/Issue.h>
29#include <xrpl/protocol/STAmount.h>
30
31#include <cstdint>
32#include <ostream>
33#include <string>
34#include <type_traits>
35
36namespace ripple {
37namespace test {
38namespace jtx {
39
40/*
41
42The decision was made to accept amounts of drops and XRP
43using an int type, since the range of XRP is 100 billion
44and having both signed and unsigned overloads creates
45tricky code leading to overload resolution ambiguities.
46
47*/
48
49struct AnyAmount;
50
51// Represents "no amount" of a currency
52// This is distinct from zero or a balance.
53// For example, no USD means the trust line
54// doesn't even exist. Using this in an
55// inappropriate context will generate a
56// compile error.
57//
58struct None
59{
61};
62
63//------------------------------------------------------------------------------
64
65// This value is also defined in SystemParameters.h. It's
66// duplicated here to catch any possible future errors that
67// could change that value (however unlikely).
68constexpr XRPAmount dropsPerXRP{1'000'000};
69
75{
76private:
77 // VFALCO TODO should be Amount
80
81public:
82 PrettyAmount() = default;
83 PrettyAmount(PrettyAmount const&) = default;
85 operator=(PrettyAmount const&) = default;
86
87 PrettyAmount(STAmount const& amount, std::string const& name)
88 : amount_(amount), name_(name)
89 {
90 }
91
93 template <class T>
95 T v,
97 sizeof(T) >= sizeof(int) && std::is_integral_v<T> &&
98 std::is_signed_v<T>>* = nullptr)
99 : amount_((v > 0) ? v : -v, v < 0)
100 {
101 }
102
104 template <class T>
106 T v,
107 std::enable_if_t<sizeof(T) >= sizeof(int) && std::is_unsigned_v<T>>* =
108 nullptr)
109 : amount_(v)
110 {
111 }
112
115 {
116 }
117
118 std::string const&
119 name() const
120 {
121 return name_;
122 }
123
124 STAmount const&
125 value() const
126 {
127 return amount_;
128 }
129
130 Number
131 number() const
132 {
133 return amount_;
134 }
135
136 operator STAmount const&() const
137 {
138 return amount_;
139 }
140
141 operator AnyAmount() const;
142
143 operator Json::Value() const
144 {
145 return to_json(value());
146 }
147};
148
149inline bool
150operator==(PrettyAmount const& lhs, PrettyAmount const& rhs)
151{
152 return lhs.value() == rhs.value();
153}
154
155inline bool
156operator!=(PrettyAmount const& lhs, PrettyAmount const& rhs)
157{
158 return !operator==(lhs, rhs);
159}
160
162operator<<(std::ostream& os, PrettyAmount const& amount);
163
165{
166private:
168 unsigned int scale_;
169
170public:
171 template <typename A>
172 requires std::convertible_to<A, Asset>
173 PrettyAsset(A const& asset, unsigned int scale = 1)
174 : PrettyAsset{Asset{asset}, scale}
175 {
176 }
177
178 PrettyAsset(Asset const& asset, unsigned int scale = 1)
179 : asset_(asset), scale_(scale)
180 {
181 }
182
183 Asset const&
184 raw() const
185 {
186 return asset_;
187 }
188
189 operator Asset const&() const
190 {
191 return asset_;
192 }
193
194 operator Json::Value() const
195 {
196 return to_json(asset_);
197 }
198
199 template <std::integral T>
201 operator()(T v) const
202 {
203 STAmount amount{asset_, v * scale_};
204 return {amount, ""};
205 }
206};
207//------------------------------------------------------------------------------
208
209// Specifies an order book
211{
214
215 BookSpec(AccountID const& account_, ripple::Currency const& currency_)
216 : account(account_), currency(currency_)
217 {
218 }
219};
220
221//------------------------------------------------------------------------------
222
223struct XRP_t
224{
230 operator Issue() const
231 {
232 return xrpIssue();
233 }
234
241 template <class T, class = std::enable_if_t<std::is_integral_v<T>>>
243 operator()(T v) const
244 {
245 using TOut = std::
246 conditional_t<std::is_signed_v<T>, std::int64_t, std::uint64_t>;
247 return {TOut{v} * dropsPerXRP};
248 }
249
251 operator()(double v) const
252 {
253 auto const c = dropsPerXRP.drops();
254 if (v >= 0)
255 {
256 auto const d = std::uint64_t(std::round(v * c));
257 if (double(d) / c != v)
258 Throw<std::domain_error>("unrepresentable");
259 return {d};
260 }
261 auto const d = std::int64_t(std::round(v * c));
262 if (double(d) / c != v)
263 Throw<std::domain_error>("unrepresentable");
264 return {d};
265 }
269 None
271 {
272 return {xrpIssue()};
273 }
274
275 friend BookSpec
277 {
278 return BookSpec(xrpAccount(), xrpCurrency());
279 }
280};
281
288extern XRP_t const XRP;
289
295template <class Integer, class = std::enable_if_t<std::is_integral_v<Integer>>>
297drops(Integer i)
298{
299 return {i};
300}
301
307inline PrettyAmount
309{
310 return {i};
311}
312
313//------------------------------------------------------------------------------
314
315namespace detail {
316
318{
320};
321
322} // namespace detail
323
324// The smallest possible IOU STAmount
326{
328 {
329 }
330
333 {
334 return {n};
335 }
336};
337
338static epsilon_t const epsilon;
339
347class IOU
348{
349public:
352
353 IOU(Account const& account_, ripple::Currency const& currency_)
354 : account(account_), currency(currency_)
355 {
356 }
357
358 Issue
359 issue() const
360 {
361 return {currency, account.id()};
362 }
363
369 operator Issue() const
370 {
371 return issue();
372 }
373 operator Asset() const
374 {
375 return issue();
376 }
377
378 template <
379 class T,
380 class = std::enable_if_t<
381 sizeof(T) >= sizeof(int) && std::is_arithmetic<T>::value>>
383 operator()(T v) const
384 {
385 // VFALCO NOTE Should throw if the
386 // representation of v is not exact.
388 }
389
391 operator()(epsilon_t) const;
394
395 // VFALCO TODO
396 // STAmount operator()(char const* s) const;
397
399 None
401 {
402 return {issue()};
403 }
404
405 friend BookSpec
406 operator~(IOU const& iou)
407 {
408 return BookSpec(iou.account.id(), iou.currency);
409 }
410};
411
413operator<<(std::ostream& os, IOU const& iou);
414
415//------------------------------------------------------------------------------
416
424class MPT
425{
426public:
429
430 MPT(std::string const& n, ripple::MPTID const& issuanceID_)
431 : name(n), issuanceID(issuanceID_)
432 {
433 }
434
435 ripple::MPTID const&
436 mpt() const
437 {
438 return issuanceID;
439 }
440
446 operator ripple::MPTIssue() const
447 {
448 return MPTIssue{issuanceID};
449 }
450
451 template <class T>
452 requires(sizeof(T) >= sizeof(int) && std::is_arithmetic_v<T>)
454 operator()(T v) const
455 {
456 return {amountFromString(mpt(), std::to_string(v)), name};
457 }
458
463
464 friend BookSpec
466 {
467 assert(false);
468 Throw<std::logic_error>("MPT is not supported");
469 return BookSpec{beast::zero, noCurrency()};
470 }
471};
472
474operator<<(std::ostream& os, MPT const& mpt);
475
476//------------------------------------------------------------------------------
477
478struct any_t
479{
480 inline AnyAmount
481 operator()(STAmount const& sta) const;
482};
483
486{
487 bool is_any;
489
490 AnyAmount() = delete;
491 AnyAmount(AnyAmount const&) = default;
492 AnyAmount&
493 operator=(AnyAmount const&) = default;
494
495 AnyAmount(STAmount const& amount) : is_any(false), value(amount)
496 {
497 }
498
499 AnyAmount(STAmount const& amount, any_t const*)
500 : is_any(true), value(amount)
501 {
502 }
503
504 // Reset the issue to a specific account
505 void
506 to(AccountID const& id)
507 {
508 if (!is_any)
509 return;
510 value.setIssuer(id);
511 }
512};
513
514inline AnyAmount
516{
517 return AnyAmount(sta, this);
518}
519
523extern any_t const any;
524
525} // namespace jtx
526} // namespace test
527} // namespace ripple
528
529#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
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:107
std::string const & name() const
Return the name.
Definition: Account.h:83
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::MPTID const & mpt() const
PrettyAmount operator()(detail::epsilon_multiple) const
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:127
bool operator==(Account const &lhs, Account const &rhs) noexcept
Definition: Account.h:150
XRP_t const XRP
Converts to XRP Issue or STAmount.
Definition: amount.cpp:105
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.
Definition: AccountID.cpp:178
Currency const & noCurrency()
A placeholder for empty currencies.
Definition: UintTypes.cpp:126
Json::Value to_json(Asset const &asset)
Definition: Asset.h:123
Currency const & xrpCurrency()
XRP currency.
Definition: UintTypes.cpp:119
STAmount amountFromString(Asset const &asset, std::string const &amount)
Definition: STAmount.cpp:1025
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
STAmount const & value() const
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
PrettyAsset(Asset const &asset, unsigned int scale=1)
PrettyAmount operator()(T v) const
PrettyAsset(A const &asset, unsigned int 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)