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/SField.h>
26 #include <ripple/protocol/Serializer.h>
27 #include <ripple/protocol/STBase.h>
28 #include <ripple/protocol/Issue.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
43  : public STBase
44 {
45 public:
47  using exponent_type = int;
49 
50 private:
54  bool mIsNative; // A shorthand for isXRP(mIssue).
56 
57 public:
59 
60  static const int cMinOffset = -96;
61  static const int cMaxOffset = 80;
62 
63  // Maximum native value supported by the code
64  static const std::uint64_t cMinValue = 1000000000000000ull;
65  static const std::uint64_t cMaxValue = 9999999999999999ull;
66  static const std::uint64_t cMaxNative = 9000000000000000000ull;
67 
68  // Max native value on network.
69  static const std::uint64_t cMaxNativeN = 100000000000000000ull;
70  static const std::uint64_t cNotNative = 0x8000000000000000ull;
71  static const std::uint64_t cPosNative = 0x4000000000000000ull;
72 
73  static std::uint64_t const uRateOne;
74 
75  //--------------------------------------------------------------------------
76  STAmount(SerialIter& sit, SField const& name);
77 
78  struct unchecked
79  {
80  explicit unchecked() = default;
81  };
82 
83  // Do not call canonicalize
84  STAmount (SField const& name, Issue const& issue,
86  bool native, bool negative, unchecked);
87 
88  STAmount (Issue const& issue,
90  bool native, bool negative, unchecked);
91 
92  // Call canonicalize
93  STAmount (SField const& name, Issue const& issue,
95  bool native, bool negative);
96 
97  STAmount (SField const& name, std::int64_t mantissa);
98 
99  STAmount (SField const& name,
100  std::uint64_t mantissa = 0, bool negative = false);
101 
102  STAmount (SField const& name, Issue const& issue,
103  std::uint64_t mantissa = 0, int exponent = 0, bool negative = false);
104 
105  explicit
106  STAmount (std::uint64_t mantissa = 0, bool negative = false);
107 
108  STAmount (Issue const& issue, std::uint64_t mantissa = 0, int exponent = 0,
109  bool negative = false);
110 
111  // VFALCO Is this needed when we have the previous signature?
113  bool negative = false);
114 
115  STAmount (Issue const& issue, std::int64_t mantissa, int exponent = 0);
116 
117  STAmount (Issue const& issue, int mantissa, int exponent = 0);
118 
119  // Legacy support for new-style amounts
120  STAmount (IOUAmount const& amount, Issue const& issue);
121  STAmount (XRPAmount const& amount);
122 
123  STBase*
124  copy (std::size_t n, void* buf) const override
125  {
126  return emplace(n, buf, *this);
127  }
128 
129  STBase*
130  move (std::size_t n, void* buf) override
131  {
132  return emplace(n, buf, std::move(*this));
133  }
134 
135  //--------------------------------------------------------------------------
136 
137 private:
138  static
140  construct (SerialIter&, SField const& name);
141 
142  void set (std::int64_t v);
143  void canonicalize();
144 
145 public:
146  //--------------------------------------------------------------------------
147  //
148  // Observers
149  //
150  //--------------------------------------------------------------------------
151 
152  int exponent() const noexcept { return mOffset; }
153  bool native() const noexcept { return mIsNative; }
154  bool negative() const noexcept { return mIsNegative; }
155  std::uint64_t mantissa() const noexcept { return mValue; }
156  Issue const& issue() const { return mIssue; }
157 
158  // These three are deprecated
159  Currency const& getCurrency() const { return mIssue.currency; }
160  AccountID const& getIssuer() const { return mIssue.account; }
161 
162  int
163  signum() const noexcept
164  {
165  return mValue ? (mIsNegative ? -1 : 1) : 0;
166  }
167 
169  STAmount
170  zeroed() const
171  {
172  return STAmount (mIssue);
173  }
174 
175  void
176  setJson (Json::Value&) const;
177 
178  STAmount const&
179  value() const noexcept
180  {
181  return *this;
182  }
183 
184  //--------------------------------------------------------------------------
185  //
186  // Operators
187  //
188  //--------------------------------------------------------------------------
189 
190  explicit operator bool() const noexcept
191  {
192  return *this != beast::zero;
193  }
194 
195  STAmount& operator+= (STAmount const&);
196  STAmount& operator-= (STAmount const&);
197 
199  {
200  clear();
201  return *this;
202  }
203 
204  STAmount& operator= (XRPAmount const& amount)
205  {
206  *this = STAmount (amount);
207  return *this;
208  }
209 
210  //--------------------------------------------------------------------------
211  //
212  // Modification
213  //
214  //--------------------------------------------------------------------------
215 
216  void negate()
217  {
218  if (*this != beast::zero)
220  }
221 
222  void clear()
223  {
224  // The -100 is used to allow 0 to sort less than a small positive values
225  // which have a negative exponent.
226  mOffset = mIsNative ? 0 : -100;
227  mValue = 0;
228  mIsNegative = false;
229  }
230 
231  // Zero while copying currency and issuer.
232  void clear (STAmount const& saTmpl)
233  {
234  clear (saTmpl.mIssue);
235  }
236 
237  void clear (Issue const& issue)
238  {
239  setIssue(issue);
240  clear();
241  }
242 
243  void setIssuer (AccountID const& uIssuer)
244  {
245  mIssue.account = uIssuer;
246  setIssue(mIssue);
247  }
248 
250  void setIssue (Issue const& issue);
251 
252  //--------------------------------------------------------------------------
253  //
254  // STBase
255  //
256  //--------------------------------------------------------------------------
257 
259  getSType() const override
260  {
261  return STI_AMOUNT;
262  }
263 
265  getFullText() const override;
266 
268  getText() const override;
269 
271  getJson (JsonOptions) const override;
272 
273  void
274  add (Serializer& s) const override;
275 
276  bool
277  isEquivalent (const STBase& t) const override;
278 
279  bool
280  isDefault() const override
281  {
282  return (mValue == 0) && mIsNative;
283  }
284 
285  XRPAmount xrp () const;
286  IOUAmount iou () const;
287 };
288 
289 //------------------------------------------------------------------------------
290 //
291 // Creation
292 //
293 //------------------------------------------------------------------------------
294 
295 // VFALCO TODO The parameter type should be Quality not uint64_t
296 STAmount
298 
299 STAmount
300 amountFromString (Issue const& issue, std::string const& amount);
301 
302 STAmount
303 amountFromJson (SField const& name, Json::Value const& v);
304 
305 bool
306 amountFromJsonNoThrow (STAmount& result, Json::Value const& jvSource);
307 
308 // IOUAmount and XRPAmount define toSTAmount, defining this
309 // trivial conversion here makes writing generic code easier
310 inline
311 STAmount const&
313 {
314  return a;
315 }
316 
317 //------------------------------------------------------------------------------
318 //
319 // Observers
320 //
321 //------------------------------------------------------------------------------
322 
323 inline
324 bool
325 isLegalNet (STAmount const& value)
326 {
327  return ! value.native() || (value.mantissa() <= STAmount::cMaxNativeN);
328 }
329 
330 //------------------------------------------------------------------------------
331 //
332 // Operators
333 //
334 //------------------------------------------------------------------------------
335 
336 bool operator== (STAmount const& lhs, STAmount const& rhs);
337 bool operator< (STAmount const& lhs, STAmount const& rhs);
338 
339 inline
340 bool
341 operator!= (STAmount const& lhs, STAmount const& rhs)
342 {
343  return !(lhs == rhs);
344 }
345 
346 inline
347 bool
348 operator> (STAmount const& lhs, STAmount const& rhs)
349 {
350  return rhs < lhs;
351 }
352 
353 inline
354 bool
355 operator<= (STAmount const& lhs, STAmount const& rhs)
356 {
357  return !(rhs < lhs);
358 }
359 
360 inline
361 bool
362 operator>= (STAmount const& lhs, STAmount const& rhs)
363 {
364  return !(lhs < rhs);
365 }
366 
367 STAmount operator- (STAmount const& value);
368 
369 //------------------------------------------------------------------------------
370 //
371 // Arithmetic
372 //
373 //------------------------------------------------------------------------------
374 
375 STAmount operator+ (STAmount const& v1, STAmount const& v2);
376 STAmount operator- (STAmount const& v1, STAmount const& v2);
377 
378 STAmount
379 divide (STAmount const& v1, STAmount const& v2, Issue const& issue);
380 
381 STAmount
382 multiply (STAmount const& v1, STAmount const& v2, Issue const& issue);
383 
384 // multiply, or divide rounding result in specified direction
385 STAmount
386 mulRound (STAmount const& v1, STAmount const& v2,
387  Issue const& issue, bool roundUp);
388 
389 STAmount
390 divRound (STAmount const& v1, STAmount const& v2,
391  Issue const& issue, bool roundUp);
392 
393 // Someone is offering X for Y, what is the rate?
394 // Rate: smaller is better, the taker wants the most out: in/out
395 // VFALCO TODO Return a Quality object
397 getRate (STAmount const& offerOut, STAmount const& offerIn);
398 
399 //------------------------------------------------------------------------------
400 
401 inline bool isXRP(STAmount const& amount)
402 {
403  return isXRP (amount.issue().currency);
404 }
405 
406 } // ripple
407 
408 #endif
ripple::STAmount::mIsNative
bool mIsNative
Definition: STAmount.h:54
ripple::STAmount::clear
void clear(STAmount const &saTmpl)
Definition: STAmount.h:232
ripple::STAmount::negate
void negate()
Definition: STAmount.h:216
ripple::operator>
bool operator>(base_uint< Bits, Tag > const &a, base_uint< Bits, Tag > const &b)
Definition: base_uint.h:470
ripple::amountFromJsonNoThrow
bool amountFromJsonNoThrow(STAmount &result, Json::Value const &jvSource)
Definition: STAmount.cpp:911
ripple::STAmount::move
STBase * move(std::size_t n, void *buf) override
Definition: STAmount.h:130
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:64
ripple::STAmount::set
void set(std::int64_t v)
Definition: STAmount.cpp:712
ripple::JsonOptions
JsonOptions
Definition: STBase.h:34
ripple::STAmount::clear
void clear()
Definition: STAmount.h:222
ripple::STAmount::mantissa
std::uint64_t mantissa() const noexcept
Definition: STAmount.h:155
std::pair
ripple::operator>=
bool operator>=(base_uint< Bits, Tag > const &a, base_uint< Bits, Tag > const &b)
Definition: base_uint.h:477
ripple::STI_AMOUNT
@ STI_AMOUNT
Definition: SField.h:65
ripple::STAmount::getText
std::string getText() const override
Definition: STAmount.cpp:492
ripple::STAmount::getJson
Json::Value getJson(JsonOptions) const override
Definition: STAmount.cpp:582
ripple::SerializedTypeID
SerializedTypeID
Definition: SField.h:52
ripple::STAmount::cMaxNative
static const std::uint64_t cMaxNative
Definition: STAmount.h:66
ripple::STAmount::mValue
mantissa_type mValue
Definition: STAmount.h:52
ripple::Issue::currency
Currency currency
Definition: Issue.h:37
ripple::STAmount::signum
int signum() const noexcept
Definition: STAmount.h:163
ripple::STAmount::cMinOffset
static const int cMinOffset
Definition: STAmount.h:60
ripple::isLegalNet
bool isLegalNet(STAmount const &value)
Definition: STAmount.h:325
ripple::operator-
STAmount operator-(STAmount const &v1, STAmount const &v2)
Definition: STAmount.cpp:397
ripple::STAmount::cNotNative
static const std::uint64_t cNotNative
Definition: STAmount.h:70
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:243
ripple::STAmount::zeroed
STAmount zeroed() const
Returns a zero value with the same issuer and currency.
Definition: STAmount.h:170
ripple::STAmount::iou
IOUAmount iou() const
Definition: STAmount.cpp:309
ripple::STAmount::operator-=
STAmount & operator-=(STAmount const &)
Definition: STAmount.cpp:335
ripple::STAmount::xrp
XRPAmount xrp() const
Definition: STAmount.cpp:294
ripple::operator==
bool operator==(Manifest const &lhs, Manifest const &rhs)
Definition: Manifest.h:148
ripple::mulRound
STAmount mulRound(STAmount const &v1, STAmount const &v2, Issue const &issue, bool roundUp)
Definition: STAmount.cpp:1173
ripple::STAmount::copy
STBase * copy(std::size_t n, void *buf) const override
Definition: STAmount.h:124
ripple::getRate
std::uint64_t getRate(STAmount const &offerOut, STAmount const &offerIn)
Definition: STAmount.cpp:423
ripple::divide
STAmount divide(STAmount const &amount, Rate const &rate)
Definition: Rate2.cpp:92
ripple::STBase::emplace
static STBase * emplace(std::size_t n, void *buf, T &&val)
Definition: STBase.h:161
ripple::base_uint< 160, detail::CurrencyTag >
ripple::STAmount::getFullText
std::string getFullText() const override
Definition: STAmount.cpp:469
ripple::STAmount::exponent
int exponent() const noexcept
Definition: STAmount.h:152
ripple::operator<=
bool operator<=(base_uint< Bits, Tag > const &a, base_uint< Bits, Tag > const &b)
Definition: base_uint.h:463
ripple::STAmount::mIssue
Issue mIssue
Definition: STAmount.h:51
ripple::STAmount::setJson
void setJson(Json::Value &) const
Definition: STAmount.cpp:444
ripple::operator+
const base_uint< Bits, Tag > operator+(base_uint< Bits, Tag > const &a, base_uint< Bits, Tag > const &b)
Definition: base_uint.h:533
ripple::STAmount::STAmount
STAmount(SerialIter &sit, SField const &name)
Definition: STAmount.cpp:68
ripple::STAmount::clear
void clear(Issue const &issue)
Definition: STAmount.h:237
ripple::divRound
STAmount divRound(STAmount const &num, STAmount const &den, Issue const &issue, bool roundUp)
Definition: STAmount.cpp:1257
ripple::STAmount::unchecked::unchecked
unchecked()=default
ripple::toSTAmount
STAmount toSTAmount(IOUAmount const &iou, Issue const &iss)
Definition: AmountConversions.h:31
ripple::operator!=
bool operator!=(Manifest const &lhs, Manifest const &rhs)
Definition: Manifest.h:161
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:805
ripple::isXRP
bool isXRP(AccountID const &c)
Definition: AccountID.h:121
ripple::SerialIter
Definition: Serializer.h:311
std::uint64_t
ripple::STAmount::setIssue
void setIssue(Issue const &issue)
Set the Issue for this amount and update mIsNative.
Definition: STAmount.cpp:407
ripple::STAmount::construct
static std::unique_ptr< STAmount > construct(SerialIter &, SField const &name)
Definition: STAmount.cpp:283
ripple::amountFromQuality
STAmount amountFromQuality(std::uint64_t rate)
Definition: STAmount.cpp:729
ripple::STAmount::getCurrency
Currency const & getCurrency() const
Definition: STAmount.h:159
ripple::STAmount::getIssuer
AccountID const & getIssuer() const
Definition: STAmount.h:160
ripple::multiply
STAmount multiply(STAmount const &amount, Rate const &rate)
Definition: Rate2.cpp:37
ripple::Serializer
Definition: Serializer.h:43
ripple::STAmount::isEquivalent
bool isEquivalent(const STBase &t) const override
Definition: STAmount.cpp:616
ripple::STAmount::native
bool native() const noexcept
Definition: STAmount.h:153
ripple::STAmount::operator+=
STAmount & operator+=(STAmount const &)
Definition: STAmount.cpp:329
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:55
ripple::amountFromString
STAmount amountFromString(Issue const &issue, std::string const &amount)
Definition: STAmount.cpp:741
ripple::STAmount::isDefault
bool isDefault() const override
Definition: STAmount.h:280
ripple::STAmount::unchecked
Definition: STAmount.h:78
ripple::SField
Identifies fields.
Definition: SField.h:112
ripple::STBase
A type which can be exported to a well known binary format.
Definition: STBase.h:65
ripple::STAmount::issue
Issue const & issue() const
Definition: STAmount.h:156
ripple::STAmount::canonicalize
void canonicalize()
Definition: STAmount.cpp:640
ripple::STAmount::add
void add(Serializer &s) const override
Definition: STAmount.cpp:590
ripple::STAmount::value
STAmount const & value() const noexcept
Definition: STAmount.h:179
ripple::STAmount::negative
bool negative() const noexcept
Definition: STAmount.h:154
ripple::STAmount::exponent_type
int exponent_type
Definition: STAmount.h:47
std::size_t
ripple::STAmount::cMaxNativeN
static const std::uint64_t cMaxNativeN
Definition: STAmount.h:69
ripple::STAmount::cMaxOffset
static const int cMaxOffset
Definition: STAmount.h:61
ripple::operator<
bool operator<(base_uint< Bits, Tag > const &a, base_uint< Bits, Tag > const &b)
Definition: base_uint.h:456
std::unique_ptr
STL class.
ripple::STAmount::mOffset
exponent_type mOffset
Definition: STAmount.h:53
ripple::STAmount::cPosNative
static const std::uint64_t cPosNative
Definition: STAmount.h:71
ripple::STAmount::uRateOne
static const std::uint64_t uRateOne
Definition: STAmount.h:73
ripple::STAmount::getSType
SerializedTypeID getSType() const override
Definition: STAmount.h:259
ripple::Issue::account
AccountID account
Definition: Issue.h:38
ripple::STAmount::cMaxValue
static const std::uint64_t cMaxValue
Definition: STAmount.h:65
ripple::STAmount::operator=
STAmount & operator=(beast::Zero)
Definition: STAmount.h:198
Json::Value
Represents a JSON value.
Definition: json_value.h:141
ripple::XRPAmount
Definition: XRPAmount.h:46