Barretenberg
The ZK-SNARK library at the core of Aztec
Loading...
Searching...
No Matches
tagged_value.hpp
Go to the documentation of this file.
1#pragma once
2
3#include <cstdint>
4#include <functional>
5#include <string>
6#include <variant>
7
12
13namespace bb::avm2 {
14
15class TagMismatchException : public std::runtime_error {
16 public:
17 TagMismatchException(const std::string& msg)
18 : std::runtime_error("Mismatched tags: " + msg)
19 {}
20};
21
22class InvalidOperationTag : public std::runtime_error {
23 public:
24 InvalidOperationTag(const std::string& msg)
25 : std::runtime_error("InvalidOperationTag: " + msg)
26 {}
27};
28
29class DivisionByZero : public std::runtime_error {
30 public:
31 DivisionByZero(const std::string& msg)
32 : std::runtime_error("Division by zero: " + msg)
33 {}
34};
35
36enum class ValueTag {
37 FF = MEM_TAG_FF,
38 U1 = MEM_TAG_U1,
39 U8 = MEM_TAG_U8,
44 MAX = U128,
45};
46
47template <typename T> ValueTag tag_for_type()
48{
49 if constexpr (std::is_same_v<T, FF>) {
50 return ValueTag::FF;
51 } else if constexpr (std::is_same_v<T, uint1_t>) {
52 return ValueTag::U1;
53 } else if constexpr (std::is_same_v<T, uint8_t>) {
54 return ValueTag::U8;
55 } else if constexpr (std::is_same_v<T, uint16_t>) {
56 return ValueTag::U16;
57 } else if constexpr (std::is_same_v<T, uint32_t>) {
58 return ValueTag::U32;
59 } else if constexpr (std::is_same_v<T, uint64_t>) {
60 return ValueTag::U64;
61 } else if constexpr (std::is_same_v<T, uint128_t>) {
62 return ValueTag::U128;
63 }
64}
65
66uint8_t get_tag_bits(ValueTag tag);
67uint8_t get_tag_bytes(ValueTag tag);
69
71 public:
72 // We are using variant to avoid heap allocations at the cost of a bigger memory footprint.
73 // Do not use this type outside of this class, except for the visitors.
74 // NOTE: Order matters, "a default-constructed variant holds a value of its first alternative".
75 // See https://en.cppreference.com/w/cpp/utility/variant.
77
78 // Default constructor. Useful for events. Note that this will be an U8.
79 TaggedValue() = default;
80
81 // Using this constructor you can specify the type explicitly via the template.
82 template <typename T> static TaggedValue from(T value) { return TaggedValue(value); }
83 // Constructs from a tag and value. Throws if the value is out of bounds for the tag.
85 // Constructs from a tag and value. Truncates the value if it is out of bounds for the tag.
86 // The truncation is equivalent to bit masking. It does not saturate to the max value of the tag.
88
89 // Arithmetic operators.
90 TaggedValue operator+(const TaggedValue& other) const;
91 TaggedValue operator-(const TaggedValue& other) const;
92 TaggedValue operator*(const TaggedValue& other) const;
93 TaggedValue operator/(const TaggedValue& other) const;
94 // Bitwise operations not valid for FF. They will throw.
95 TaggedValue operator&(const TaggedValue& other) const;
96 TaggedValue operator|(const TaggedValue& other) const;
97 TaggedValue operator^(const TaggedValue& other) const;
98 TaggedValue operator~() const;
99 // Shift operations not valid for FF. They will throw.
100 TaggedValue operator<<(const TaggedValue& other) const;
101 TaggedValue operator>>(const TaggedValue& other) const;
102 // Comparison operators. If the tags are not the same, false is returned
103 bool operator<(const TaggedValue& other) const;
104 bool operator<=(const TaggedValue& other) const;
105 bool operator==(const TaggedValue& other) const;
106 bool operator!=(const TaggedValue& other) const;
107
108 // Converts any type to FF.
109 FF as_ff() const;
110 operator FF() const { return as_ff(); }
111 ValueTag get_tag() const;
112 std::string to_string() const;
113
114 // Use sparingly. The held type must match.
115 template <typename T> T as() const
116 {
118 return std::get<T>(value);
119 }
120 throw std::runtime_error("TaggedValue::as(): type mismatch. Wanted type " +
121 std::to_string(static_cast<uint32_t>(tag_for_type<T>())) + " but got " + to_string());
122 }
123
124 std::size_t hash() const noexcept { return std::hash<FF>{}(as_ff()); }
125
126 private:
129};
130
131} // namespace bb::avm2
132
133namespace std {
134
135std::string to_string(bb::avm2::ValueTag tag);
136std::string to_string(const bb::avm2::TaggedValue& val);
137
138} // namespace std
#define MEM_TAG_U1
#define MEM_TAG_U32
#define MEM_TAG_U16
#define MEM_TAG_U8
#define MEM_TAG_U128
#define MEM_TAG_FF
#define MEM_TAG_U64
DivisionByZero(const std::string &msg)
InvalidOperationTag(const std::string &msg)
TagMismatchException(const std::string &msg)
TaggedValue operator>>(const TaggedValue &other) const
TaggedValue operator+(const TaggedValue &other) const
bool operator<=(const TaggedValue &other) const
static TaggedValue from(T value)
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
std::size_t hash() const noexcept
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
ValueTag get_tag() const
std::string to_string() const
bool operator!=(const TaggedValue &other) const
uint8_t get_tag_bits(ValueTag tag)
ValueTag tag_for_type()
uint256_t get_tag_max_value(ValueTag tag)
AvmFlavorSettings::FF FF
Definition field.hpp:10
uint8_t get_tag_bytes(ValueTag tag)
STL namespace.
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
Definition tuple.hpp:13
std::string to_string(bb::avm2::ValueTag tag)