40 std::unordered_set<int> node_refs;
52 static small test(
decltype(&C::toJSON));
57 static const bool value =
sizeof(test<T>(0)) ==
sizeof(
char);
71 enum state_restore_kind { NONE, OBJECT, VECTOR };
72 class state_restore_t {
73 output_state_t prev_state;
75 state_restore_kind kind;
76 friend class JSONGenerator;
78 state_restore_t(JSONGenerator &gen, state_restore_kind kind)
79 : prev_state(gen.output_state), gen(gen), kind(kind) {}
80 state_restore_t(
const state_restore_t &) =
delete;
81 state_restore_t(state_restore_t &&a) : prev_state(a.prev_state), gen(a.gen), kind(a.kind) {
87 if (kind == OBJECT) gen.end_object(*
this);
88 if (kind == VECTOR) gen.end_vector(*
this);
93 explicit JSONGenerator(std::ostream &out,
bool dumpSourceInfo =
false)
94 : out(out), dumpSourceInfo(dumpSourceInfo) {}
96 state_restore_t begin_vector() {
97 if (output_state == OBJ_START) output_state = OBJ_END;
98 BUG_CHECK(output_state != VEC_START,
"invalid json output state in begin_vector");
99 state_restore_t rv(*
this, VECTOR);
100 output_state = VEC_START;
106 void end_vector(state_restore_t &prev) {
107 BUG_CHECK(prev.kind == VECTOR,
"invalid previous state in end_vector");
110 if (output_state == VEC_MID)
111 out << std::endl << indent;
112 else if (output_state != VEC_START)
113 BUG(
"invalid json output state in end_vector");
115 if ((output_state = prev.prev_state) == OBJ_AFTERTAG) output_state = OBJ_MID;
118 state_restore_t begin_object() {
119 BUG_CHECK(output_state != OBJ_START && output_state != OBJ_MID && output_state != OBJ_END,
120 "invalid json output state in begin_object");
121 state_restore_t rv(*
this, OBJECT);
122 output_state = OBJ_START;
126 void end_object(state_restore_t &prev) {
127 BUG_CHECK(prev.kind == OBJECT,
"invalid previous state in end_object");
129 switch (output_state) {
134 out << std::endl << --indent <<
'}';
142 BUG(
"invalid json output state in end_object");
145 if ((output_state = prev.prev_state) == OBJ_AFTERTAG) output_state = OBJ_MID;
148 template <
typename T>
149 void emit(
const T &val) {
150 switch (output_state) {
155 out << std::endl << indent;
156 output_state = VEC_MID;
159 output_state = OBJ_MID;
164 output_state = OBJ_END;
168 BUG(
"invalid json output state for emit(obj)");
171 if (output_state == TOP) out << std::endl;
174 void emit_tag(std::string_view tag) {
175 switch (output_state) {
177 out <<
'{' << std::endl << ++indent;
180 out <<
',' << std::endl << indent;
187 BUG(
"invalid json output state for emit_tag");
190 output_state = OBJ_AFTERTAG;
193 template <
typename T>
194 void emit(std::string_view tag,
const T &val) {
197 output_state = OBJ_MID;
201 template <
typename T>
203 auto t = begin_vector();
204 for (
auto &el : v) emit(el);
208 template <
typename T>
209 void generate(
const std::vector<T> &v) {
210 auto t = begin_vector();
211 for (
auto &el : v) emit(el);
215 template <
typename T,
typename U>
216 void generate(
const std::pair<T, U> &v) {
217 auto t = begin_object();
223 template <
typename T,
typename U>
224 void toJSON(
const std::pair<T, U> &v) {
225 emit(
"first", v.first);
226 emit(
"second", v.second);
230 template <
typename T>
231 void generate(
const std::optional<T> &v) {
232 auto t = begin_object();
234 if (v) emit(
"value", *v);
238 template <
typename T>
239 void generate(
const std::set<T> &v) {
240 auto t = begin_vector();
241 for (
auto &el : v) emit(el);
245 template <
typename T>
247 auto t = begin_vector();
248 for (
auto &el : v) emit(el);
252 template <
typename K,
typename V>
253 void generate(
const std::map<K, V> &v) {
254 auto t = begin_vector();
255 for (
auto &el : v) emit(el);
259 template <
typename K,
typename V>
261 auto t = begin_vector();
262 for (
auto &el : v) emit(el);
266 template <
typename V>
268 auto t = begin_object();
269 for (
auto &el : v) emit(el.first, el.second);
273 template <
class... Types>
274 void generate(
const std::variant<Types...> &v) {
275 auto t = begin_object();
276 emit(
"variant_index", v.index());
277 std::visit([
this](
auto &value) { this->emit(
"value", value); }, v);
281 void generate(
bool v) { out << (v ?
"true" :
"false"); }
282 template <
typename T>
283 std::enable_if_t<std::is_integral_v<T>> generate(T v) {
284 out << std::to_string(v);
286 void generate(
double v) { out << std::to_string(v); }
287 template <
typename T>
288 std::enable_if_t<std::is_same_v<T, big_int>> generate(
const T &v) {
299 template <
typename T>
300 std::enable_if_t<std::is_same_v<T, LTBitMatrix> || std::is_enum_v<T>> generate(T v) {
301 out <<
"\"" << v <<
"\"";
304 void generate(
const bitvec &v) { out <<
"\"" << v <<
"\""; }
306 void generate(
const match_t &v) {
307 auto t = begin_object();
308 emit(
"word0", v.word0);
309 emit(
"word1", v.word1);
313 template <
typename T>
314 std::enable_if_t<has_toJSON<T>::value && !std::is_base_of_v<IR::INode, T>> generate(
316 auto t = begin_object();
322 auto &v = *v_.getNode();
323 auto t = begin_object();
324 if (node_refs.find(v.id) != node_refs.end()) {
325 emit(
"Node_ID", v.id);
327 node_refs.insert(v.id);
329 if (dumpSourceInfo) {
330 v.sourceInfoToJSON(*
this);
338 template <
typename T>
339 void generate(
const T *
const &v) {
346 template <
typename T,
size_t N>
347 void generate(
const T (&v)[N]) {
348 auto t = begin_vector();
349 for (
auto &el : v) emit(el);