github.com/igggame/nebulas-go@v2.1.0+incompatible/nbre/common/nebulas_currency.h (about) 1 // Copyright (C) 2018 go-nebulas authors 2 // 3 // This file is part of the go-nebulas library. 4 // 5 // the go-nebulas library is free software: you can redistribute it and/or 6 // modify 7 // it under the terms of the GNU General Public License as published by 8 // the Free Software Foundation, either version 3 of the License, or 9 // (at your option) any later version. 10 // 11 // the go-nebulas library is distributed in the hope that it will be useful, 12 // but WITHOUT ANY WARRANTY; without even the implied warranty of 13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 // GNU General Public License for more details. 15 // 16 // You should have received a copy of the GNU General Public License 17 // along with the go-nebulas library. If not, see 18 // <http://www.gnu.org/licenses/>. 19 // 20 21 #pragma once 22 #include "common/byte.h" 23 #include "common/common.h" 24 25 namespace neb { 26 27 template <int64_t ratio> class nas_currency_t { 28 public: 29 typedef boost::multiprecision::int128_t nas_currency_value_t; 30 31 nas_currency_t() : m_value(0) {} 32 nas_currency_t(const nas_currency_value_t &v) : m_value(v) {} 33 34 template <int64_t r> 35 nas_currency_t(const nas_currency_t<r> &v) : m_value(v.wei_value()){}; 36 37 nas_currency_t(long double v) : m_value(v * ratio) {} 38 39 nas_currency_t(const nas_currency_t<ratio> &v) : m_value(v.m_value) {} 40 41 nas_currency_t<ratio> &operator=(const nas_currency_t<ratio> &v) { 42 if (&v == this) 43 return *this; 44 m_value = v.m_value; 45 return *this; 46 } 47 48 nas_currency_t<ratio> &operator++() { 49 m_value += ratio; 50 return *this; 51 } 52 nas_currency_t<ratio> operator++(int) { 53 nas_currency_t<ratio> tmp(*this); // copy 54 operator++(); // pre-increment 55 return tmp; // return old value 56 } 57 58 nas_currency_t<ratio> &operator--() { 59 m_value -= ratio; 60 return *this; 61 } 62 nas_currency_t<ratio> operator--(int) { 63 nas_currency_t<ratio> tmp(*this); // copy 64 operator--(); // pre-increment 65 return tmp; // return old value 66 } 67 68 template <int64_t r1, int64_t r2> 69 friend bool operator<(const nas_currency_t<r1> &l, 70 const nas_currency_t<r2> &r) { 71 return l.m_value < r.m_value; 72 } 73 template <int64_t r1, int64_t r2> 74 friend bool operator>(const nas_currency_t<r1> &lhs, 75 const nas_currency_t<r2> &rhs) { 76 return rhs < lhs; 77 } 78 template <int64_t r1, int64_t r2> 79 friend bool operator<=(const nas_currency_t<r1> &lhs, 80 const nas_currency_t<r2> &rhs) { 81 return !(lhs > rhs); 82 } 83 template <int64_t r1, int64_t r2> 84 friend bool operator>=(const nas_currency_t<r1> &lhs, 85 const nas_currency_t<r2> &rhs) { 86 return !(lhs < rhs); 87 } 88 template <int64_t r1, int64_t r2> 89 friend bool operator==(const nas_currency_t<r1> &lhs, 90 const nas_currency_t<r2> &rhs) { 91 return lhs.m_value == rhs.m_value; 92 } 93 template <int64_t r1, int64_t r2> 94 friend bool operator!=(const nas_currency_t<r1> &lhs, 95 const nas_currency_t<r2> &rhs) { 96 return lhs.m_value != rhs.m_value; 97 } 98 99 template <int64_t r1, int64_t r2> 100 friend nas_currency_t<r1> operator+(const nas_currency_t<r1> &l, 101 const nas_currency_t<r2> &r) { 102 nas_currency_t<r1> tmp; 103 tmp.m_value = l.m_value + r.m_value; 104 return tmp; 105 } 106 107 template <int64_t r1, int64_t r2> 108 friend nas_currency_t<r1> operator-(const nas_currency_t<r1> &l, 109 const nas_currency_t<r2> &r) { 110 nas_currency_t<r1> tmp; 111 tmp.m_value = l.m_value + r.m_value; 112 return tmp; 113 } 114 115 nas_currency_value_t wei_value() const { return m_value; } 116 117 long double value() const { 118 return m_value.convert_to<long double>() / ratio; 119 } 120 121 protected: 122 nas_currency_value_t m_value; 123 124 }; // end class nas_currency_unit 125 126 typedef nas_currency_t<1000000000000000000> nas; 127 typedef nas_currency_t<1> wei; 128 129 template <int64_t r1, int64_t r2> 130 nas_currency_t<r1> nas_cast(const nas_currency_t<r2> &v) { 131 return nas_currency_t<r1>(v); 132 } 133 134 template <class T> struct is_nas_currency { const static bool value = false; }; 135 template <int64_t r> struct is_nas_currency<nas_currency_t<r>> { 136 const static bool value = true; 137 }; 138 139 template <class T1, class T2> 140 auto nas_cast(const T2 &v) -> typename std::enable_if< 141 is_nas_currency<T1>::value && is_nas_currency<T2>::value, T1>::type { 142 return T1(v); 143 } 144 145 typedef fix_bytes<16> nas_storage_t; 146 147 template <typename T> nas_storage_t nas_to_storage(const T &v) { 148 nas::nas_currency_value_t cv = v.wei_value(); 149 150 uint64_t high = static_cast<uint64_t>(cv >> 64); 151 nas::nas_currency_value_t mask(0xFFFFFFFFFFFFFFFF); 152 auto lm = cv & mask; 153 uint64_t low = static_cast<uint64_t>(lm); 154 nas_storage_t ret; 155 uint64_t *low_ptr = (uint64_t *)ret.value(); 156 *low_ptr = boost::endian::native_to_big(high); 157 uint64_t *high_ptr = (uint64_t *)(ret.value() + 8); 158 *high_ptr = boost::endian::native_to_big(low); 159 160 return ret; 161 } 162 163 template <typename T> T storage_to_nas(const nas_storage_t &v) { 164 uint64_t low; 165 uint64_t high; 166 low = *(uint64_t *)(v.value()); 167 high = *(uint64_t *)(v.value() + 8); 168 169 low = boost::endian::big_to_native(low); 170 high = boost::endian::big_to_native(high); 171 nas::nas_currency_value_t cv(low); 172 cv = cv << 64; 173 cv += nas::nas_currency_value_t(high); 174 175 return nas(cv); 176 } 177 178 inline neb::bytes wei_to_storage(const wei_t &v) { 179 return from_fix_bytes(nas_to_storage(nas(v))); 180 } 181 inline wei_t storage_to_wei(const neb::bytes &v) { 182 return storage_to_nas<nas>(to_fix_bytes<nas_storage_t>(v)).wei_value(); 183 } 184 185 } // end namespace neb 186 187 neb::nas operator"" _nas(long double x); 188 neb::nas operator"" _nas(const char *s); 189 190 neb::wei operator"" _wei(long double x); 191 neb::wei operator"" _wei(const char *s); 192 193 std::ostream &operator<<(std::ostream &os, const neb::nas &obj); 194 195 std::ostream &operator<<(std::ostream &os, const neb::wei &obj);