#include #include #include #include using namespace std; // Builds NLOHMANN_JSON_EXPAND, NLOHMANN_JSON_GET_MACRO, and the // NLOHMANN_JSON_PASTE / NLOHMANN_JSON_PASTE2..PASTE dispatch table // and recursive definitions. string build_paste_code(int max_args) { stringstream ss; ss << "#define NLOHMANN_JSON_EXPAND( x ) x" << endl; ss << "#define NLOHMANN_JSON_GET_MACRO("; for (int i = 0 ; i < max_args ; i++) ss << "_" << i + 1 << ", "; ss << "NAME,...) NAME" << endl; ss << "#define NLOHMANN_JSON_PASTE(...) NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_GET_MACRO(__VA_ARGS__, \\" << endl; for (int i = max_args ; i > 1 ; i--) ss << "NLOHMANN_JSON_PASTE" << i << ", \\" << endl; ss << "NLOHMANN_JSON_PASTE1)(__VA_ARGS__))" << endl; ss << "#define NLOHMANN_JSON_PASTE2(func, v1) func(v1)" << endl; for (int i = 3 ; i <= max_args ; i++) { ss << "#define NLOHMANN_JSON_PASTE" << i << "(func, "; for (int j = 1 ; j < i -1 ; j++) ss << "v" << j << ", "; ss << "v" << i-1 << ") NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE" << i-1 << "(func, "; for (int j = 2 ; j < i-1 ; j++) ss << "v" << j << ", "; ss << "v" << i-1 << ")" << endl; } return ss.str(); } // Builds the NLOHMANN_JSON_DOUBLE_PASTE dispatch table and recursive // definitions used by the *_WITH_NAMES macros. Its GET_MACRO dispatch reuses // the same max_args slots as NLOHMANN_JSON_PASTE, but DOUBLE_PASTE consumes // its arguments two at a time (name, member), so an even slot count falls // back to the next lower odd NLOHMANN_JSON_DOUBLE_PASTE. string build_double_paste_code(int max_args) { stringstream ss; ss << "#define NLOHMANN_JSON_DOUBLE_PASTE(...) NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_GET_MACRO(__VA_ARGS__, \\" << endl; for (int i = max_args ; i > 1 ; i--) { int k = (i % 2 == 1) ? i : i - 1; ss << "NLOHMANN_JSON_DOUBLE_PASTE" << k << ", \\" << endl; } ss << "NLOHMANN_JSON_DOUBLE_PASTE1)(__VA_ARGS__))" << endl; ss << "#define NLOHMANN_JSON_DOUBLE_PASTE3(func, v1, v2) func(v1, v2)" << endl; for (int k = 5 ; k <= max_args - 1 ; k += 2) { ss << "#define NLOHMANN_JSON_DOUBLE_PASTE" << k << "(func, "; for (int j = 1 ; j < k - 1 ; j++) ss << "v" << j << ", "; ss << "v" << k - 1 << ") NLOHMANN_JSON_DOUBLE_PASTE3(func, v1, v2) NLOHMANN_JSON_DOUBLE_PASTE" << k - 2 << "(func, "; for (int j = 3 ; j < k - 1 ; j++) ss << "v" << j << ", "; ss << "v" << k - 1 << ")" << endl; } return ss.str(); } // Builds the NLOHMANN_JSON_TYPE_BODY dispatch table: max_args - 1 slots // selecting the *_MEMBERS implementation and a final slot selecting // *_EMPTY, so NLOHMANN_DEFINE_TYPE_*(Type) with no further arguments still // resolves (issue #4041). string build_type_body_table(int max_args) { stringstream ss; ss << "#define NLOHMANN_JSON_TYPE_BODY(Prefix, ...) NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_GET_MACRO(__VA_ARGS__, \\" << endl; const int per_line = 8; for (int i = 1 ; i <= max_args ; i++) { ss << (i == max_args ? "Prefix ## EMPTY" : "Prefix ## MEMBERS") << ", "; if (i % per_line == 0) ss << "\\" << endl; } ss << "NLOHMANN_JSON_TYPE_BODY_SENTINEL))" << endl; return ss.str(); } int main(int argc, char** argv) { int max_args = 64; // With "type_body", print only the NLOHMANN_JSON_TYPE_BODY dispatch // table (a separate insertion point in macro_scope.hpp); otherwise // print the EXPAND/GET_MACRO/PASTE/DOUBLE_PASTE block that precedes it. if (argc > 1 && string(argv[1]) == "type_body") { cout << build_type_body_table(max_args); } else { cout << build_paste_code(max_args) << build_double_paste_code(max_args); } return 0; }