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 bool (*errfn)(
const JSONLoader &, std::string_view msg) =
nullptr;
63 JSONLoader(
const JsonData *
json, std::unordered_map<int, IR::Node *> &refs,
65 : node_refs(refs),
json(
json), locinfo(locinfo) {}
69 : node_refs(*(
new std::unordered_map<int, IR::Node *>())), locinfo(li) {
71 json = json_root.get();
74 JSONLoader(
const JSONLoader &unpacker, std::string_view field)
75 : node_refs(unpacker.node_refs),
json(
nullptr), locinfo(unpacker.locinfo) {
76 if (!unpacker)
return;
78 if (
auto it = obj->find(field); it != obj->end()) {
79 json = it->second.get();
84 explicit operator bool()
const {
return json !=
nullptr; }
86 [[nodiscard]]
bool is()
const {
90 [[nodiscard]]
const T &as()
const {
94 std::string locdesc(
const JsonData &d)
const {
95 if (!locinfo)
return "";
96 return locinfo->desc(d);
98 std::string locdesc()
const {
100 return locdesc(*
json);
102 bool error(std::string_view msg)
const {
108 const IR::Node *get_node(NodeFactoryFn factory =
nullptr) {
111 auto success = load(
"Node_ID",
id) || error(
"missing field Node_ID");
112 if (!success)
return nullptr;
114 if (node_refs.find(
id) == node_refs.end()) {
117 auto success = load(
"Node_Type", type) || error(
"missing field Node_Type");
118 if (!success)
return nullptr;
119 factory = get(IR::unpacker_table, type);
122 node_refs[id] = factory(*
this);
126 node_refs[id]->sourceInfoFromJSON(*
this);
131 return node_refs[id];
136 template <
typename T>
140 for (
auto &e : as<JsonVector>()) {
146 template <
typename T>
147 void unpack_json(std::set<T> &v) {
150 for (
auto &e : as<JsonVector>()) {
156 template <
typename T>
160 for (
auto &e : as<JsonVector>()) {
166 template <
typename T>
168 v = get_node(NodeFactoryFn(&IR::Vector<T>::fromJSON))->
as<
IR::Vector<T>>();
170 template <
typename T>
172 v = get_node(NodeFactoryFn(&IR::Vector<T>::fromJSON))->checkedTo<
IR::Vector<T>>();
174 template <
typename T>
178 template <
typename T>
180 v = get_node(NodeFactoryFn(&IR::IndexedVector<T>::fromJSON))
183 template <
class T,
template <
class K,
class V,
class COMP,
class ALLOC>
class MAP,
class COMP,
186 m = get_node(NodeFactoryFn(&IR::NameMap<T, MAP, COMP, ALLOC>::fromJSON))
189 template <
class T,
template <
class K,
class V,
class COMP,
class ALLOC>
class MAP,
class COMP,
192 m = get_node(NodeFactoryFn(&IR::NameMap<T, MAP, COMP, ALLOC>::fromJSON))
196 template <
typename K,
typename V>
197 void unpack_json(std::map<K, V> &v) {
198 std::pair<K, V> temp;
200 if (is<JsonVector>()) {
201 for (
auto &e : as<JsonVector>()) {
206 for (
auto &e : as<JsonObject>()) {
208 load(e.second, temp.second);
213 template <
typename K,
typename V>
215 std::pair<K, V> temp;
217 if (is<JsonVector>()) {
218 for (
auto &e : as<JsonVector>()) {
223 for (
auto &e : as<JsonObject>()) {
225 load(e.second, temp.second);
230 template <
typename V>
232 std::pair<cstring, V> temp;
234 for (
auto &e : as<JsonObject>()) {
235 temp.first = e.first;
236 load(e.second, temp.second);
241 template <
typename K,
typename V>
242 void unpack_json(std::multimap<K, V> &v) {
243 std::pair<K, V> temp;
245 if (is<JsonVector>()) {
246 for (
auto &e : as<JsonVector>()) {
251 for (
auto &e : as<JsonObject>()) {
253 load(e.second, temp.second);
259 template <
typename T>
260 void unpack_json(std::vector<T> &v) {
263 for (
auto &e : as<JsonVector>()) {
269 template <
typename T,
typename U>
270 void unpack_json(std::pair<T, U> &v) {
271 load(
"first", v.first) || error(
"missing field first");
272 load(
"second", v.second) || error(
"missing field second");
275 template <
typename T>
276 void unpack_json(std::optional<T> &v) {
277 bool isValid =
false;
278 load(
"valid", isValid) || error(
"missing field valid");
284 auto success = load(
"value", value) || error(
"missing field value");
289 v = std::move(value);
292 template <
int N,
class Variant>
293 std::enable_if_t<N == std::variant_size_v<Variant>> unpack_variant(
int ,
295 BUG(
"Error traversing variant during load");
298 template <
int N,
class Variant>
299 std::enable_if_t<(N < std::variant_size_v<Variant>)> unpack_variant(
int target,
302 variant.template emplace<N>();
303 load(
"value", std::get<N>(variant)) || error(
"missing field value");
305 unpack_variant<N + 1>(target, variant);
308 template <
class... Types>
309 void unpack_json(std::variant<Types...> &v) {
311 load(
"variant_index", index) || error(
"missing field variant_index");
312 unpack_variant<0>(index, v);
315 void unpack_json(
bool &v) { v = as<JsonBoolean>(); }
317 template <
typename T>
318 std::enable_if_t<std::is_integral_v<T>> unpack_json(T &v) {
319 v = as<JsonNumber>();
321 void unpack_json(big_int &v) { v = as<JsonNumber>().val; }
322 void unpack_json(std::string &v) {
323 if (is<JsonString>()) v = as<JsonString>();
326 if (is<JsonString>())
328 else if (is<JsonNull>())
331 void unpack_json(
IR::ID &v) {
339 void unpack_json(
bitvec &v) {
343 template <
typename T>
344 std::enable_if_t<std::is_enum_v<T>> unpack_json(T &v) {
352 template <
typename T>
353 std::enable_if_t<has_fromJSON<T>::value && !std::is_base_of_v<IR::INode, T> &&
354 std::is_pointer_v<decltype(T::fromJSON(std::declval<JSONLoader &>()))>>
356 v = T::fromJSON(*
this);
359 template <
typename T>
360 std::enable_if_t<has_fromJSON<T>::value && !std::is_base_of_v<IR::INode, T> &&
361 std::is_pointer_v<decltype(T::fromJSON(std::declval<JSONLoader &>()))>>
363 v = *(T::fromJSON(*
this));
366 template <
typename T>
367 std::enable_if_t<has_fromJSON<T>::value && !std::is_base_of<IR::INode, T>::value &&
368 !std::is_pointer_v<decltype(T::fromJSON(std::declval<JSONLoader &>()))>>
370 v = T::fromJSON(*
this);
373 template <
typename T>
374 std::enable_if_t<has_fromJSON<T>::value && !std::is_base_of<IR::INode, T>::value &&
375 !std::is_pointer_v<decltype(T::fromJSON(std::declval<JSONLoader &>()))>>
377 v =
new T(T::fromJSON(*
this));
380 template <
typename T>
381 std::enable_if_t<std::is_base_of_v<IR::INode, T>> unpack_json(T &v) {
382 v = get_node()->as<T>();
384 template <
typename T>
385 std::enable_if_t<std::is_base_of_v<IR::INode, T>> unpack_json(
const T *&v) {
386 v = get_node()->checkedTo<T>();
389 template <
typename T,
size_t N>
390 void unpack_json(T (&v)[N]) {
392 for (
size_t i = 0; i < N && i < j->size(); ++i) {
393 load(j->at(i), v[i]);
399 template <
typename T>
401 JSONLoader(&
json, node_refs, locinfo).unpack_json(v);
404 template <
typename T>
405 void load(
const std::unique_ptr<JsonData> &
json, T &v) {
406 JSONLoader(
json.get(), node_refs, locinfo).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);
420 template <
typename T>
421 bool load(std::string_view field, T &v) {
422 if (
auto loader = JSONLoader(*
this, field)) {
423 loader.unpack_json(v);
429 template <
typename T>
430 JSONLoader &operator>>(T &v) {