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)
62 : node_refs(refs), json(json) {}
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 {
84 return json && json->is<T>();
87 [[nodiscard]]
const T &as()
const {
93 if (!json || !json->is<
JsonObject>())
return nullptr;
97 if (node_refs.find(
id) == node_refs.end()) {
99 load(
"Node_Type", type);
100 if (
auto fn = get(IR::unpacker_table, type)) {
101 node_refs[id] = fn(*
this);
105 node_refs[id]->sourceInfoFromJSON(*
this);
110 return node_refs[id];
115 template <
typename T>
119 for (
auto &e : as<JsonVector>()) {
125 template <
typename T>
126 void unpack_json(std::set<T> &v) {
129 for (
auto &e : as<JsonVector>()) {
135 template <
typename T>
139 for (
auto &e : as<JsonVector>()) {
145 template <
typename T>
147 v = *IR::Vector<T>::fromJSON(*
this);
149 template <
typename T>
151 v = IR::Vector<T>::fromJSON(*
this);
153 template <
typename T>
155 v = *IR::IndexedVector<T>::fromJSON(*
this);
157 template <
typename T>
159 v = IR::IndexedVector<T>::fromJSON(*
this);
161 template <
class T,
template <
class K,
class V,
class COMP,
class ALLOC>
class MAP,
class COMP,
164 m = *IR::NameMap<T, MAP, COMP, ALLOC>::fromJSON(*
this);
166 template <
class T,
template <
class K,
class V,
class COMP,
class ALLOC>
class MAP,
class COMP,
169 m = IR::NameMap<T, MAP, COMP, ALLOC>::fromJSON(*
this);
172 template <
typename K,
typename V>
173 void unpack_json(std::map<K, V> &v) {
174 std::pair<K, V> temp;
176 if (is<JsonVector>()) {
177 for (
auto &e : as<JsonVector>()) {
182 for (
auto &e : as<JsonObject>()) {
184 load(e.second, temp.second);
189 template <
typename K,
typename V>
191 std::pair<K, V> temp;
193 if (is<JsonVector>()) {
194 for (
auto &e : as<JsonVector>()) {
199 for (
auto &e : as<JsonObject>()) {
201 load(e.second, temp.second);
206 template <
typename V>
208 std::pair<cstring, V> temp;
210 for (
auto &e : as<JsonObject>()) {
211 temp.first = e.first;
212 load(e.second, temp.second);
217 template <
typename K,
typename V>
218 void unpack_json(std::multimap<K, V> &v) {
219 std::pair<K, V> temp;
221 if (is<JsonVector>()) {
222 for (
auto &e : as<JsonVector>()) {
227 for (
auto &e : as<JsonObject>()) {
229 load(e.second, temp.second);
235 template <
typename T>
236 void unpack_json(std::vector<T> &v) {
239 for (
auto &e : as<JsonVector>()) {
245 template <
typename T,
typename U>
246 void unpack_json(std::pair<T, U> &v) {
247 load(
"first", v.first);
248 load(
"second", v.second);
251 template <
typename T>
252 void unpack_json(std::optional<T> &v) {
253 bool isValid =
false;
254 load(
"valid", isValid);
260 load(
"value", value);
261 v = std::move(value);
264 template <
int N,
class Variant>
265 std::enable_if_t<N == std::variant_size_v<Variant>> unpack_variant(
int ,
267 BUG(
"Error traversing variant during load");
270 template <
int N,
class Variant>
271 std::enable_if_t<(N < std::variant_size_v<Variant>)> unpack_variant(
int target,
274 variant.template emplace<N>();
275 load(
"value", std::get<N>(variant));
277 unpack_variant<N + 1>(target, variant);
280 template <
class... Types>
281 void unpack_json(std::variant<Types...> &v) {
283 load(
"variant_index", index);
284 unpack_variant<0>(index, v);
287 void unpack_json(
bool &v) { v = as<JsonBoolean>(); }
289 template <
typename T>
290 std::enable_if_t<std::is_integral_v<T>> unpack_json(T &v) {
291 v = as<JsonNumber>();
293 void unpack_json(big_int &v) { v = as<JsonNumber>().val; }
294 void unpack_json(std::string &v) {
295 if (is<JsonString>()) v = as<JsonString>();
298 if (is<JsonString>())
300 else if (is<JsonNull>())
303 void unpack_json(
IR::ID &v) {
304 if (!json->is<
JsonNull>()) v.name = as<JsonString>();
308 if (
auto *s = json->to<
JsonString>()) s->c_str() >> m;
311 void unpack_json(
bitvec &v) {
312 if (
auto *s = json->to<
JsonString>()) s->c_str() >> v;
315 template <
typename T>
316 std::enable_if_t<std::is_enum_v<T>> unpack_json(T &v) {
317 if (
auto *s = json->to<
JsonString>()) *s >> v;
321 if (
auto *s = json->to<
JsonString>()) s->c_str() >> v;
328 bool hasWidth =
false;
333 load(
"hasWidth", hasWidth);
338 template <
typename T>
339 std::enable_if_t<has_fromJSON<T>::value && !std::is_base_of_v<IR::Node, T> &&
340 std::is_pointer_v<decltype(T::fromJSON(std::declval<JSONLoader &>()))>>
342 v = T::fromJSON(*
this);
345 template <
typename T>
346 std::enable_if_t<has_fromJSON<T>::value && !std::is_base_of_v<IR::Node, T> &&
347 std::is_pointer_v<decltype(T::fromJSON(std::declval<JSONLoader &>()))>>
349 v = *(T::fromJSON(*
this));
352 template <
typename T>
353 std::enable_if_t<has_fromJSON<T>::value && !std::is_base_of<IR::Node, T>::value &&
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<std::is_base_of_v<IR::INode, T>> unpack_json(T &v) {
361 v = get_node()->as<T>();
363 template <
typename T>
364 std::enable_if_t<std::is_base_of_v<IR::INode, T>> unpack_json(
const T *&v) {
365 v = get_node()->checkedTo<T>();
368 template <
typename T,
size_t N>
369 void unpack_json(T (&v)[N]) {
371 for (
size_t i = 0; i < N && i < j->size(); ++i) {
372 load(j->at(i), v[i]);
378 template <
typename T>
379 void load(
const JsonData &json, T &v) {
380 JSONLoader(&json, node_refs).unpack_json(v);
383 template <
typename T>
384 void load(
const std::unique_ptr<JsonData> &json, T &v) {
385 JSONLoader(json.get(), node_refs).unpack_json(v);
388 template <
typename T>
389 bool load(std::string_view field, T *&v) {
390 if (
auto loader = JSONLoader(*
this, field)) {
391 loader.unpack_json(v);
399 template <
typename T>
400 bool load(std::string_view field, T &v) {
401 if (
auto loader = JSONLoader(*
this, field)) {
402 loader.unpack_json(v);
409 template <
typename T>
410 JSONLoader &operator>>(T &v) {