49 static small test(
decltype(&C::fromJSON));
54 static const bool value =
sizeof(test<T>(0)) ==
sizeof(
char);
57 std::unordered_map<int, IR::Node *> &node_refs;
58 std::unique_ptr<JsonData> json_root;
61 JSONLoader(
const JsonData *
json, std::unordered_map<int, IR::Node *> &refs)
65 explicit JSONLoader(std::istream &in)
66 : node_refs(*(
new std::unordered_map<int, IR::Node *>())) {
68 json = json_root.get();
71 JSONLoader(
const JSONLoader &unpacker, std::string_view field)
72 : node_refs(unpacker.node_refs),
json(
nullptr) {
73 if (!unpacker)
return;
75 if (
auto it = obj->find(field); it != obj->end()) {
76 json = it->second.get();
81 explicit operator bool()
const {
return json !=
nullptr; }
83 [[nodiscard]]
bool is()
const {
87 [[nodiscard]]
const T &as()
const {
95 auto success = load(
"Node_ID",
id);
100 if (node_refs.find(
id) == node_refs.end()) {
102 auto success = load(
"Node_Type", type);
106 if (
auto fn = get(IR::unpacker_table, type)) {
107 node_refs[id] = fn(*
this);
111 node_refs[id]->sourceInfoFromJSON(*
this);
116 return node_refs[id];
121 template <
typename T>
125 for (
auto &e : as<JsonVector>()) {
131 template <
typename T>
132 void unpack_json(std::set<T> &v) {
135 for (
auto &e : as<JsonVector>()) {
141 template <
typename T>
145 for (
auto &e : as<JsonVector>()) {
151 template <
typename T>
153 v = *IR::Vector<T>::fromJSON(*
this);
155 template <
typename T>
157 v = IR::Vector<T>::fromJSON(*
this);
159 template <
typename T>
161 v = *IR::IndexedVector<T>::fromJSON(*
this);
163 template <
typename T>
165 v = IR::IndexedVector<T>::fromJSON(*
this);
167 template <
class T,
template <
class K,
class V,
class COMP,
class ALLOC>
class MAP,
class COMP,
170 m = *IR::NameMap<T, MAP, COMP, ALLOC>::fromJSON(*
this);
172 template <
class T,
template <
class K,
class V,
class COMP,
class ALLOC>
class MAP,
class COMP,
175 m = IR::NameMap<T, MAP, COMP, ALLOC>::fromJSON(*
this);
178 template <
typename K,
typename V>
179 void unpack_json(std::map<K, V> &v) {
180 std::pair<K, V> temp;
182 if (is<JsonVector>()) {
183 for (
auto &e : as<JsonVector>()) {
188 for (
auto &e : as<JsonObject>()) {
190 load(e.second, temp.second);
195 template <
typename K,
typename V>
197 std::pair<K, V> temp;
199 if (is<JsonVector>()) {
200 for (
auto &e : as<JsonVector>()) {
205 for (
auto &e : as<JsonObject>()) {
207 load(e.second, temp.second);
212 template <
typename V>
214 std::pair<cstring, V> temp;
216 for (
auto &e : as<JsonObject>()) {
217 temp.first = e.first;
218 load(e.second, temp.second);
223 template <
typename K,
typename V>
224 void unpack_json(std::multimap<K, V> &v) {
225 std::pair<K, V> temp;
227 if (is<JsonVector>()) {
228 for (
auto &e : as<JsonVector>()) {
233 for (
auto &e : as<JsonObject>()) {
235 load(e.second, temp.second);
241 template <
typename T>
242 void unpack_json(std::vector<T> &v) {
245 for (
auto &e : as<JsonVector>()) {
251 template <
typename T,
typename U>
252 void unpack_json(std::pair<T, U> &v) {
253 load(
"first", v.first);
254 load(
"second", v.second);
257 template <
typename T>
258 void unpack_json(std::optional<T> &v) {
259 bool isValid =
false;
260 load(
"valid", isValid);
266 auto success = load(
"value", value);
271 v = std::move(value);
274 template <
int N,
class Variant>
275 std::enable_if_t<N == std::variant_size_v<Variant>> unpack_variant(
int ,
277 BUG(
"Error traversing variant during load");
280 template <
int N,
class Variant>
281 std::enable_if_t<(N < std::variant_size_v<Variant>)> unpack_variant(
int target,
284 variant.template emplace<N>();
285 load(
"value", std::get<N>(variant));
287 unpack_variant<N + 1>(target, variant);
290 template <
class... Types>
291 void unpack_json(std::variant<Types...> &v) {
293 load(
"variant_index", index);
294 unpack_variant<0>(index, v);
297 void unpack_json(
bool &v) { v = as<JsonBoolean>(); }
299 template <
typename T>
300 std::enable_if_t<std::is_integral_v<T>> unpack_json(T &v) {
301 v = as<JsonNumber>();
303 void unpack_json(big_int &v) { v = as<JsonNumber>().val; }
304 void unpack_json(std::string &v) {
305 if (is<JsonString>()) v = as<JsonString>();
308 if (is<JsonString>())
310 else if (is<JsonNull>())
313 void unpack_json(
IR::ID &v) {
321 void unpack_json(
bitvec &v) {
325 template <
typename T>
326 std::enable_if_t<std::is_enum_v<T>> unpack_json(T &v) {
338 bool hasWidth =
false;
343 load(
"hasWidth", hasWidth);
348 template <
typename T>
349 std::enable_if_t<has_fromJSON<T>::value && !std::is_base_of_v<IR::Node, T> &&
350 std::is_pointer_v<decltype(T::fromJSON(std::declval<JSONLoader &>()))>>
352 v = T::fromJSON(*
this);
355 template <
typename T>
356 std::enable_if_t<has_fromJSON<T>::value && !std::is_base_of_v<IR::Node, T> &&
357 std::is_pointer_v<decltype(T::fromJSON(std::declval<JSONLoader &>()))>>
359 v = *(T::fromJSON(*
this));
362 template <
typename T>
363 std::enable_if_t<has_fromJSON<T>::value && !std::is_base_of<IR::Node, T>::value &&
364 !std::is_pointer_v<decltype(T::fromJSON(std::declval<JSONLoader &>()))>>
366 v = T::fromJSON(*
this);
369 template <
typename T>
370 std::enable_if_t<std::is_base_of_v<IR::INode, T>> unpack_json(T &v) {
371 v = get_node()->as<T>();
373 template <
typename T>
374 std::enable_if_t<std::is_base_of_v<IR::INode, T>> unpack_json(
const T *&v) {
375 v = get_node()->checkedTo<T>();
378 template <
typename T,
size_t N>
379 void unpack_json(T (&v)[N]) {
381 for (
size_t i = 0; i < N && i < j->size(); ++i) {
382 load(j->at(i), v[i]);
388 template <
typename T>
390 JSONLoader(&
json, node_refs).unpack_json(v);
393 template <
typename T>
394 void load(
const std::unique_ptr<JsonData> &
json, T &v) {
395 JSONLoader(
json.get(), node_refs).unpack_json(v);
398 template <
typename T>
399 bool load(std::string_view field, T *&v) {
400 if (
auto loader = JSONLoader(*
this, field)) {
401 loader.unpack_json(v);
409 template <
typename T>
410 bool load(std::string_view field, T &v) {
411 if (
auto loader = JSONLoader(*
this, field)) {
412 loader.unpack_json(v);
418 template <
typename T>
419 JSONLoader &operator>>(T &v) {