Files
…
..
…
…

macro_builder

Generates the argument-counting macros behind the NLOHMANN_DEFINE_TYPE_* and NLOHMANN_DEFINE_DERIVED_TYPE_* macros in include/nlohmann/detail/macro_scope.hpp:

  • NLOHMANN_JSON_EXPAND
  • NLOHMANN_JSON_GET_MACRO, which selects a macro by the number of its arguments (64 slots)
  • NLOHMANN_JSON_PASTE, which calls a function-like macro for each member, and its helpers NLOHMANN_JSON_PASTE2 to NLOHMANN_JSON_PASTE64
  • NLOHMANN_JSON_DOUBLE_PASTE, which the *_WITH_NAMES macros use to call a function-like macro for each (JSON name, member) pair, and its helpers NLOHMANN_JSON_DOUBLE_PASTE3 to NLOHMANN_JSON_DOUBLE_PASTE63
  • the slot table of NLOHMANN_JSON_TYPE_BODY, which dispatches NLOHMANN_DEFINE_TYPE_*(Type) (no further arguments) to the zero-member implementation and every other argument count to the one-or-more-member implementation

The number of slots (max_args in main.cpp) sets the member limit of these macros. NLOHMANN_JSON_PASTE and NLOHMANN_JSON_TYPE_BODY take the function/prefix as their first argument, so 64 slots allow 63 members; NLOHMANN_JSON_DOUBLE_PASTE additionally consumes its members two at a time (name, member), so it only defines the odd helpers up to NLOHMANN_JSON_DOUBLE_PASTE63.

Usage

From the project root:

c++ -std=c++11 tools/macro_builder/main.cpp -o macro_builder
./macro_builder
./macro_builder type_body
  1. Run ./macro_builder (no arguments). In include/nlohmann/detail/macro_scope.hpp, replace the lines from #define NLOHMANN_JSON_EXPAND( x ) x to the #define NLOHMANN_JSON_DOUBLE_PASTE63(...) line with the output, without its trailing empty line.
  2. Run ./macro_builder type_body. Replace the lines from #define NLOHMANN_JSON_TYPE_BODY(Prefix, ...) to the NLOHMANN_JSON_TYPE_BODY_SENTINEL)) line with the output.
  3. Run make amalgamate. It updates single_include/nlohmann/json.hpp and runs make pretty, which indents the continuation lines that the tool writes unindented.

With an unchanged main.cpp, these steps reproduce both blocks of macro_scope.hpp byte for byte. make macro_builder_check (also run by CI, see .github/workflows/check_amalgamation.yml) automates this: it builds main.cpp, regenerates both blocks, and fails on a diff against the checked-in header.

Maintained by hand

The tool does not generate everything that depends on the number of slots. When changing max_args, also update:

  • the documented limit of 63 members in docs/mkdocs/docs and the tests at that limit in tests/src/unit-udt_macro.cpp

All three tables pass one macro name per slot to NLOHMANN_JSON_GET_MACRO, so they need exactly as many entries as it has slots.