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
79struct less_than_equal {
80 template <
typename T,
typename U>
bool operator()(
const T&
a,
const U&
b)
const
91struct checked_divides {
92 template <
typename T>
auto operator()(T&&
a, T&&
b)
const
94 if (
b ==
static_cast<T
>(0)) {
95 throw DivisionByZero(
"Dividing numeric value by zero");
101template <
typename Op>
102constexpr bool is_bitwise_operation_v =
107template <
typename Op>
struct BinaryOperationVisitor {
112 throw InvalidOperationTag(
"Bitwise operations not valid for FF");
115 return static_cast<T
>(Op{}(
a,
b));
118 throw TagMismatchException(
"Cannot perform operation between different types: " +
125template <
typename Op>
struct UnaryOperationVisitor {
129 throw InvalidOperationTag(
"Can't do unary bitwise operations on an FF");
132 return static_cast<T
>(Op{}(
a));
138template <
typename Op>
struct ComparisonOperationVisitor {
139 template <
typename T,
typename U>
bool operator()(
const T&
a,
const U&
b)
const
170 assert(
false &&
"Invalid tag");
189 assert(
false &&
"Invalid tag");
207 assert(
false &&
"Invalid tag");
218 auto assert_bounds = [](
const FF&
value, uint8_t bits) {
220 throw std::runtime_error(
"Value out of bounds");
227 assert_bounds(
value, 1);
230 assert_bounds(
value, 8);
233 assert_bounds(
value, 16);
236 assert_bounds(
value, 32);
239 assert_bounds(
value, 64);
242 assert_bounds(
value, 128);
269 throw std::runtime_error(
"Invalid tag");
291 return std::visit(BinaryOperationVisitor<checked_divides>(),
value, other.
value);
318 return std::visit(BinaryOperationVisitor<shift_left>(),
value, other.
value);
323 return std::visit(BinaryOperationVisitor<shift_right>(),
value, other.
value);
330 return std::visit(ComparisonOperationVisitor<less_than>(),
value, other.
value);
336 return std::visit(ComparisonOperationVisitor<less_than_equal>(),
value, other.
value);
353 const auto visitor = overloads{ [](
FF val) ->
FF {
return val; },
354 [](
uint1_t val) ->
FF {
return val.value(); },
356 [](
auto&& val) ->
FF {
return val; } };
358 return std::visit(visitor,
value);
379 throw std::runtime_error(
"Unknown value type");
382 assert(
false &&
"This should never happen.");
388 std::string v = std::visit(
391 [](
const uint1_t& val) -> std::string {
return val.value() == 0 ?
"0" :
"1"; },
424 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
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
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