48 static small test(
decltype(&C::fromJSON));
53 static const bool value =
sizeof(test<T>(0)) ==
sizeof(
char);
57 std::unordered_map<int, IR::Node *> &node_refs;
61 : node_refs(*(
new std::unordered_map<int, IR::Node *>())) {
66 : node_refs(*(
new std::unordered_map<int, IR::Node *>())), json(json) {}
69 : node_refs(refs), json(json) {}
72 : node_refs(unpacker.node_refs), json(
nullptr) {
73 if (
auto *obj = unpacker.json->
to<
JsonObject>()) json = get(obj, field);
81 if (node_refs.find(
id) == node_refs.end()) {
82 if (
auto fn = get(IR::unpacker_table, json->
as<
JsonObject>().get_type())) {
83 node_refs[id] = fn(*
this);
88 if (obj->hasSrcInfo() ==
true) {
89 node_refs[id]->srcInfo =
91 obj->get_column(), obj->get_sourceFragment());
102 template <
typename T>
111 template <
typename T>
112 void unpack_json(std::set<T> &v) {
120 template <
typename T>
129 template <
typename T>
133 template <
typename T>
137 template <
typename T>
141 template <
typename T>
145 template <
class T,
template <
class K,
class V,
class COMP,
class ALLOC>
class MAP,
class COMP,
150 template <
class T,
template <
class K,
class V,
class COMP,
class ALLOC>
class MAP,
class COMP,
156 template <
typename K,
typename V>
157 void unpack_json(std::map<K, V> &v) {
158 std::pair<K, V> temp;
162 load(e.second, temp.second);
166 template <
typename K,
typename V>
168 std::pair<K, V> temp;
172 load(e.second, temp.second);
176 template <
typename V>
178 std::pair<cstring, V> temp;
182 load(e.second, temp.second);
187 template <
typename K,
typename V>
188 void unpack_json(std::multimap<K, V> &v) {
189 std::pair<K, V> temp;
193 load(e.second, temp.second);
198 template <
typename T>
199 void unpack_json(std::vector<T> &v) {
207 template <
typename T,
typename U>
208 void unpack_json(std::pair<T, U> &v) {
210 load(::P4::get(obj,
"first"), v.first);
211 load(::P4::get(obj,
"second"), v.second);
214 template <
typename T>
215 void unpack_json(std::optional<T> &v) {
217 bool isValid =
false;
218 load(::P4::get(obj,
"valid"), isValid);
224 load(::P4::get(obj,
"value"), value), v = std::move(value);
227 template <
int N,
class Variant>
228 std::enable_if_t<N == std::variant_size_v<Variant>> unpack_variant(
const JsonObject *,
231 BUG(
"Error traversing variant during load");
234 template <
int N,
class Variant>
235 std::enable_if_t<(N < std::variant_size_v<Variant>)> unpack_variant(
const JsonObject *obj,
239 variant.template emplace<N>();
240 load(P4::get(obj,
"value"), std::get<N>(variant));
242 unpack_variant<N + 1>(obj, target, variant);
245 template <
class... Types>
246 void unpack_json(std::variant<Types...> &v) {
249 load(P4::get(obj,
"variant_index"), index);
250 unpack_variant<0>(obj, index, v);
255 template <
typename T>
256 std::enable_if_t<std::is_integral_v<T>> unpack_json(T &v) {
259 void unpack_json(big_int &v) { v = json->
as<
JsonNumber>().val; }
262 std::string::size_type p = 0;
263 while ((p = tmp.find(
'\\', p)) != std::string::npos) {
280 void unpack_json(
IR::ID &v) {
288 void unpack_json(
bitvec &v) {
292 template <
typename T>
293 std::enable_if_t<std::is_enum_v<T>> unpack_json(T &v) {
305 bool hasWidth =
false;
310 load(
"hasWidth", hasWidth);
315 template <
typename T>
316 std::enable_if_t<has_fromJSON<T>::value && !std::is_base_of_v<IR::Node, T> &&
317 std::is_pointer_v<decltype(T::fromJSON(std::declval<JSONLoader &>()))>>
319 v = T::fromJSON(*
this);
322 template <
typename T>
323 std::enable_if_t<has_fromJSON<T>::value && !std::is_base_of_v<IR::Node, T> &&
324 std::is_pointer_v<decltype(T::fromJSON(std::declval<JSONLoader &>()))>>
326 v = *(T::fromJSON(*
this));
329 template <
typename T>
330 std::enable_if_t<has_fromJSON<T>::value && !std::is_base_of<IR::Node, T>::value &&
331 !std::is_pointer_v<decltype(T::fromJSON(std::declval<JSONLoader &>()))>>
333 v = T::fromJSON(*
this);
336 template <
typename T>
337 std::enable_if_t<std::is_base_of_v<IR::INode, T>> unpack_json(T &v) {
338 v = get_node()->
as<T>();
340 template <
typename T>
341 std::enable_if_t<std::is_base_of_v<IR::INode, T>> unpack_json(
const T *&v) {
342 v = get_node()->checkedTo<T>();
345 template <
typename T,
size_t N>
346 void unpack_json(T (&v)[N]) {
348 for (
size_t i = 0; i < N && i < j->size(); ++i) {
356 template <
typename T>
361 template <
typename T>
362 void load(
const std::string field, T *&v) {
364 if (loader.json ==
nullptr) {
367 loader.unpack_json(v);
371 template <
typename T>
372 void load(
const std::string field, T &v) {
374 if (loader.json ==
nullptr)
return;
375 loader.unpack_json(v);
378 template <
typename T>