rippled
STAmount.h
1 //------------------------------------------------------------------------------
2 /*
3  This file is part of rippled: https://github.com/ripple/rippled
4  Copyright (c) 2012, 2013 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_PROTOCOL_STAMOUNT_H_INCLUDED
21 #define RIPPLE_PROTOCOL_STAMOUNT_H_INCLUDED
22 
23 #include <ripple/basics/IOUAmount.h>
24 #include <ripple/basics/XRPAmount.h>
25 #include <ripple/protocol/Issue.h>
26 #include <ripple/protocol/SField.h>
27 #include <ripple/protocol/STBase.h>
28 #include <ripple/protocol/Serializer.h>
29 
30 namespace ripple {
31 
32 // Internal form:
33 // 1: If amount is zero, then value is zero and offset is -100
34 // 2: Otherwise:
35 // legal offset range is -96 to +80 inclusive
36 // value range is 10^15 to (10^16 - 1) inclusive
37 // amount = value * [10 ^ offset]
38 
39 // Wire form:
40 // High 8 bits are (offset+142), legal range is, 80 to 22 inclusive
41 // Low 56 bits are value, legal range is 10^15 to (10^16 - 1) inclusive
42 class STAmount : public STBase
43 {
44 public:
46  using exponent_type = int;
48 
49 private:
53  bool mIsNative; // A shorthand for isXRP(mIssue).
55 
56 public:
58 
59  static const int cMinOffset = -96;
60  static const int cMaxOffset = 80;
61 
62  // Maximum native value supported by the code
63  static const std::uint64_t cMinValue = 1000000000000000ull;
64  static const std::uint64_t cMaxValue = 9999999999999999ull;
65  static const std::uint64_t cMaxNative = 9000000000000000000ull;
66 
67  // Max native value on network.
68  static const std::uint64_t cMaxNativeN = 100000000000000000ull;
69  static const std::uint64_t cNotNative = 0x8000000000000000ull;
70  static const std::uint64_t cPosNative = 0x4000000000000000ull;
71 
72  static std::uint64_t const uRateOne;
73 
74  //--------------------------------------------------------------------------
75  STAmount(SerialIter& sit, SField const& name);
76 
77  struct unchecked
78  {
79  explicit unchecked() = default;
80  };
81 
82  // Do not call canonicalize
83  STAmount(
84  SField const& name,
85  Issue const& issue,
88  bool native,
89  bool negative,
90  unchecked);
91 
92  STAmount(
93  Issue const& issue,
96  bool native,
97  bool negative,
98  unchecked);
99 
100  // Call canonicalize
101  STAmount(
102  SField const& name,
103  Issue const& issue,
106  bool native,
107  bool negative);
108 
109  STAmount(SField const& name, std::int64_t mantissa);
110 
111  STAmount(
112  SField const& name,
114  bool negative = false);
115 
116  STAmount(
117  SField const& name,
118  Issue const& issue,
120  int exponent = 0,
121  bool negative = false);
122 
123  explicit STAmount(std::uint64_t mantissa = 0, bool negative = false);
124 
125  STAmount(
126  Issue const& issue,
128  int exponent = 0,
129  bool negative = false);
130 
131  // VFALCO Is this needed when we have the previous signature?
132  STAmount(
133  Issue const& issue,
135  int exponent = 0,
136  bool negative = false);
137 
138  STAmount(Issue const& issue, std::int64_t mantissa, int exponent = 0);
139 
140  STAmount(Issue const& issue, int mantissa, int exponent = 0);
141 
142  // Legacy support for new-style amounts
143  STAmount(IOUAmount const& amount, Issue const& issue);
144  STAmount(XRPAmount const& amount);
145 
146  STBase*
147  copy(std::size_t n, void* buf) const override
148  {
149  return emplace(n, buf, *this);
150  }
151 
152  STBase*
153  move(std::size_t n, void* buf) override
154  {
155  return emplace(n, buf, std::move(*this));
156  }
157 
158  //--------------------------------------------------------------------------
159 
160 private:
162  construct(SerialIter&, SField const& name);
163 
164  void
165  set(std::int64_t v);
166  void
167  canonicalize();
168 
169 public:
170  //--------------------------------------------------------------------------
171  //
172  // Observers
173  //
174  //--------------------------------------------------------------------------
175 
176  int
177  exponent() const noexcept
178  {
179  return mOffset;
180  }
181  bool
182  native() const noexcept
183  {
184  return mIsNative;
185  }
186  bool
187  negative() const noexcept
188  {
189  return mIsNegative;
190  }
192  mantissa() const noexcept
193  {
194  return mValue;
195  }
196  Issue const&
197  issue() const
198  {
199  return mIssue;
200  }
201 
202  // These three are deprecated
203  Currency const&
204  getCurrency() const
205  {
206  return mIssue.currency;
207  }
208  AccountID const&
209  getIssuer() const
210  {
211  return mIssue.account;
212  }
213 
214  int
215  signum() const noexcept
216  {
217  return mValue ? (mIsNegative ? -1 : 1) : 0;
218  }
219 
221  STAmount
222  zeroed() const
223  {
224  return STAmount(mIssue);
225  }
226 
227  void
228  setJson(Json::Value&) const;
229 
230  STAmount const&
231  value() const noexcept
232  {
233  return *this;
234  }
235 
236  //--------------------------------------------------------------------------
237  //
238  // Operators
239  //
240  //--------------------------------------------------------------------------
241 
242  explicit operator bool() const noexcept
243  {
244  return *this != beast::zero;
245  }
246 
247  STAmount&
248  operator+=(STAmount const&);
249  STAmount&
250  operator-=(STAmount const&);
251 
253  {
254  clear();
255  return *this;
256  }
257 
258  STAmount&
259  operator=(XRPAmount const& amount)
260  {
261  *this = STAmount(amount);
262  return *this;
263  }
264 
265  //--------------------------------------------------------------------------
266  //
267  // Modification
268  //
269  //--------------------------------------------------------------------------
270 
271  void
273  {
274  if (*this != beast::zero)
276  }
277 
278  void
280  {
281  // The -100 is used to allow 0 to sort less than a small positive values
282  // which have a negative exponent.
283  mOffset = mIsNative ? 0 : -100;
284  mValue = 0;
285  mIsNegative = false;
286  }
287 
288  // Zero while copying currency and issuer.
289  void
290  clear(STAmount const& saTmpl)
291  {
292  clear(saTmpl.mIssue);
293  }
294 
295  void
296  clear(Issue const& issue)
297  {
298  setIssue(issue);
299  clear();
300  }
301 
302  void
303  setIssuer(AccountID const& uIssuer)
304  {
305  mIssue.account = uIssuer;
306  setIssue(mIssue);
307  }
308 
310  void
311  setIssue(Issue const& issue);
312 
313  //--------------------------------------------------------------------------
314  //
315  // STBase
316  //
317  //--------------------------------------------------------------------------
318 
320  getSType() const override
321  {
322  return STI_AMOUNT;
323  }
324 
326  getFullText() const override;
327 
329  getText() const override;
330 
331  Json::Value getJson(JsonOptions) const override;
332 
333  void
334  add(Serializer& s) const override;
335 
336  bool
337  isEquivalent(const STBase& t) const override;
338 
339  bool
340  isDefault() const override
341  {
342  return (mValue == 0) && mIsNative;
343  }
344 
345  XRPAmount
346  xrp() const;
347  IOUAmount
348  iou() const;
349 };
350 
351 //------------------------------------------------------------------------------
352 //
353 // Creation
354 //
355 //------------------------------------------------------------------------------
356 
357 // VFALCO TODO The parameter type should be Quality not uint64_t
358 STAmount
360 
361 STAmount
362 amountFromString(Issue const& issue, std::string const& amount);
363 
364 STAmount
365 amountFromJson(SField const& name, Json::Value const& v);
366 
367 bool
368 amountFromJsonNoThrow(STAmount& result, Json::Value const& jvSource);
369 
370 // IOUAmount and XRPAmount define toSTAmount, defining this
371 // trivial conversion here makes writing generic code easier
372 inline STAmount const&
374 {
375  return a;
376 }
377 
378 //------------------------------------------------------------------------------
379 //
380 // Observers
381 //
382 //------------------------------------------------------------------------------
383 
384 inline bool
385 isLegalNet(STAmount const& value)
386 {
387  return !value.native() || (value.mantissa() <= STAmount::cMaxNativeN);
388 }
389 
390 //------------------------------------------------------------------------------
391 //
392 // Operators
393 //
394 //------------------------------------------------------------------------------
395 
396 bool
397 operator==(STAmount const& lhs, STAmount const& rhs);
398 bool
399 operator<(STAmount const& lhs, STAmount const& rhs);
400 
401 inline bool
402 operator!=(STAmount const& lhs, STAmount const& rhs)
403 {
404  return !(lhs == rhs);
405 }
406 
407 inline bool
408 operator>(STAmount const& lhs, STAmount const& rhs)
409 {
410  return rhs < lhs;
411 }
412 
413 inline bool
414 operator<=(STAmount const& lhs, STAmount const& rhs)
415 {
416  return !(rhs < lhs);
417 }
418 
419 inline bool
420 operator>=(STAmount const& lhs, STAmount const& rhs)
421 {
422  return !(lhs < rhs);
423 }
424 
425 STAmount
426 operator-(STAmount const& value);
427 
428 //------------------------------------------------------------------------------
429 //
430 // Arithmetic
431 //
432 //------------------------------------------------------------------------------
433 
434 STAmount
435 operator+(STAmount const& v1, STAmount const& v2);
436 STAmount
437 operator-(STAmount const& v1, STAmount const& v2);
438 
439 STAmount
440 divide(STAmount const& v1, STAmount const& v2, Issue const& issue);
441 
442 STAmount
443 multiply(STAmount const& v1, STAmount const& v2, Issue const& issue);
444 
445 // multiply, or divide rounding result in specified direction
446 STAmount
447 mulRound(
448  STAmount const& v1,
449  STAmount const& v2,
450  Issue const& issue,
451  bool roundUp);
452 
453 STAmount
454 divRound(
455  STAmount const& v1,
456  STAmount const& v2,
457  Issue const& issue,
458  bool roundUp);
459 
460 // Someone is offering X for Y, what is the rate?
461 // Rate: smaller is better, the taker wants the most out: in/out
462 // VFALCO TODO Return a Quality object
464 getRate(STAmount const& offerOut, STAmount const& offerIn);
465 
466 //------------------------------------------------------------------------------
467 
468 inline bool
469 isXRP(STAmount const& amount)
470 {
471  return isXRP(amount.issue().currency);
472 }
473 
474 } // namespace ripple
475 
476 #endif
ripple::STAmount::mIsNative
bool mIsNative
Definition: STAmount.h:53
ripple::STAmount::clear
void clear(STAmount const &saTmpl)
Definition: STAmount.h:290
ripple::STAmount::negate
void negate()
Definition: STAmount.h:272
ripple::operator>
bool operator>(base_uint< Bits, Tag > const &a, base_uint< Bits, Tag > const &b)
Definition: base_uint.h:492
ripple::amountFromJsonNoThrow
bool amountFromJsonNoThrow(STAmount &result, Json::Value const &jvSource)
Definition: STAmount.cpp:931
ripple::STAmount::move
STBase * move(std::size_t n, void *buf) override
Definition: STAmount.h:153
ripple::Issue
A currency issued by an account.
Definition: Issue.h:34
std::string
STL class.
ripple::STAmount::cMinValue
static const std::uint64_t cMinValue
Definition: STAmount.h:63
ripple::STAmount::set
void set(std::int64_t v)
Definition: STAmount.cpp:732
ripple::JsonOptions
JsonOptions
Definition: STBase.h:34
ripple::STAmount::clear
void clear()
Definition: STAmount.h:279
ripple::STAmount::mantissa
std::uint64_t mantissa() const noexcept
Definition: STAmount.h:192
std::pair
ripple::operator>=
bool operator>=(base_uint< Bits, Tag > const &a, base_uint< Bits, Tag > const &b)
Definition: base_uint.h:499
ripple::STI_AMOUNT
@ STI_AMOUNT
Definition: SField.h:64
ripple::STAmount::getText
std::string getText() const override
Definition: STAmount.cpp:510
ripple::STAmount::getJson
Json::Value getJson(JsonOptions) const override
Definition: STAmount.cpp:594
ripple::SerializedTypeID
SerializedTypeID
Definition: SField.h:52
ripple::STAmount::cMaxNative
static const std::uint64_t cMaxNative
Definition: STAmount.h:65
ripple::STAmount::mValue
mantissa_type mValue
Definition: STAmount.h:51
ripple::Issue::currency
Currency currency
Definition: Issue.h:37
ripple::STAmount::signum
int signum() const noexcept
Definition: STAmount.h:215
ripple::STAmount::cMinOffset
static const int cMinOffset
Definition: STAmount.h:59
ripple::isLegalNet
bool isLegalNet(STAmount const &value)
Definition: STAmount.h:385
ripple::operator-
STAmount operator-(STAmount const &v1, STAmount const &v2)
Definition: STAmount.cpp:414
ripple::STAmount::cNotNative
static const std::uint64_t cNotNative
Definition: STAmount.h:69
ripple::IOUAmount
Floating point representation of amounts with high dynamic range.
Definition: IOUAmount.h:41
ripple::STAmount::setIssuer
void setIssuer(AccountID const &uIssuer)
Definition: STAmount.h:303
ripple::STAmount::zeroed
STAmount zeroed() const
Returns a zero value with the same issuer and currency.
Definition: STAmount.h:222
ripple::STAmount::operator=
STAmount & operator=(XRPAmount const &amount)
Definition: STAmount.h:259
ripple::STAmount::iou
IOUAmount iou() const
Definition: STAmount.cpp:314
ripple::STAmount::operator-=
STAmount & operator-=(STAmount const &)
Definition: STAmount.cpp:342
ripple::STAmount::xrp
XRPAmount xrp() const
Definition: STAmount.cpp:299
ripple::operator==
bool operator==(Manifest const &lhs, Manifest const &rhs)
Definition: Manifest.h:155
ripple::mulRound
STAmount mulRound(STAmount const &v1, STAmount const &v2, Issue const &issue, bool roundUp)
Definition: STAmount.cpp:1199
ripple::STAmount::copy
STBase * copy(std::size_t n, void *buf) const override
Definition: STAmount.h:147
ripple::getRate
std::uint64_t getRate(STAmount const &offerOut, STAmount const &offerIn)
Definition: STAmount.cpp:440
ripple::divide
STAmount divide(STAmount const &amount, Rate const &rate)
Definition: Rate2.cpp:77
ripple::STBase::emplace
static STBase * emplace(std::size_t n, void *buf, T &&val)
Definition: STBase.h:149
ripple::base_uint< 160, detail::CurrencyTag >
ripple::STAmount::getFullText
std::string getFullText() const override
Definition: STAmount.cpp:487
ripple::STAmount::exponent
int exponent() const noexcept
Definition: STAmount.h:177
ripple::operator<=
bool operator<=(base_uint< Bits, Tag > const &a, base_uint< Bits, Tag > const &b)
Definition: base_uint.h:485
ripple::STAmount::mIssue
Issue mIssue
Definition: STAmount.h:50
ripple::STAmount::setJson
void setJson(Json::Value &) const
Definition: STAmount.cpp:462
ripple::operator+
const base_uint< Bits, Tag > operator+(base_uint< Bits, Tag > const &a, base_uint< Bits, Tag > const &b)
Definition: base_uint.h:557
ripple::STAmount::STAmount
STAmount(SerialIter &sit, SField const &name)
Definition: STAmount.cpp:65
ripple::operator<
bool operator<(CanonicalTXSet::Key const &lhs, CanonicalTXSet::Key const &rhs)
Definition: CanonicalTXSet.cpp:25
ripple::STAmount::clear
void clear(Issue const &issue)
Definition: STAmount.h:296
ripple::divRound
STAmount divRound(STAmount const &num, STAmount const &den, Issue const &issue, bool roundUp)
Definition: STAmount.cpp:1285
ripple::STAmount::unchecked::unchecked
unchecked()=default
ripple::toSTAmount
STAmount toSTAmount(IOUAmount const &iou, Issue const &iss)
Definition: AmountConversions.h:30
ripple::operator!=
bool operator!=(Manifest const &lhs, Manifest const &rhs)
Definition: Manifest.h:165
beast::Zero
Zero allows classes to offer efficient comparisons to zero.
Definition: Zero.h:42
ripple::STAmount
Definition: STAmount.h:42
ripple::amountFromJson
STAmount amountFromJson(SField const &name, Json::Value const &v)
Definition: STAmount.cpp:826
ripple::isXRP
bool isXRP(AccountID const &c)
Definition: AccountID.h:89
ripple::SerialIter
Definition: Serializer.h:308
std::uint64_t
ripple::STAmount::setIssue
void setIssue(Issue const &issue)
Set the Issue for this amount and update mIsNative.
Definition: STAmount.cpp:424
ripple::STAmount::construct
static std::unique_ptr< STAmount > construct(SerialIter &, SField const &name)
Definition: STAmount.cpp:288
ripple::amountFromQuality
STAmount amountFromQuality(std::uint64_t rate)
Definition: STAmount.cpp:749
ripple::STAmount::getCurrency
Currency const & getCurrency() const
Definition: STAmount.h:204
ripple::STAmount::getIssuer
AccountID const & getIssuer() const
Definition: STAmount.h:209
ripple::multiply
STAmount multiply(STAmount const &amount, Rate const &rate)
Definition: Rate2.cpp:38
ripple::Serializer
Definition: Serializer.h:39
ripple::STAmount::isEquivalent
bool isEquivalent(const STBase &t) const override
Definition: STAmount.cpp:633
ripple::STAmount::native
bool native() const noexcept
Definition: STAmount.h:182
ripple::STAmount::operator+=
STAmount & operator+=(STAmount const &)
Definition: STAmount.cpp:335
ripple
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition: RCLCensorshipDetector.h:29
ripple::STAmount::mIsNegative
bool mIsNegative
Definition: STAmount.h:54
ripple::amountFromString
STAmount amountFromString(Issue const &issue, std::string const &amount)
Definition: STAmount.cpp:761
ripple::STAmount::isDefault
bool isDefault() const override
Definition: STAmount.h:340
ripple::STAmount::unchecked
Definition: STAmount.h:77
ripple::SField
Identifies fields.
Definition: SField.h:109
ripple::STBase
A type which can be exported to a well known binary format.
Definition: STBase.h:62
ripple::STAmount::issue
Issue const & issue() const
Definition: STAmount.h:197
ripple::STAmount::canonicalize
void canonicalize()
Definition: STAmount.cpp:658
ripple::STAmount::add
void add(Serializer &s) const override
Definition: STAmount.cpp:602
ripple::STAmount::value
STAmount const & value() const noexcept
Definition: STAmount.h:231
ripple::STAmount::negative
bool negative() const noexcept
Definition: STAmount.h:187
ripple::STAmount::exponent_type
int exponent_type
Definition: STAmount.h:46
std::size_t
ripple::STAmount::cMaxNativeN
static const std::uint64_t cMaxNativeN
Definition: STAmount.h:68
ripple::STAmount::cMaxOffset
static const int cMaxOffset
Definition: STAmount.h:60
std::unique_ptr
STL class.
ripple::STAmount::mOffset
exponent_type mOffset
Definition: STAmount.h:52
ripple::STAmount::cPosNative
static const std::uint64_t cPosNative
Definition: STAmount.h:70
ripple::STAmount::uRateOne
static const std::uint64_t uRateOne
Definition: STAmount.h:72
ripple::STAmount::getSType
SerializedTypeID getSType() const override
Definition: STAmount.h:320
ripple::Issue::account
AccountID account
Definition: Issue.h:38
ripple::STAmount::cMaxValue
static const std::uint64_t cMaxValue
Definition: STAmount.h:64
ripple::STAmount::operator=
STAmount & operator=(beast::Zero)
Definition: STAmount.h:252
Json::Value
Represents a JSON value.
Definition: json_value.h:145
ripple::XRPAmount
Definition: XRPAmount.h:46