diff --git a/.github/workflows/check_amalgamation.yml b/.github/workflows/check_amalgamation.yml index 670269cbb..35f3a57f7 100644 --- a/.github/workflows/check_amalgamation.yml +++ b/.github/workflows/check_amalgamation.yml @@ -67,6 +67,7 @@ jobs: python3 $TOOL_DIR/amalgamate.py -c $TOOL_DIR/config_json.json -s . python3 $TOOL_DIR/amalgamate.py -c $TOOL_DIR/config_json_fwd.json -s . + cp include/nlohmann/json_literals.hpp $INCLUDE_DIR/json_literals.hpp # the header list of the Bazel "json" target must match the files in include/ cmake -P cmake/scripts/gen_bazel_build_file.cmake diff --git a/BUILD.bazel b/BUILD.bazel index db59095cd..5f2bea555 100644 --- a/BUILD.bazel +++ b/BUILD.bazel @@ -65,6 +65,7 @@ cc_library( "include/nlohmann/detail/value_t.hpp", "include/nlohmann/json.hpp", "include/nlohmann/json_fwd.hpp", + "include/nlohmann/json_literals.hpp", "include/nlohmann/ordered_map.hpp", "include/nlohmann/thirdparty/hedley/hedley.hpp", "include/nlohmann/thirdparty/hedley/hedley_undef.hpp", diff --git a/Makefile b/Makefile index 196f87243..ccea759af 100644 --- a/Makefile +++ b/Makefile @@ -21,6 +21,8 @@ TESTS_SRCS=$(shell find tests -type f \( -name '*.hpp' -o -name '*.cpp' -o -name # the single headers (amalgamated from the source files) AMALGAMATED_FILE=single_include/nlohmann/json.hpp AMALGAMATED_FWD_FILE=single_include/nlohmann/json_fwd.hpp +# json_literals.hpp only includes , so it is copied verbatim +AMALGAMATED_LITERALS_FILE=single_include/nlohmann/json_literals.hpp ########################################################################## @@ -29,7 +31,7 @@ AMALGAMATED_FWD_FILE=single_include/nlohmann/json_fwd.hpp # main target all: - @echo "amalgamate - amalgamate files single_include/nlohmann/json{,_fwd}.hpp from the include/nlohmann sources" + @echo "amalgamate - amalgamate files single_include/nlohmann/json{,_fwd,_literals}.hpp from the include/nlohmann sources" @echo "BUILD.bazel - regenerate the Bazel BUILD file from the include/nlohmann sources" @echo "ChangeLog.md - generate ChangeLog file" @echo "check-amalgamation - check whether sources have been amalgamated and BUILD.bazel is up to date" @@ -154,14 +156,14 @@ install_astyle: # call the Artistic Style pretty printer on all source files pretty: install_astyle - $(ASTYLE) --project=tools/astyle/.astylerc $(SRCS) $(TESTS_SRCS) $(AMALGAMATED_FILE) $(AMALGAMATED_FWD_FILE) docs/mkdocs/docs/examples/*.cpp + $(ASTYLE) --project=tools/astyle/.astylerc $(SRCS) $(TESTS_SRCS) $(AMALGAMATED_FILE) $(AMALGAMATED_FWD_FILE) $(AMALGAMATED_LITERALS_FILE) docs/mkdocs/docs/examples/*.cpp # call the Clang-Format on all source files pretty_format: for FILE in $(SRCS) $(TESTS_SRCS) $(AMALGAMATED_FILE) docs/mkdocs/docs/examples/*.cpp; do echo $$FILE; clang-format -i $$FILE; done # create single header files and pretty print -amalgamate: $(AMALGAMATED_FILE) $(AMALGAMATED_FWD_FILE) +amalgamate: $(AMALGAMATED_FILE) $(AMALGAMATED_FWD_FILE) $(AMALGAMATED_LITERALS_FILE) $(MAKE) pretty # call the amalgamation tool for json.hpp @@ -172,16 +174,23 @@ $(AMALGAMATED_FILE): $(SRCS) $(AMALGAMATED_FWD_FILE): $(SRCS) tools/amalgamate/amalgamate.py -c tools/amalgamate/config_json_fwd.json -s . --verbose=yes +# copy json_literals.hpp +$(AMALGAMATED_LITERALS_FILE): include/nlohmann/json_literals.hpp + cp include/nlohmann/json_literals.hpp $(AMALGAMATED_LITERALS_FILE) + # check if file single_include/nlohmann/json.hpp has been amalgamated from the nlohmann sources # Note: this target is called by Travis check-amalgamation: @mv $(AMALGAMATED_FILE) $(AMALGAMATED_FILE)~ @mv $(AMALGAMATED_FWD_FILE) $(AMALGAMATED_FWD_FILE)~ + @mv $(AMALGAMATED_LITERALS_FILE) $(AMALGAMATED_LITERALS_FILE)~ @$(MAKE) amalgamate @diff $(AMALGAMATED_FILE) $(AMALGAMATED_FILE)~ || (echo "===================================================================\n Amalgamation required! Please read the contribution guidelines\n in file .github/CONTRIBUTING.md.\n===================================================================" ; mv $(AMALGAMATED_FILE)~ $(AMALGAMATED_FILE) ; false) @diff $(AMALGAMATED_FWD_FILE) $(AMALGAMATED_FWD_FILE)~ || (echo "===================================================================\n Amalgamation required! Please read the contribution guidelines\n in file .github/CONTRIBUTING.md.\n===================================================================" ; mv $(AMALGAMATED_FWD_FILE)~ $(AMALGAMATED_FWD_FILE) ; false) + @diff $(AMALGAMATED_LITERALS_FILE) $(AMALGAMATED_LITERALS_FILE)~ || (echo "===================================================================\n Amalgamation required! Please read the contribution guidelines\n in file .github/CONTRIBUTING.md.\n===================================================================" ; mv $(AMALGAMATED_LITERALS_FILE)~ $(AMALGAMATED_LITERALS_FILE) ; false) @mv $(AMALGAMATED_FILE)~ $(AMALGAMATED_FILE) @mv $(AMALGAMATED_FWD_FILE)~ $(AMALGAMATED_FWD_FILE) + @mv $(AMALGAMATED_LITERALS_FILE)~ $(AMALGAMATED_LITERALS_FILE) @mv BUILD.bazel BUILD.bazel~ @$(MAKE) BUILD.bazel @diff BUILD.bazel BUILD.bazel~ || (echo "===================================================================\n BUILD.bazel is out of date! Please run 'make BUILD.bazel'.\n===================================================================" ; mv BUILD.bazel~ BUILD.bazel ; false) @@ -222,7 +231,7 @@ json.tar.xz: # We use `-X` to make the resulting ZIP file reproducible, see # . include.zip: BUILD.bazel - zip -9 --recurse-paths -X include.zip $(SRCS) $(AMALGAMATED_FILE) $(AMALGAMATED_FWD_FILE) BUILD.bazel MODULE.bazel meson.build LICENSE.MIT + zip -9 --recurse-paths -X include.zip $(SRCS) $(AMALGAMATED_FILE) $(AMALGAMATED_FWD_FILE) $(AMALGAMATED_LITERALS_FILE) BUILD.bazel MODULE.bazel meson.build LICENSE.MIT # Create the files for a release and add signatures and hashes. release: include.zip json.tar.xz @@ -231,10 +240,12 @@ release: include.zip json.tar.xz gpg --armor --detach-sig include.zip gpg --armor --detach-sig $(AMALGAMATED_FILE) gpg --armor --detach-sig $(AMALGAMATED_FWD_FILE) + gpg --armor --detach-sig $(AMALGAMATED_LITERALS_FILE) gpg --armor --detach-sig json.tar.xz cp $(AMALGAMATED_FILE) release_files cp $(AMALGAMATED_FWD_FILE) release_files - mv $(AMALGAMATED_FILE).asc $(AMALGAMATED_FWD_FILE).asc json.tar.xz json.tar.xz.asc include.zip include.zip.asc release_files + cp $(AMALGAMATED_LITERALS_FILE) release_files + mv $(AMALGAMATED_FILE).asc $(AMALGAMATED_FWD_FILE).asc $(AMALGAMATED_LITERALS_FILE).asc json.tar.xz json.tar.xz.asc include.zip include.zip.asc release_files cd release_files ; shasum -a 256 json.hpp include.zip json.tar.xz > hashes.txt diff --git a/cmake/ci.cmake b/cmake/ci.cmake index f7695c36e..a001a05ae 100644 --- a/cmake/ci.cmake +++ b/cmake/ci.cmake @@ -373,9 +373,10 @@ file(GLOB_RECURSE INDENT_FILES set(include_dir ${PROJECT_SOURCE_DIR}/single_include/nlohmann) set(tool_dir ${PROJECT_SOURCE_DIR}/tools/amalgamate) add_custom_target(ci_test_amalgamation - COMMAND rm -fr ${include_dir}/json.hpp~ ${include_dir}/json_fwd.hpp~ + COMMAND rm -fr ${include_dir}/json.hpp~ ${include_dir}/json_fwd.hpp~ ${include_dir}/json_literals.hpp~ COMMAND cp ${include_dir}/json.hpp ${include_dir}/json.hpp~ COMMAND cp ${include_dir}/json_fwd.hpp ${include_dir}/json_fwd.hpp~ + COMMAND cp ${include_dir}/json_literals.hpp ${include_dir}/json_literals.hpp~ COMMAND ${Python3_EXECUTABLE} -mvenv venv_astyle COMMAND venv_astyle/bin/pip3 --quiet install -r ${CMAKE_SOURCE_DIR}/tools/astyle/requirements.txt @@ -383,10 +384,12 @@ add_custom_target(ci_test_amalgamation COMMAND ${Python3_EXECUTABLE} ${tool_dir}/amalgamate.py -c ${tool_dir}/config_json.json -s . COMMAND ${Python3_EXECUTABLE} ${tool_dir}/amalgamate.py -c ${tool_dir}/config_json_fwd.json -s . + COMMAND cp ${PROJECT_SOURCE_DIR}/include/nlohmann/json_literals.hpp ${include_dir}/json_literals.hpp COMMAND venv_astyle/bin/astyle --project=tools/astyle/.astylerc --suffix=none ${include_dir}/json.hpp ${include_dir}/json_fwd.hpp COMMAND diff ${include_dir}/json.hpp~ ${include_dir}/json.hpp COMMAND diff ${include_dir}/json_fwd.hpp~ ${include_dir}/json_fwd.hpp + COMMAND diff ${include_dir}/json_literals.hpp~ ${include_dir}/json_literals.hpp COMMAND venv_astyle/bin/astyle --project=tools/astyle/.astylerc --suffix=orig ${INDENT_FILES} COMMAND for FILE in `find . -name '*.orig'`\; do false \; done diff --git a/docs/mkdocs/docs/api/macros/index.md b/docs/mkdocs/docs/api/macros/index.md index a59af1eaa..9d2636eb2 100644 --- a/docs/mkdocs/docs/api/macros/index.md +++ b/docs/mkdocs/docs/api/macros/index.md @@ -28,9 +28,9 @@ header. See also the [macro overview page](../../features/macros.md). - [**JSON_HAS_RANGES**](json_has_ranges.md) - control `std::ranges` support - [**JSON_HAS_STD_FORMAT**](json_has_std_format.md) - control `std::format`/`std::formatter` support - [**JSON_HAS_THREE_WAY_COMPARISON**](json_has_three_way_comparison.md) - control 3-way comparison support +- [**JSON_NO_AUTOMATIC_UDLS**](json_no_automatic_udls.md) - do not include the user-defined string literals (UDLs) automatically - [**JSON_NO_IO**](json_no_io.md) - switch off functions relying on certain C++ I/O headers - [**JSON_NO_THREAD_LOCAL**](json_no_thread_local.md) - switch off the use of `thread_local` storage -- [**JSON_NO_UDLS**](json_no_udls.md) - leave out the user-defined string literals (UDLs) to reduce compile time - [**JSON_SKIP_UNSUPPORTED_COMPILER_CHECK**](json_skip_unsupported_compiler_check.md) - do not warn about unsupported compilers - [**JSON_USE_GLOBAL_UDLS**](json_use_global_udls.md) - place user-defined string literals (UDLs) into the global namespace - [**JSON_USE_SIMDUTF**](json_use_simdutf.md) - use the simdutf library to accelerate UTF-8 validation diff --git a/docs/mkdocs/docs/api/macros/json_no_automatic_udls.md b/docs/mkdocs/docs/api/macros/json_no_automatic_udls.md new file mode 100644 index 000000000..acb6a356e --- /dev/null +++ b/docs/mkdocs/docs/api/macros/json_no_automatic_udls.md @@ -0,0 +1,68 @@ +# JSON_NO_AUTOMATIC_UDLS + +```cpp +#define JSON_NO_AUTOMATIC_UDLS +``` + +When defined, `` does not include ``, so the user-defined string +literals [`operator""_json`](../operator_literal_json.md) and +[`operator""_json_pointer`](../operator_literal_json_pointer.md) are not declared. Include +`` in the files that use them. + +The literals are ordinary inline functions whose bodies call the parser, so every translation unit that includes them +instantiates the parser — even if it never parses anything itself. Defining `JSON_NO_AUTOMATIC_UDLS` for a whole project +avoids this cost in translation units that do not parse (e.g., ones that only define types and conversions or pass +`json` values around) and reduces their compile time. + +## Default definition + +By default, `#!cpp JSON_NO_AUTOMATIC_UDLS` is not defined, and `` includes +``. + +```cpp +#undef JSON_NO_AUTOMATIC_UDLS +``` + +## Notes + +!!! info "Header ``" + + The header includes `` itself and places the literals according to + [`JSON_USE_GLOBAL_UDLS`](json_use_global_udls.md). It is part of the multi-header sources (`include/nlohmann`) + and of the single-header sources (`single_include/nlohmann`), next to `json.hpp`. + +!!! info "C++ modules" + + The `nlohmann.json` [module](../../features/modules.md) always exports the literals, regardless of this macro. + +## Examples + +??? example + + The code below includes the library without the literals and adds them in a single translation unit. + + ```cpp + // compiled with -DJSON_NO_AUTOMATIC_UDLS for the whole project + #include + + // this file uses the literals, so it includes them explicitly + #include + + int main() + { + auto j = R"({"foo": 42})"_json; + return j.at("/foo"_json_pointer) == 42 ? 0 : 1; + } + ``` + + Without the include of ``, the code would fail to compile. + +## See also + +- [`operator""_json`](../operator_literal_json.md) +- [`operator""_json_pointer`](../operator_literal_json_pointer.md) +- [`JSON_USE_GLOBAL_UDLS`](json_use_global_udls.md) - place user-defined string literals (UDLs) into the global namespace + +## Version history + +- Added in version 3.13.0. diff --git a/docs/mkdocs/docs/api/macros/json_no_udls.md b/docs/mkdocs/docs/api/macros/json_no_udls.md deleted file mode 100644 index 7e52d302f..000000000 --- a/docs/mkdocs/docs/api/macros/json_no_udls.md +++ /dev/null @@ -1,61 +0,0 @@ -# JSON_NO_UDLS - -```cpp -#define JSON_NO_UDLS -``` - -When defined, the user-defined string literals [`operator""_json`](../operator_literal_json.md) and -[`operator""_json_pointer`](../operator_literal_json_pointer.md) are not defined, neither in the namespace -`nlohmann::literals::json_literals` nor in the global namespace (regardless of -[`JSON_USE_GLOBAL_UDLS`](json_use_global_udls.md)). - -The literals are ordinary inline functions whose bodies call the parser, so every translation unit that includes the -library instantiates the parser — even if it never parses anything itself. Defining `JSON_NO_UDLS` avoids this and -reduces the compile time of such translation units (e.g., ones that only define types and conversions or pass `json` -values around). Everything else in the library is unaffected; use [`parse`](../basic_json/parse.md) and the -[`json_pointer`](../json_pointer/json_pointer.md) constructor instead of the literals. - -## Default definition - -By default, `#!cpp JSON_NO_UDLS` is not defined. - -```cpp -#undef JSON_NO_UDLS -``` - -## Notes - -!!! info "Per translation unit" - - The macro only removes declarations, so it can be defined for some translation units and not for others. Code that - uses `_json` or `_json_pointer` fails to compile when `JSON_NO_UDLS` is defined. - -## Examples - -??? example - - The code below leaves out the user-defined string literals and uses `parse` and the `json_pointer` constructor - instead. - - ```cpp - #define JSON_NO_UDLS 1 - #include - - int main() - { - // auto j = R"({"foo": 42})"_json; // This line would fail to compile - auto j = nlohmann::json::parse(R"({"foo": 42})"); - auto p = nlohmann::json::json_pointer("/foo"); - return j.at(p) == 42 ? 0 : 1; - } - ``` - -## See also - -- [`operator""_json`](../operator_literal_json.md) -- [`operator""_json_pointer`](../operator_literal_json_pointer.md) -- [`JSON_USE_GLOBAL_UDLS`](json_use_global_udls.md) - place user-defined string literals (UDLs) into the global namespace - -## Version history - -- Added in version 3.13.0. diff --git a/docs/mkdocs/docs/api/macros/json_use_global_udls.md b/docs/mkdocs/docs/api/macros/json_use_global_udls.md index f7ba822e1..0b055640e 100644 --- a/docs/mkdocs/docs/api/macros/json_use_global_udls.md +++ b/docs/mkdocs/docs/api/macros/json_use_global_udls.md @@ -15,7 +15,7 @@ The default value is `1`. #define JSON_USE_GLOBAL_UDLS 1 ``` -When the macro is not defined, the library will define it to its default value. +When the macro is not defined, the library behaves as if it were defined to its default value. ## Notes @@ -34,7 +34,8 @@ When the macro is not defined, the library will define it to its default value. !!! info "Leaving out the literals" - If [`JSON_NO_UDLS`](json_no_udls.md) is defined, the literals are not defined at all and this macro has no effect. + If [`JSON_NO_AUTOMATIC_UDLS`](json_no_automatic_udls.md) is defined, the literals are only declared where + `` is included; this macro then applies to that header. ## Examples @@ -96,7 +97,7 @@ When the macro is not defined, the library will define it to its default value. - [`operator""_json`](../operator_literal_json.md) - [`operator""_json_pointer`](../operator_literal_json_pointer.md) -- [`JSON_NO_UDLS`](json_no_udls.md) - leave out the user-defined string literals entirely +- [`JSON_NO_AUTOMATIC_UDLS`](json_no_automatic_udls.md) - do not include the user-defined string literals automatically - [:simple-cmake: JSON_GlobalUDLs](../../integration/cmake.md#json_globaludls) - CMake option to control the macro ## Version history diff --git a/docs/mkdocs/docs/api/operator_literal_json.md b/docs/mkdocs/docs/api/operator_literal_json.md index 15a5a606f..a909d8165 100644 --- a/docs/mkdocs/docs/api/operator_literal_json.md +++ b/docs/mkdocs/docs/api/operator_literal_json.md @@ -18,8 +18,9 @@ using namespace nlohmann; ``` This is suggested to ease migration to the next major version release of the library. See -[`JSON_USE_GLOBAL_UDLS`](macros/json_use_global_udls.md#notes) for details. The operator is not defined if -[`JSON_NO_UDLS`](macros/json_no_udls.md) is defined. +[`JSON_USE_GLOBAL_UDLS`](macros/json_use_global_udls.md#notes) for details. The operator is declared in header +``, which `` includes unless +[`JSON_NO_AUTOMATIC_UDLS`](macros/json_no_automatic_udls.md) is defined. ## Parameters @@ -60,7 +61,8 @@ Linear. ## See also - [Creating JSON values](../features/creating_values.md) - the article on creating JSON values -- [JSON_NO_UDLS](macros/json_no_udls.md) - leave out the user-defined string literals +- [JSON_NO_AUTOMATIC_UDLS](macros/json_no_automatic_udls.md) - do not include the user-defined string literals + automatically ## Version history diff --git a/docs/mkdocs/docs/api/operator_literal_json_pointer.md b/docs/mkdocs/docs/api/operator_literal_json_pointer.md index 5817963a4..0494439aa 100644 --- a/docs/mkdocs/docs/api/operator_literal_json_pointer.md +++ b/docs/mkdocs/docs/api/operator_literal_json_pointer.md @@ -17,8 +17,9 @@ using namespace nlohmann::literals::json_literals; using namespace nlohmann; ``` This is suggested to ease migration to the next major version release of the library. See -[`JSON_USE_GLOBAL_UDLS`](macros/json_use_global_udls.md#notes) for details. The operator is not defined if -[`JSON_NO_UDLS`](macros/json_no_udls.md) is defined. +[`JSON_USE_GLOBAL_UDLS`](macros/json_use_global_udls.md#notes) for details. The operator is declared in header +``, which `` includes unless +[`JSON_NO_AUTOMATIC_UDLS`](macros/json_no_automatic_udls.md) is defined. ## Parameters @@ -59,7 +60,8 @@ Linear. ## See also - [json_pointer](json_pointer/index.md) - type to represent JSON Pointers -- [JSON_NO_UDLS](macros/json_no_udls.md) - leave out the user-defined string literals +- [JSON_NO_AUTOMATIC_UDLS](macros/json_no_automatic_udls.md) - do not include the user-defined string literals + automatically ## Version history diff --git a/docs/mkdocs/docs/features/macros.md b/docs/mkdocs/docs/features/macros.md index 9a612fd07..e4a628c3e 100644 --- a/docs/mkdocs/docs/features/macros.md +++ b/docs/mkdocs/docs/features/macros.md @@ -83,6 +83,15 @@ When defined, default parse and serialize functions for enums are excluded and h See [full documentation of `JSON_DISABLE_ENUM_SERIALIZATION`](../api/macros/json_disable_enum_serialization.md). +## `JSON_NO_AUTOMATIC_UDLS` + +When defined, `` does not include `` with the user-defined string literals +`operator""_json` and `operator""_json_pointer`. This reduces the compile time of translation units that do not use +them, because the literals instantiate the parser in every translation unit that includes them. Include +`` where the literals are needed. + +See [full documentation of `JSON_NO_AUTOMATIC_UDLS`](../api/macros/json_no_automatic_udls.md). + ## `JSON_NO_IO` When defined, headers ``, ``, ``, ``, and `` are not included and parse functions @@ -99,14 +108,6 @@ same values and the same comparisons. See [full documentation of `JSON_NO_THREAD_LOCAL`](../api/macros/json_no_thread_local.md). -## `JSON_NO_UDLS` - -When defined, the user-defined string literals `operator""_json` and `operator""_json_pointer` are left out entirely. This -reduces the compile time of translation units that do not use them, because the literals would otherwise instantiate -the parser in every translation unit that includes the library. - -See [full documentation of `JSON_NO_UDLS`](../api/macros/json_no_udls.md). - ## `JSON_PRECISE_STREAM_POSITION` When defined to `1`, [`operator>>`](../api/operator_gtgt.md) and non-strict diff --git a/docs/mkdocs/docs/features/modules.md b/docs/mkdocs/docs/features/modules.md index 72d4ca6d5..32e9ba7fd 100644 --- a/docs/mkdocs/docs/features/modules.md +++ b/docs/mkdocs/docs/features/modules.md @@ -40,8 +40,8 @@ Only the following symbols are exported from `nlohmann.json`: - `nlohmann::literals::json_literals::operator""_json` - `nlohmann::literals::json_literals::operator""_json_pointer` -The two user-defined string literals are not exported if [`JSON_NO_UDLS`](../api/macros/json_no_udls.md) is defined -when building the module. +The module always exports the two user-defined string literals, even if +[`JSON_NO_AUTOMATIC_UDLS`](../api/macros/json_no_automatic_udls.md) is defined when building it. Additionally, the following `nlohmann::detail` symbols are exported, solely to work around an MSVC compilation issue ([#3970](https://github.com/nlohmann/json/issues/3970)). They are implementation details, not part of the public API, diff --git a/docs/mkdocs/docs/integration/index.md b/docs/mkdocs/docs/integration/index.md index 2bbaa8604..99bf088b6 100644 --- a/docs/mkdocs/docs/integration/index.md +++ b/docs/mkdocs/docs/integration/index.md @@ -15,4 +15,7 @@ Clang). You can further use file [`single_include/nlohmann/json_fwd.hpp`](https://github.com/nlohmann/json/blob/develop/single_include/nlohmann/json_fwd.hpp) -for forward declarations. +for forward declarations, and file +[`single_include/nlohmann/json_literals.hpp`](https://github.com/nlohmann/json/blob/develop/single_include/nlohmann/json_literals.hpp) +for the user-defined string literals if you define +[`JSON_NO_AUTOMATIC_UDLS`](../api/macros/json_no_automatic_udls.md). diff --git a/docs/mkdocs/mkdocs.yml b/docs/mkdocs/mkdocs.yml index 65111c8ca..21fad832a 100644 --- a/docs/mkdocs/mkdocs.yml +++ b/docs/mkdocs/mkdocs.yml @@ -293,10 +293,10 @@ nav: - 'JSON_HAS_STATIC_RTTI': api/macros/json_has_static_rtti.md - 'JSON_HAS_STD_FORMAT': api/macros/json_has_std_format.md - 'JSON_HAS_THREE_WAY_COMPARISON': api/macros/json_has_three_way_comparison.md + - 'JSON_NO_AUTOMATIC_UDLS': api/macros/json_no_automatic_udls.md - 'JSON_NOEXCEPTION': api/macros/json_noexception.md - 'JSON_NO_IO': api/macros/json_no_io.md - 'JSON_NO_THREAD_LOCAL': api/macros/json_no_thread_local.md - - 'JSON_NO_UDLS': api/macros/json_no_udls.md - 'JSON_PRECISE_STREAM_POSITION': api/macros/json_precise_stream_position.md - 'JSON_SKIP_LIBRARY_VERSION_CHECK': api/macros/json_skip_library_version_check.md - 'JSON_SKIP_UNSUPPORTED_COMPILER_CHECK': api/macros/json_skip_unsupported_compiler_check.md diff --git a/include/nlohmann/detail/macro_scope.hpp b/include/nlohmann/detail/macro_scope.hpp index 3a4eb79f4..7c39afbeb 100644 --- a/include/nlohmann/detail/macro_scope.hpp +++ b/include/nlohmann/detail/macro_scope.hpp @@ -915,7 +915,3 @@ void templated_json_throw(ExceptionType exception) #ifndef JSON_DISABLE_ENUM_SERIALIZATION #define JSON_DISABLE_ENUM_SERIALIZATION 0 #endif - -#ifndef JSON_USE_GLOBAL_UDLS - #define JSON_USE_GLOBAL_UDLS 1 -#endif diff --git a/include/nlohmann/detail/macro_unscope.hpp b/include/nlohmann/detail/macro_unscope.hpp index a73951a22..d2675d3f1 100644 --- a/include/nlohmann/detail/macro_unscope.hpp +++ b/include/nlohmann/detail/macro_unscope.hpp @@ -25,7 +25,6 @@ #undef JSON_INLINE_VARIABLE #undef JSON_NO_UNIQUE_ADDRESS #undef JSON_DISABLE_ENUM_SERIALIZATION -#undef JSON_USE_GLOBAL_UDLS #ifndef JSON_TEST_KEEP_MACROS #undef JSON_CATCH diff --git a/include/nlohmann/json.hpp b/include/nlohmann/json.hpp index d7dcfa6e2..6f3ec5b40 100644 --- a/include/nlohmann/json.hpp +++ b/include/nlohmann/json.hpp @@ -6423,57 +6423,6 @@ std::string format_as(const NLOHMANN_BASIC_JSON_TPL& j) return j.dump(); } -#ifndef JSON_NO_UDLS -inline namespace literals -{ -inline namespace json_literals -{ - -/// @brief user-defined string literal for JSON values -/// @sa https://json.nlohmann.me/api/basic_json/operator_literal_json/ -JSON_HEDLEY_NON_NULL(1) -#if !defined(JSON_HEDLEY_GCC_VERSION) || JSON_HEDLEY_GCC_VERSION_CHECK(4,9,0) - inline nlohmann::json operator""_json(const char* s, std::size_t n) -#else - // GCC 4.8 requires a space between "" and suffix - inline nlohmann::json operator"" _json(const char* s, std::size_t n) -#endif -{ - return nlohmann::json::parse(s, s + n); -} - -#if defined(__cpp_char8_t) -JSON_HEDLEY_NON_NULL(1) -inline nlohmann::json operator""_json(const char8_t* s, std::size_t n) -{ - return nlohmann::json::parse(reinterpret_cast(s), - reinterpret_cast(s) + n); -} -#endif - -/// @brief user-defined string literal for JSON pointer -/// @sa https://json.nlohmann.me/api/basic_json/operator_literal_json_pointer/ -JSON_HEDLEY_NON_NULL(1) -#if !defined(JSON_HEDLEY_GCC_VERSION) || JSON_HEDLEY_GCC_VERSION_CHECK(4,9,0) - inline nlohmann::json::json_pointer operator""_json_pointer(const char* s, std::size_t n) -#else - // GCC 4.8 requires a space between "" and suffix - inline nlohmann::json::json_pointer operator"" _json_pointer(const char* s, std::size_t n) -#endif -{ - return nlohmann::json::json_pointer(std::string(s, n)); -} - -#if defined(__cpp_char8_t) -inline nlohmann::json::json_pointer operator""_json_pointer(const char8_t* s, std::size_t n) -{ - return nlohmann::json::json_pointer(std::string(reinterpret_cast(s), n)); -} -#endif - -} // namespace json_literals -} // namespace literals -#endif // JSON_NO_UDLS NLOHMANN_JSON_NAMESPACE_END /////////////////////// @@ -6608,17 +6557,6 @@ struct formatter // NOLINT(cert-dcl58-c } // namespace std -#if JSON_USE_GLOBAL_UDLS && !defined(JSON_NO_UDLS) - #if !defined(JSON_HEDLEY_GCC_VERSION) || JSON_HEDLEY_GCC_VERSION_CHECK(4,9,0) - using nlohmann::literals::json_literals::operator""_json; // NOLINT(misc-unused-using-decls,google-global-names-in-headers) - using nlohmann::literals::json_literals::operator""_json_pointer; //NOLINT(misc-unused-using-decls,google-global-names-in-headers) - #else - // GCC 4.8 requires a space between "" and suffix - using nlohmann::literals::json_literals::operator"" _json; // NOLINT(misc-unused-using-decls,google-global-names-in-headers) - using nlohmann::literals::json_literals::operator"" _json_pointer; //NOLINT(misc-unused-using-decls,google-global-names-in-headers) - #endif -#endif - #include // End of GCC diagnostic pragmas for C++ modules support @@ -6626,4 +6564,12 @@ struct formatter // NOLINT(cert-dcl58-c #pragma GCC diagnostic pop #endif +// The user-defined string literals are in a separate header, because their +// bodies instantiate the parser in every translation unit that includes them. +// Define JSON_NO_AUTOMATIC_UDLS to include only +// where needed. +#ifndef JSON_NO_AUTOMATIC_UDLS + #include +#endif + #endif // INCLUDE_NLOHMANN_JSON_HPP_ diff --git a/include/nlohmann/json_literals.hpp b/include/nlohmann/json_literals.hpp new file mode 100644 index 000000000..d62e0cf2e --- /dev/null +++ b/include/nlohmann/json_literals.hpp @@ -0,0 +1,83 @@ +// __ _____ _____ _____ +// __| | __| | | | JSON for Modern C++ +// | | |__ | | | | | | version 3.12.0 +// |_____|_____|_____|_|___| https://github.com/nlohmann/json +// +// SPDX-FileCopyrightText: 2013-2026 Niels Lohmann +// SPDX-License-Identifier: MIT + +#ifndef INCLUDE_NLOHMANN_JSON_LITERALS_HPP_ +#define INCLUDE_NLOHMANN_JSON_LITERALS_HPP_ + +#include // size_t +#include // string + +#include + +// This header is included at the end of unless +// JSON_NO_AUTOMATIC_UDLS is defined, and can be included on its own after that. +// Either way, the library's internal macros are no longer defined here (and the +// amalgamation inlines macro_scope.hpp only once), so only standard and public +// macros may be used below. + +NLOHMANN_JSON_NAMESPACE_BEGIN +inline namespace literals +{ +inline namespace json_literals +{ + +/// @brief user-defined string literal for JSON values +/// @sa https://json.nlohmann.me/api/operator_literal_json/ +#if !defined(__GNUC__) || defined(__clang__) || __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 9) + inline nlohmann::json operator""_json(const char* s, std::size_t n) +#else + // GCC 4.8 requires a space between "" and suffix + inline nlohmann::json operator"" _json(const char* s, std::size_t n) +#endif +{ + return nlohmann::json::parse(s, s + n); +} + +#if defined(__cpp_char8_t) +inline nlohmann::json operator""_json(const char8_t* s, std::size_t n) +{ + return nlohmann::json::parse(reinterpret_cast(s), + reinterpret_cast(s) + n); +} +#endif + +/// @brief user-defined string literal for JSON pointer +/// @sa https://json.nlohmann.me/api/operator_literal_json_pointer/ +#if !defined(__GNUC__) || defined(__clang__) || __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 9) + inline nlohmann::json::json_pointer operator""_json_pointer(const char* s, std::size_t n) +#else + // GCC 4.8 requires a space between "" and suffix + inline nlohmann::json::json_pointer operator"" _json_pointer(const char* s, std::size_t n) +#endif +{ + return nlohmann::json::json_pointer(std::string(s, n)); +} + +#if defined(__cpp_char8_t) +inline nlohmann::json::json_pointer operator""_json_pointer(const char8_t* s, std::size_t n) +{ + return nlohmann::json::json_pointer(std::string(reinterpret_cast(s), n)); +} +#endif + +} // namespace json_literals +} // namespace literals +NLOHMANN_JSON_NAMESPACE_END + +#if !defined(JSON_USE_GLOBAL_UDLS) || JSON_USE_GLOBAL_UDLS + #if !defined(__GNUC__) || defined(__clang__) || __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 9) + using nlohmann::literals::json_literals::operator""_json; // NOLINT(misc-unused-using-decls,google-global-names-in-headers) + using nlohmann::literals::json_literals::operator""_json_pointer; //NOLINT(misc-unused-using-decls,google-global-names-in-headers) + #else + // GCC 4.8 requires a space between "" and suffix + using nlohmann::literals::json_literals::operator"" _json; // NOLINT(misc-unused-using-decls,google-global-names-in-headers) + using nlohmann::literals::json_literals::operator"" _json_pointer; //NOLINT(misc-unused-using-decls,google-global-names-in-headers) + #endif +#endif + +#endif // INCLUDE_NLOHMANN_JSON_LITERALS_HPP_ diff --git a/meson.build b/meson.build index a2d6e31a2..2800957ec 100644 --- a/meson.build +++ b/meson.build @@ -15,6 +15,7 @@ nlohmann_json_multiple_headers = declare_dependency( if not meson.is_subproject() install_headers('single_include/nlohmann/json.hpp', subdir: 'nlohmann') install_headers('single_include/nlohmann/json_fwd.hpp', subdir: 'nlohmann') +install_headers('single_include/nlohmann/json_literals.hpp', subdir: 'nlohmann') pkgc = import('pkgconfig') pkgc.generate(name: 'nlohmann_json', diff --git a/single_include/nlohmann/json.hpp b/single_include/nlohmann/json.hpp index e73583e17..14ae985f3 100644 --- a/single_include/nlohmann/json.hpp +++ b/single_include/nlohmann/json.hpp @@ -3327,10 +3327,6 @@ void templated_json_throw(ExceptionType exception) #define JSON_DISABLE_ENUM_SERIALIZATION 0 #endif -#ifndef JSON_USE_GLOBAL_UDLS - #define JSON_USE_GLOBAL_UDLS 1 -#endif - #if JSON_HAS_THREE_WAY_COMPARISON #include // partial_ordering #endif @@ -32504,57 +32500,6 @@ std::string format_as(const NLOHMANN_BASIC_JSON_TPL& j) return j.dump(); } -#ifndef JSON_NO_UDLS -inline namespace literals -{ -inline namespace json_literals -{ - -/// @brief user-defined string literal for JSON values -/// @sa https://json.nlohmann.me/api/basic_json/operator_literal_json/ -JSON_HEDLEY_NON_NULL(1) -#if !defined(JSON_HEDLEY_GCC_VERSION) || JSON_HEDLEY_GCC_VERSION_CHECK(4,9,0) - inline nlohmann::json operator""_json(const char* s, std::size_t n) -#else - // GCC 4.8 requires a space between "" and suffix - inline nlohmann::json operator"" _json(const char* s, std::size_t n) -#endif -{ - return nlohmann::json::parse(s, s + n); -} - -#if defined(__cpp_char8_t) -JSON_HEDLEY_NON_NULL(1) -inline nlohmann::json operator""_json(const char8_t* s, std::size_t n) -{ - return nlohmann::json::parse(reinterpret_cast(s), - reinterpret_cast(s) + n); -} -#endif - -/// @brief user-defined string literal for JSON pointer -/// @sa https://json.nlohmann.me/api/basic_json/operator_literal_json_pointer/ -JSON_HEDLEY_NON_NULL(1) -#if !defined(JSON_HEDLEY_GCC_VERSION) || JSON_HEDLEY_GCC_VERSION_CHECK(4,9,0) - inline nlohmann::json::json_pointer operator""_json_pointer(const char* s, std::size_t n) -#else - // GCC 4.8 requires a space between "" and suffix - inline nlohmann::json::json_pointer operator"" _json_pointer(const char* s, std::size_t n) -#endif -{ - return nlohmann::json::json_pointer(std::string(s, n)); -} - -#if defined(__cpp_char8_t) -inline nlohmann::json::json_pointer operator""_json_pointer(const char8_t* s, std::size_t n) -{ - return nlohmann::json::json_pointer(std::string(reinterpret_cast(s), n)); -} -#endif - -} // namespace json_literals -} // namespace literals -#endif // JSON_NO_UDLS NLOHMANN_JSON_NAMESPACE_END /////////////////////// @@ -32689,17 +32634,6 @@ struct formatter // NOLINT(cert-dcl58-c } // namespace std -#if JSON_USE_GLOBAL_UDLS && !defined(JSON_NO_UDLS) - #if !defined(JSON_HEDLEY_GCC_VERSION) || JSON_HEDLEY_GCC_VERSION_CHECK(4,9,0) - using nlohmann::literals::json_literals::operator""_json; // NOLINT(misc-unused-using-decls,google-global-names-in-headers) - using nlohmann::literals::json_literals::operator""_json_pointer; //NOLINT(misc-unused-using-decls,google-global-names-in-headers) - #else - // GCC 4.8 requires a space between "" and suffix - using nlohmann::literals::json_literals::operator"" _json; // NOLINT(misc-unused-using-decls,google-global-names-in-headers) - using nlohmann::literals::json_literals::operator"" _json_pointer; //NOLINT(misc-unused-using-decls,google-global-names-in-headers) - #endif -#endif - // #include // __ _____ _____ _____ // __| | __| | | | JSON for Modern C++ @@ -32728,7 +32662,6 @@ struct formatter // NOLINT(cert-dcl58-c #undef JSON_INLINE_VARIABLE #undef JSON_NO_UNIQUE_ADDRESS #undef JSON_DISABLE_ENUM_SERIALIZATION -#undef JSON_USE_GLOBAL_UDLS #ifndef JSON_TEST_KEEP_MACROS #undef JSON_CATCH @@ -32921,4 +32854,97 @@ struct formatter // NOLINT(cert-dcl58-c #pragma GCC diagnostic pop #endif +// The user-defined string literals are in a separate header, because their +// bodies instantiate the parser in every translation unit that includes them. +// Define JSON_NO_AUTOMATIC_UDLS to include only +// where needed. +#ifndef JSON_NO_AUTOMATIC_UDLS +// #include +// __ _____ _____ _____ +// __| | __| | | | JSON for Modern C++ +// | | |__ | | | | | | version 3.12.0 +// |_____|_____|_____|_|___| https://github.com/nlohmann/json +// +// SPDX-FileCopyrightText: 2013-2026 Niels Lohmann +// SPDX-License-Identifier: MIT + +#ifndef INCLUDE_NLOHMANN_JSON_LITERALS_HPP_ +#define INCLUDE_NLOHMANN_JSON_LITERALS_HPP_ + +#include // size_t +#include // string + +// #include + + +// This header is included at the end of unless +// JSON_NO_AUTOMATIC_UDLS is defined, and can be included on its own after that. +// Either way, the library's internal macros are no longer defined here (and the +// amalgamation inlines macro_scope.hpp only once), so only standard and public +// macros may be used below. + +NLOHMANN_JSON_NAMESPACE_BEGIN +inline namespace literals +{ +inline namespace json_literals +{ + +/// @brief user-defined string literal for JSON values +/// @sa https://json.nlohmann.me/api/operator_literal_json/ +#if !defined(__GNUC__) || defined(__clang__) || __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 9) + inline nlohmann::json operator""_json(const char* s, std::size_t n) +#else + // GCC 4.8 requires a space between "" and suffix + inline nlohmann::json operator"" _json(const char* s, std::size_t n) +#endif +{ + return nlohmann::json::parse(s, s + n); +} + +#if defined(__cpp_char8_t) +inline nlohmann::json operator""_json(const char8_t* s, std::size_t n) +{ + return nlohmann::json::parse(reinterpret_cast(s), + reinterpret_cast(s) + n); +} +#endif + +/// @brief user-defined string literal for JSON pointer +/// @sa https://json.nlohmann.me/api/operator_literal_json_pointer/ +#if !defined(__GNUC__) || defined(__clang__) || __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 9) + inline nlohmann::json::json_pointer operator""_json_pointer(const char* s, std::size_t n) +#else + // GCC 4.8 requires a space between "" and suffix + inline nlohmann::json::json_pointer operator"" _json_pointer(const char* s, std::size_t n) +#endif +{ + return nlohmann::json::json_pointer(std::string(s, n)); +} + +#if defined(__cpp_char8_t) +inline nlohmann::json::json_pointer operator""_json_pointer(const char8_t* s, std::size_t n) +{ + return nlohmann::json::json_pointer(std::string(reinterpret_cast(s), n)); +} +#endif + +} // namespace json_literals +} // namespace literals +NLOHMANN_JSON_NAMESPACE_END + +#if !defined(JSON_USE_GLOBAL_UDLS) || JSON_USE_GLOBAL_UDLS + #if !defined(__GNUC__) || defined(__clang__) || __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 9) + using nlohmann::literals::json_literals::operator""_json; // NOLINT(misc-unused-using-decls,google-global-names-in-headers) + using nlohmann::literals::json_literals::operator""_json_pointer; //NOLINT(misc-unused-using-decls,google-global-names-in-headers) + #else + // GCC 4.8 requires a space between "" and suffix + using nlohmann::literals::json_literals::operator"" _json; // NOLINT(misc-unused-using-decls,google-global-names-in-headers) + using nlohmann::literals::json_literals::operator"" _json_pointer; //NOLINT(misc-unused-using-decls,google-global-names-in-headers) + #endif +#endif + +#endif // INCLUDE_NLOHMANN_JSON_LITERALS_HPP_ + +#endif + #endif // INCLUDE_NLOHMANN_JSON_HPP_ diff --git a/single_include/nlohmann/json_literals.hpp b/single_include/nlohmann/json_literals.hpp new file mode 100644 index 000000000..d62e0cf2e --- /dev/null +++ b/single_include/nlohmann/json_literals.hpp @@ -0,0 +1,83 @@ +// __ _____ _____ _____ +// __| | __| | | | JSON for Modern C++ +// | | |__ | | | | | | version 3.12.0 +// |_____|_____|_____|_|___| https://github.com/nlohmann/json +// +// SPDX-FileCopyrightText: 2013-2026 Niels Lohmann +// SPDX-License-Identifier: MIT + +#ifndef INCLUDE_NLOHMANN_JSON_LITERALS_HPP_ +#define INCLUDE_NLOHMANN_JSON_LITERALS_HPP_ + +#include // size_t +#include // string + +#include + +// This header is included at the end of unless +// JSON_NO_AUTOMATIC_UDLS is defined, and can be included on its own after that. +// Either way, the library's internal macros are no longer defined here (and the +// amalgamation inlines macro_scope.hpp only once), so only standard and public +// macros may be used below. + +NLOHMANN_JSON_NAMESPACE_BEGIN +inline namespace literals +{ +inline namespace json_literals +{ + +/// @brief user-defined string literal for JSON values +/// @sa https://json.nlohmann.me/api/operator_literal_json/ +#if !defined(__GNUC__) || defined(__clang__) || __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 9) + inline nlohmann::json operator""_json(const char* s, std::size_t n) +#else + // GCC 4.8 requires a space between "" and suffix + inline nlohmann::json operator"" _json(const char* s, std::size_t n) +#endif +{ + return nlohmann::json::parse(s, s + n); +} + +#if defined(__cpp_char8_t) +inline nlohmann::json operator""_json(const char8_t* s, std::size_t n) +{ + return nlohmann::json::parse(reinterpret_cast(s), + reinterpret_cast(s) + n); +} +#endif + +/// @brief user-defined string literal for JSON pointer +/// @sa https://json.nlohmann.me/api/operator_literal_json_pointer/ +#if !defined(__GNUC__) || defined(__clang__) || __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 9) + inline nlohmann::json::json_pointer operator""_json_pointer(const char* s, std::size_t n) +#else + // GCC 4.8 requires a space between "" and suffix + inline nlohmann::json::json_pointer operator"" _json_pointer(const char* s, std::size_t n) +#endif +{ + return nlohmann::json::json_pointer(std::string(s, n)); +} + +#if defined(__cpp_char8_t) +inline nlohmann::json::json_pointer operator""_json_pointer(const char8_t* s, std::size_t n) +{ + return nlohmann::json::json_pointer(std::string(reinterpret_cast(s), n)); +} +#endif + +} // namespace json_literals +} // namespace literals +NLOHMANN_JSON_NAMESPACE_END + +#if !defined(JSON_USE_GLOBAL_UDLS) || JSON_USE_GLOBAL_UDLS + #if !defined(__GNUC__) || defined(__clang__) || __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 9) + using nlohmann::literals::json_literals::operator""_json; // NOLINT(misc-unused-using-decls,google-global-names-in-headers) + using nlohmann::literals::json_literals::operator""_json_pointer; //NOLINT(misc-unused-using-decls,google-global-names-in-headers) + #else + // GCC 4.8 requires a space between "" and suffix + using nlohmann::literals::json_literals::operator"" _json; // NOLINT(misc-unused-using-decls,google-global-names-in-headers) + using nlohmann::literals::json_literals::operator"" _json_pointer; //NOLINT(misc-unused-using-decls,google-global-names-in-headers) + #endif +#endif + +#endif // INCLUDE_NLOHMANN_JSON_LITERALS_HPP_ diff --git a/src/modules/json.cppm b/src/modules/json.cppm index 480961f6b..a32b97603 100644 --- a/src/modules/json.cppm +++ b/src/modules/json.cppm @@ -18,6 +18,7 @@ module; // See: https://github.com/nlohmann/json/issues/5103 #include +#include export module nlohmann.json; @@ -32,7 +33,6 @@ using NLOHMANN_JSON_NAMESPACE::ordered_json; using NLOHMANN_JSON_NAMESPACE::ordered_map; using NLOHMANN_JSON_NAMESPACE::to_string; -#ifndef JSON_NO_UDLS inline namespace literals { inline namespace json_literals @@ -41,7 +41,6 @@ inline namespace json_literals using NLOHMANN_JSON_NAMESPACE::literals::json_literals::operator""_json_pointer; } // namespace json_literals } // namespace literals -#endif // Note: the following nlohmann::detail symbols must be exported due to // an MSVC bug failing to compile without these symbols visible (ticket #3970) diff --git a/tests/src/unit-no_udls.cpp b/tests/src/unit-no_automatic_udls.cpp similarity index 66% rename from tests/src/unit-no_udls.cpp rename to tests/src/unit-no_automatic_udls.cpp index bf5402b1c..001ed4251 100644 --- a/tests/src/unit-no_udls.cpp +++ b/tests/src/unit-no_automatic_udls.cpp @@ -6,10 +6,12 @@ // SPDX-FileCopyrightText: 2013-2026 Niels Lohmann // SPDX-License-Identifier: MIT -// This translation unit checks JSON_NO_UDLS, which leaves out the user-defined -// string literals operator""_json and operator""_json_pointer entirely (see -// #5294), while the rest of the library keeps working. -#define JSON_NO_UDLS 1 +// This translation unit checks JSON_NO_AUTOMATIC_UDLS, which keeps +// from including and thereby +// leaves out the user-defined string literals operator""_json and +// operator""_json_pointer (see #5294), and that including +// afterwards brings them back. +#define JSON_NO_AUTOMATIC_UDLS 1 #include "doctest_compatibility.h" @@ -23,7 +25,7 @@ using json = nlohmann::json; // argument-dependent lookup of a literal operator called by its function name // also searches the inline namespaces nlohmann::literals::json_literals. NLOHMANN_JSON_NAMESPACE_BEGIN -struct no_udls_probe +struct no_automatic_udls_probe { operator const char* () const // NOLINT(google-explicit-constructor,hicpp-explicit-conversions) { @@ -52,7 +54,7 @@ template using has_json_pointer_udl = nlohmann::detail::is_detected; } // namespace -TEST_CASE("JSON_NO_UDLS") +TEST_CASE("JSON_NO_AUTOMATIC_UDLS") { SECTION("literals are not declared") { @@ -61,8 +63,8 @@ TEST_CASE("JSON_NO_UDLS") CHECK_FALSE(has_json_pointer_udl::value); // nlohmann::literals::json_literals - CHECK_FALSE(has_json_udl::value); - CHECK_FALSE(has_json_pointer_udl::value); + CHECK_FALSE(has_json_udl::value); + CHECK_FALSE(has_json_pointer_udl::value); } SECTION("the rest of the library keeps working") @@ -75,3 +77,21 @@ TEST_CASE("JSON_NO_UDLS") CHECK(j.contains(ptr)); } } + +// the literals can still be added where they are needed +#include + +TEST_CASE("JSON_NO_AUTOMATIC_UDLS with ") +{ + SECTION("global namespace") + { + CHECK("[1,2]"_json == json({1, 2})); + CHECK("/a/0"_json_pointer == json::json_pointer("/a/0")); + } + + SECTION("nlohmann::literals::json_literals") + { + using namespace nlohmann::literals::json_literals; // NOLINT(google-build-using-namespace) + CHECK(R"({"a":[42]})"_json.at("/a/0"_json_pointer) == 42); + } +}