19#include "../uint256/uint256.hpp"
28template <
class base_u
int>
class uintx {
41 constexpr uintx(
const base_uint input_lo)
46 constexpr uintx(
const base_uint input_lo,
const base_uint input_hi)
54 static constexpr size_t length() {
return 2 * base_uint::length(); }
59 constexpr explicit operator bool()
const {
return static_cast<bool>(
lo) ||
static_cast<bool>(
hi); };
60 constexpr explicit operator uint8_t()
const {
return static_cast<uint8_t
>(
lo); };
61 constexpr explicit operator uint16_t()
const {
return static_cast<uint16_t
>(
lo); };
62 constexpr explicit operator uint32_t()
const {
return static_cast<uint32_t
>(
lo); };
63 constexpr explicit operator uint64_t()
const {
return static_cast<uint64_t
>(
lo); };
65 constexpr explicit operator base_uint()
const {
return lo; }
67 [[nodiscard]]
bool get_bit(uint64_t bit_index)
const;
68 [[nodiscard]]
constexpr uint64_t
get_msb()
const
70 uint64_t hi_idx =
hi.get_msb();
71 uint64_t lo_idx =
lo.get_msb();
72 return (hi_idx || (
hi > base_uint(0))) ? (hi_idx + base_uint::length()) : lo_idx;
81 constexpr uintx slice(
const uint64_t start,
const uint64_t end)
const
83 const uint64_t range = end - start;
85 return ((*
this) >> start) & mask;
91 base_uint res_lo =
lo - other.
lo;
92 bool borrow = res_lo >
lo;
93 base_uint res_hi =
hi - other.
hi - ((borrow) ? base_uint(1) : base_uint(0));
94 return { res_lo, res_hi };
100 const uint64_t total_shift = other;
101 if (total_shift >=
length()) {
104 if (total_shift == 0) {
107 const uint64_t num_shifted_limbs = total_shift >> (base_uint(base_uint::length()).get_msb());
108 const uint64_t limb_shift = total_shift &
static_cast<uint64_t
>(base_uint::length() - 1);
111 if (limb_shift == 0) {
112 shifted_limbs[0] =
lo;
113 shifted_limbs[1] =
hi;
115 const uint64_t remainder_shift =
static_cast<uint64_t
>(base_uint::length()) - limb_shift;
117 shifted_limbs[0] =
lo << limb_shift;
119 base_uint remainder =
lo >> remainder_shift;
121 shifted_limbs[1] = (
hi << limb_shift) + remainder;
124 if (num_shifted_limbs == 0) {
125 result.
hi = shifted_limbs[1];
126 result.
lo = shifted_limbs[0];
128 result.
hi = shifted_limbs[0];
136 const uint64_t total_shift = other;
137 if (total_shift >=
length()) {
140 if (total_shift == 0) {
143 const uint64_t num_shifted_limbs = total_shift >> (base_uint(base_uint::length()).get_msb());
145 const uint64_t limb_shift = total_shift &
static_cast<uint64_t
>(base_uint::length() - 1);
148 if (limb_shift == 0) {
149 shifted_limbs[0] =
lo;
150 shifted_limbs[1] =
hi;
152 const uint64_t remainder_shift =
static_cast<uint64_t
>(base_uint::length()) - limb_shift;
154 shifted_limbs[1] =
hi >> limb_shift;
156 base_uint remainder = (
hi) << remainder_shift;
158 shifted_limbs[0] = (
lo >> limb_shift) + remainder;
161 if (num_shifted_limbs == 0) {
162 result.
hi = shifted_limbs[1];
163 result.
lo = shifted_limbs[0];
165 result.
lo = shifted_limbs[1];
173 base_uint res_lo =
lo + other.
lo;
174 bool carry = res_lo <
lo;
175 base_uint res_hi =
hi + other.
hi + ((carry) ? base_uint(1) : base_uint(0));
176 return { res_lo, res_hi };
204 *
this = *
this + other;
209 *
this = *
this - other;
214 *
this = *
this * other;
220 *
this = *
this / other;
226 *
this = *
this % other;
243 *
this = *
this & other;
248 *
this = *
this ^ other;
253 *
this = *
this | other;
259 *
this = *
this >> other;
264 *
this = *
this << other;
constexpr uintx(uintx &&other) noexcept=default
constexpr uintx(const uint256_t &data)
constexpr uintx operator+(const uintx &other) const
uintx operator%(const uintx &other) const
uintx & operator|=(const uintx &other)
uintx & operator*=(const uintx &other)
std::pair< uintx, uintx > divmod(const uintx &b) const
constexpr uintx(const base_uint input_lo, const base_uint input_hi)
constexpr uintx slice(const uint64_t start, const uint64_t end) const
uintx & operator>>=(const uint64_t other)
bool operator!=(const uintx &other) const
bool operator<(const uintx &other) const
uintx operator*(const uintx &other) const
uintx & operator&=(const uintx &other)
static constexpr size_t length()
uintx unsafe_invmod(const uintx &modulus) const
constexpr uintx operator-(const uintx &other) const
uintx & operator+=(const uintx &other)
uintx & operator=(uintx &&other) noexcept=default
std::pair< uintx, uintx > divmod_base(const uintx &b) const
bool operator==(const uintx &other) const
uintx & operator^=(const uintx &other)
bool operator>(const uintx &other) const
bool operator<=(const uintx &other) const
bool get_bit(uint64_t bit_index) const
constexpr uint64_t get_msb() const
uintx & operator-=(const uintx &other)
std::pair< uintx, uintx > barrett_reduction() const
uintx & operator<<=(const uint64_t other)
constexpr uintx operator&(const uintx &other) const
uintx operator|(const uintx &other) const
uintx & operator=(const uintx &other)=default
bool operator>=(const uintx &other) const
uintx operator/(const uintx &other) const
uintx & operator/=(const uintx &other)
std::pair< uintx, uintx > mul_extended(const uintx &other) const
constexpr uintx(const uint64_t &data=0)
constexpr uintx operator>>(const uint64_t other) const
uintx invmod(const uintx &modulus) const
uintx operator^(const uintx &other) const
constexpr uintx operator<<(const uint64_t other) const
uintx & operator%=(const uintx &other)
constexpr uintx(const uintx &other)=default
constexpr uintx(const base_uint input_lo)
const std::vector< MemoryValue > data
void read(B &it, uint256_t &value)
std::ostream & operator<<(std::ostream &os, uint256_t const &a)
void write(B &it, uint256_t const &value)
void read(auto &it, msgpack_concepts::HasMsgPack auto &obj)
Automatically derived read for any object that defines .msgpack() (implicitly defined by MSGPACK_FIEL...
void write(auto &buf, const msgpack_concepts::HasMsgPack auto &obj)
Automatically derived write for any object that defines .msgpack() (implicitly defined by MSGPACK_FIE...
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept