19template <
class... Ts>
struct overloads : Ts... {
20 using Ts::operator()...;
23template <
class... Ts> overloads(Ts...) -> overloads<Ts...>;
25template <std::
integral T> T safe_shift_left(T
a, T
b)
27 constexpr size_t bits =
sizeof(T) * 8;
29 return static_cast<T
>(0);
31 return static_cast<T
>(
a <<
b);
35 template <
typename T> T operator()(
const T&
a,
const T&
b)
const
38 return static_cast<T
>(
b == uint1_t(0) ?
a : uint1_t(0));
40 return safe_shift_left<T>(
a,
b);
45template <std::
integral T> T safe_shift_right(T
a, T
b)
47 constexpr size_t bits =
sizeof(T) * 8;
49 return static_cast<T
>(0);
51 return static_cast<T
>(
a >>
b);
55 template <
typename T> T operator()(
const T&
a,
const T&
b)
const
58 return static_cast<T
>(
b == uint1_t(0) ?
a : uint1_t(0));
60 return safe_shift_right<T>(
a,
b);
66 template <
typename T,
typename U>
bool operator()(
const T&
a,
const U&
b)
const
77 template <
typename T,
typename U>
bool operator()(
const T&
a,
const U&
b)
const
90struct less_than_equal {
91 template <
typename T,
typename U>
bool operator()(
const T&
a,
const U&
b)
const
102struct checked_divides {
103 template <
typename T>
auto operator()(T&&
a, T&&
b)
const
105 if (
b ==
static_cast<T
>(0)) {
106 throw DivisionByZero(
"Dividing numeric value by zero");
112template <
typename Op>
113constexpr bool is_bitwise_operation_v =
118template <
typename Op>
struct BinaryOperationVisitor {
123 throw InvalidOperationTag(
"Bitwise operations not valid for FF");
126 return static_cast<T
>(Op{}(
a,
b));
129 throw TagMismatchException(
"Cannot perform operation between different types: " +
136template <
typename Op>
struct UnaryOperationVisitor {
140 throw InvalidOperationTag(
"Can't do unary bitwise operations on an FF");
143 return static_cast<T
>(Op{}(
a));
149template <
typename Op>
struct ComparisonOperationVisitor {
150 template <
typename T,
typename U>
bool operator()(
const T&
a,
const U&
b)
const
181 assert(
false &&
"Invalid tag");
200 assert(
false &&
"Invalid tag");
218 assert(
false &&
"Invalid tag");
229 auto assert_bounds = [](
const FF&
value, uint8_t bits) {
231 throw std::runtime_error(
"Value out of bounds");
238 assert_bounds(
value, 1);
241 assert_bounds(
value, 8);
244 assert_bounds(
value, 16);
247 assert_bounds(
value, 32);
250 assert_bounds(
value, 64);
253 assert_bounds(
value, 128);
280 throw std::runtime_error(
"Invalid tag");
302 return std::visit(BinaryOperationVisitor<checked_divides>(),
value, other.
value);
329 return std::visit(BinaryOperationVisitor<shift_left>(),
value, other.
value);
334 return std::visit(BinaryOperationVisitor<shift_right>(),
value, other.
value);
341 return std::visit(ComparisonOperationVisitor<less_than>(),
value, other.
value);
347 return std::visit(ComparisonOperationVisitor<greater_than>(),
value, other.
value);
353 return std::visit(ComparisonOperationVisitor<less_than_equal>(),
value, other.
value);
370 const auto visitor = overloads{ [](
FF val) ->
FF {
return val; },
371 [](
uint1_t val) ->
FF {
return val.value(); },
373 [](
auto&& val) ->
FF {
return val; } };
375 return std::visit(visitor,
value);
384 return index_to_tag[
value.index()];
389 std::string v = std::visit(
392 [](
const uint1_t& val) -> std::string {
return val.value() == 0 ?
"0" :
"1"; },
425 return value.to_string();
TaggedValue operator>>(const TaggedValue &other) const
TaggedValue operator+(const TaggedValue &other) const
bool operator<=(const TaggedValue &other) const
TaggedValue operator~() const
std::variant< uint8_t, uint1_t, uint16_t, uint32_t, uint64_t, uint128_t, FF > value_type
bool operator>(const TaggedValue &other) const
TaggedValue operator/(const TaggedValue &other) const
static TaggedValue from_tag_truncating(ValueTag tag, FF value)
TaggedValue operator-(const TaggedValue &other) const
bool operator<(const TaggedValue &other) const
TaggedValue operator<<(const TaggedValue &other) const
bool operator==(const TaggedValue &other) const
TaggedValue operator|(const TaggedValue &other) const
static TaggedValue from_tag(ValueTag tag, FF value)
TaggedValue operator^(const TaggedValue &other) const
TaggedValue operator*(const TaggedValue &other) const
TaggedValue operator&(const TaggedValue &other) const
std::string to_string() const
bool operator!=(const TaggedValue &other) const
A 1-bit unsigned integer type.
static constexpr uint256_t from_uint128(const uint128_t a) noexcept
constexpr uint64_t get_msb() const
testing::StrictMock< MockGreaterThan > greater_than
uint8_t get_tag_bits(ValueTag tag)
uint256_t get_tag_max_value(ValueTag tag)
std::string field_to_string(const FF &ff)
uint8_t get_tag_bytes(ValueTag tag)
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
std::string to_string(bb::avm2::ValueTag tag)
unsigned __int128 uint128_t
static constexpr uint256_t modulus