Compare commits

..
Author SHA1 Message Date
Niels Lohmann a00c951d52 Fix CI: include cycle, GCC 4.8 literal operator spacing, and global UDLs off in the JSON_NO_AUTOMATIC_UDLS test
- Suppress clang-tidy misc-header-include-cycle on the intentional mutual
  include of json.hpp and json_literals.hpp.
- Use operator"" _json with a space for GCC 4.8 in the test's detection
  aliases, as the header does.
- Only test the global literal operators when JSON_USE_GLOBAL_UDLS is on.

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-09-29 16:40:12 +02:00
Niels Lohmann 71b9c4a88d Merge branch 'develop' into claude/json-no-udls-e999fc
Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-09-28 22:22:15 +02:00
Niels Lohmann 1419aeff60 Move the user-defined string literals to <nlohmann/json_literals.hpp>
Following the review in #5294, the literals now live in their own header
instead of being removed entirely: <nlohmann/json.hpp> includes it at the
end unless JSON_NO_AUTOMATIC_UDLS (renamed from JSON_NO_UDLS) is defined,
so a project can opt out globally and include the header only where the
literals are used.

The header only uses public and standard macros, because the library's
internal macros are undefined at the end of json.hpp and the amalgamation
inlines macro_scope.hpp only once. For the same reason, the library no
longer defines and undefines JSON_USE_GLOBAL_UDLS, so a user's definition
is still visible to the header. The single-header copy is identical to
the multi-header one, as it only includes <nlohmann/json.hpp>. The module
always exports the literals.

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-09-28 21:49:37 +02:00
Niels Lohmann e0ee07fe73 Mention JSON_NO_UDLS in the list of exported module symbols
Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-09-28 21:24:40 +02:00
Niels Lohmann dc4a70e7b4 Add JSON_NO_UDLS to leave out the user-defined string literals
The bodies of operator""_json and operator""_json_pointer call the
parser, so every translation unit including the library instantiates it,
even if it never parses anything. Defining JSON_NO_UDLS leaves the
literals out entirely, which saves 15-35% compile time for such
translation units (#5294). Nothing changes if the macro is not defined.

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-09-28 21:23:52 +02:00
22 changed files with 507 additions and 140 deletions
+1
View File
@@ -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.json -s .
python3 $TOOL_DIR/amalgamate.py -c $TOOL_DIR/config_json_fwd.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/ # the header list of the Bazel "json" target must match the files in include/
cmake -P cmake/scripts/gen_bazel_build_file.cmake cmake -P cmake/scripts/gen_bazel_build_file.cmake
+1
View File
@@ -65,6 +65,7 @@ cc_library(
"include/nlohmann/detail/value_t.hpp", "include/nlohmann/detail/value_t.hpp",
"include/nlohmann/json.hpp", "include/nlohmann/json.hpp",
"include/nlohmann/json_fwd.hpp", "include/nlohmann/json_fwd.hpp",
"include/nlohmann/json_literals.hpp",
"include/nlohmann/ordered_map.hpp", "include/nlohmann/ordered_map.hpp",
"include/nlohmann/thirdparty/hedley/hedley.hpp", "include/nlohmann/thirdparty/hedley/hedley.hpp",
"include/nlohmann/thirdparty/hedley/hedley_undef.hpp", "include/nlohmann/thirdparty/hedley/hedley_undef.hpp",
+16 -5
View File
@@ -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) # the single headers (amalgamated from the source files)
AMALGAMATED_FILE=single_include/nlohmann/json.hpp AMALGAMATED_FILE=single_include/nlohmann/json.hpp
AMALGAMATED_FWD_FILE=single_include/nlohmann/json_fwd.hpp AMALGAMATED_FWD_FILE=single_include/nlohmann/json_fwd.hpp
# json_literals.hpp only includes <nlohmann/json.hpp>, 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 # main target
all: 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 "BUILD.bazel - regenerate the Bazel BUILD file from the include/nlohmann sources"
@echo "ChangeLog.md - generate ChangeLog file" @echo "ChangeLog.md - generate ChangeLog file"
@echo "check-amalgamation - check whether sources have been amalgamated and BUILD.bazel is up to date" @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 # call the Artistic Style pretty printer on all source files
pretty: install_astyle 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 # call the Clang-Format on all source files
pretty_format: pretty_format:
for FILE in $(SRCS) $(TESTS_SRCS) $(AMALGAMATED_FILE) docs/mkdocs/docs/examples/*.cpp; do echo $$FILE; clang-format -i $$FILE; done 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 # create single header files and pretty print
amalgamate: $(AMALGAMATED_FILE) $(AMALGAMATED_FWD_FILE) amalgamate: $(AMALGAMATED_FILE) $(AMALGAMATED_FWD_FILE) $(AMALGAMATED_LITERALS_FILE)
$(MAKE) pretty $(MAKE) pretty
# call the amalgamation tool for json.hpp # call the amalgamation tool for json.hpp
@@ -172,16 +174,23 @@ $(AMALGAMATED_FILE): $(SRCS)
$(AMALGAMATED_FWD_FILE): $(SRCS) $(AMALGAMATED_FWD_FILE): $(SRCS)
tools/amalgamate/amalgamate.py -c tools/amalgamate/config_json_fwd.json -s . --verbose=yes 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 # check if file single_include/nlohmann/json.hpp has been amalgamated from the nlohmann sources
# Note: this target is called by Travis # Note: this target is called by Travis
check-amalgamation: check-amalgamation:
@mv $(AMALGAMATED_FILE) $(AMALGAMATED_FILE)~ @mv $(AMALGAMATED_FILE) $(AMALGAMATED_FILE)~
@mv $(AMALGAMATED_FWD_FILE) $(AMALGAMATED_FWD_FILE)~ @mv $(AMALGAMATED_FWD_FILE) $(AMALGAMATED_FWD_FILE)~
@mv $(AMALGAMATED_LITERALS_FILE) $(AMALGAMATED_LITERALS_FILE)~
@$(MAKE) amalgamate @$(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_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_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_FILE)~ $(AMALGAMATED_FILE)
@mv $(AMALGAMATED_FWD_FILE)~ $(AMALGAMATED_FWD_FILE) @mv $(AMALGAMATED_FWD_FILE)~ $(AMALGAMATED_FWD_FILE)
@mv $(AMALGAMATED_LITERALS_FILE)~ $(AMALGAMATED_LITERALS_FILE)
@mv BUILD.bazel BUILD.bazel~ @mv BUILD.bazel BUILD.bazel~
@$(MAKE) 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) @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 # We use `-X` to make the resulting ZIP file reproducible, see
# <https://content.pivotal.io/blog/barriers-to-deterministic-reproducible-zip-files>. # <https://content.pivotal.io/blog/barriers-to-deterministic-reproducible-zip-files>.
include.zip: BUILD.bazel 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. # Create the files for a release and add signatures and hashes.
release: include.zip json.tar.xz 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 include.zip
gpg --armor --detach-sig $(AMALGAMATED_FILE) gpg --armor --detach-sig $(AMALGAMATED_FILE)
gpg --armor --detach-sig $(AMALGAMATED_FWD_FILE) gpg --armor --detach-sig $(AMALGAMATED_FWD_FILE)
gpg --armor --detach-sig $(AMALGAMATED_LITERALS_FILE)
gpg --armor --detach-sig json.tar.xz gpg --armor --detach-sig json.tar.xz
cp $(AMALGAMATED_FILE) release_files cp $(AMALGAMATED_FILE) release_files
cp $(AMALGAMATED_FWD_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 cd release_files ; shasum -a 256 json.hpp include.zip json.tar.xz > hashes.txt
+4 -1
View File
@@ -373,9 +373,10 @@ file(GLOB_RECURSE INDENT_FILES
set(include_dir ${PROJECT_SOURCE_DIR}/single_include/nlohmann) set(include_dir ${PROJECT_SOURCE_DIR}/single_include/nlohmann)
set(tool_dir ${PROJECT_SOURCE_DIR}/tools/amalgamate) set(tool_dir ${PROJECT_SOURCE_DIR}/tools/amalgamate)
add_custom_target(ci_test_amalgamation 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.hpp ${include_dir}/json.hpp~
COMMAND cp ${include_dir}/json_fwd.hpp ${include_dir}/json_fwd.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 ${Python3_EXECUTABLE} -mvenv venv_astyle
COMMAND venv_astyle/bin/pip3 --quiet install -r ${CMAKE_SOURCE_DIR}/tools/astyle/requirements.txt 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.json -s .
COMMAND ${Python3_EXECUTABLE} ${tool_dir}/amalgamate.py -c ${tool_dir}/config_json_fwd.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 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.hpp~ ${include_dir}/json.hpp
COMMAND diff ${include_dir}/json_fwd.hpp~ ${include_dir}/json_fwd.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 venv_astyle/bin/astyle --project=tools/astyle/.astylerc --suffix=orig ${INDENT_FILES}
COMMAND for FILE in `find . -name '*.orig'`\; do false \; done COMMAND for FILE in `find . -name '*.orig'`\; do false \; done
+1
View File
@@ -28,6 +28,7 @@ header. See also the [macro overview page](../../features/macros.md).
- [**JSON_HAS_RANGES**](json_has_ranges.md) - control `std::ranges` support - [**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_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_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_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_THREAD_LOCAL**](json_no_thread_local.md) - switch off the use of `thread_local` storage
- [**JSON_SKIP_UNSUPPORTED_COMPILER_CHECK**](json_skip_unsupported_compiler_check.md) - do not warn about unsupported compilers - [**JSON_SKIP_UNSUPPORTED_COMPILER_CHECK**](json_skip_unsupported_compiler_check.md) - do not warn about unsupported compilers
@@ -0,0 +1,68 @@
# JSON_NO_AUTOMATIC_UDLS
```cpp
#define JSON_NO_AUTOMATIC_UDLS
```
When defined, `<nlohmann/json.hpp>` does not include `<nlohmann/json_literals.hpp>`, 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
`<nlohmann/json_literals.hpp>` 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 `<nlohmann/json.hpp>` includes
`<nlohmann/json_literals.hpp>`.
```cpp
#undef JSON_NO_AUTOMATIC_UDLS
```
## Notes
!!! info "Header `<nlohmann/json_literals.hpp>`"
The header includes `<nlohmann/json.hpp>` 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 <nlohmann/json.hpp>
// this file uses the literals, so it includes them explicitly
#include <nlohmann/json_literals.hpp>
int main()
{
auto j = R"({"foo": 42})"_json;
return j.at("/foo"_json_pointer) == 42 ? 0 : 1;
}
```
Without the include of `<nlohmann/json_literals.hpp>`, 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.
@@ -15,7 +15,7 @@ The default value is `1`.
#define JSON_USE_GLOBAL_UDLS 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 ## Notes
@@ -32,6 +32,11 @@ When the macro is not defined, the library will define it to its default value.
[`JSON_GlobalUDLs`](../../integration/cmake.md#json_globaludls) (`ON` by default) which defines [`JSON_GlobalUDLs`](../../integration/cmake.md#json_globaludls) (`ON` by default) which defines
`JSON_USE_GLOBAL_UDLS` accordingly. `JSON_USE_GLOBAL_UDLS` accordingly.
!!! info "Leaving out the literals"
If [`JSON_NO_AUTOMATIC_UDLS`](json_no_automatic_udls.md) is defined, the literals are only declared where
`<nlohmann/json_literals.hpp>` is included; this macro then applies to that header.
## Examples ## Examples
??? example "Example 1: Default behavior" ??? example "Example 1: Default behavior"
@@ -92,6 +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`](../operator_literal_json.md)
- [`operator""_json_pointer`](../operator_literal_json_pointer.md) - [`operator""_json_pointer`](../operator_literal_json_pointer.md)
- [`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 - [:simple-cmake: JSON_GlobalUDLs](../../integration/cmake.md#json_globaludls) - CMake option to control the macro
## Version history ## Version history
@@ -18,7 +18,9 @@ using namespace nlohmann;
``` ```
This is suggested to ease migration to the next major version release of the library. See 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. [`JSON_USE_GLOBAL_UDLS`](macros/json_use_global_udls.md#notes) for details. The operator is declared in header
`<nlohmann/json_literals.hpp>`, which `<nlohmann/json.hpp>` includes unless
[`JSON_NO_AUTOMATIC_UDLS`](macros/json_no_automatic_udls.md) is defined.
## Parameters ## Parameters
@@ -59,6 +61,8 @@ Linear.
## See also ## See also
- [Creating JSON values](../features/creating_values.md) - the article on creating JSON values - [Creating JSON values](../features/creating_values.md) - the article on creating JSON values
- [JSON_NO_AUTOMATIC_UDLS](macros/json_no_automatic_udls.md) - do not include the user-defined string literals
automatically
## Version history ## Version history
@@ -17,7 +17,9 @@ using namespace nlohmann::literals::json_literals;
using namespace nlohmann; using namespace nlohmann;
``` ```
This is suggested to ease migration to the next major version release of the library. See 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. [`JSON_USE_GLOBAL_UDLS`](macros/json_use_global_udls.md#notes) for details. The operator is declared in header
`<nlohmann/json_literals.hpp>`, which `<nlohmann/json.hpp>` includes unless
[`JSON_NO_AUTOMATIC_UDLS`](macros/json_no_automatic_udls.md) is defined.
## Parameters ## Parameters
@@ -58,6 +60,8 @@ Linear.
## See also ## See also
- [json_pointer](json_pointer/index.md) - type to represent JSON Pointers - [json_pointer](json_pointer/index.md) - type to represent JSON Pointers
- [JSON_NO_AUTOMATIC_UDLS](macros/json_no_automatic_udls.md) - do not include the user-defined string literals
automatically
## Version history ## Version history
+9
View File
@@ -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). See [full documentation of `JSON_DISABLE_ENUM_SERIALIZATION`](../api/macros/json_disable_enum_serialization.md).
## `JSON_NO_AUTOMATIC_UDLS`
When defined, `<nlohmann/json.hpp>` does not include `<nlohmann/json_literals.hpp>` 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
`<nlohmann/json_literals.hpp>` where the literals are needed.
See [full documentation of `JSON_NO_AUTOMATIC_UDLS`](../api/macros/json_no_automatic_udls.md).
## `JSON_NO_IO` ## `JSON_NO_IO`
When defined, headers `<cstdio>`, `<ios>`, `<iosfwd>`, `<istream>`, and `<ostream>` are not included and parse functions When defined, headers `<cstdio>`, `<ios>`, `<iosfwd>`, `<istream>`, and `<ostream>` are not included and parse functions
+3
View File
@@ -40,6 +40,9 @@ Only the following symbols are exported from `nlohmann.json`:
- `nlohmann::literals::json_literals::operator""_json` - `nlohmann::literals::json_literals::operator""_json`
- `nlohmann::literals::json_literals::operator""_json_pointer` - `nlohmann::literals::json_literals::operator""_json_pointer`
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 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, ([#3970](https://github.com/nlohmann/json/issues/3970)). They are implementation details, not part of the public API,
and should not be used directly: and should not be used directly:
+4 -1
View File
@@ -15,4 +15,7 @@ Clang).
You can further use file You can further use file
[`single_include/nlohmann/json_fwd.hpp`](https://github.com/nlohmann/json/blob/develop/single_include/nlohmann/json_fwd.hpp) [`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).
+1
View File
@@ -293,6 +293,7 @@ nav:
- 'JSON_HAS_STATIC_RTTI': api/macros/json_has_static_rtti.md - 'JSON_HAS_STATIC_RTTI': api/macros/json_has_static_rtti.md
- 'JSON_HAS_STD_FORMAT': api/macros/json_has_std_format.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_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_NOEXCEPTION': api/macros/json_noexception.md
- 'JSON_NO_IO': api/macros/json_no_io.md - 'JSON_NO_IO': api/macros/json_no_io.md
- 'JSON_NO_THREAD_LOCAL': api/macros/json_no_thread_local.md - 'JSON_NO_THREAD_LOCAL': api/macros/json_no_thread_local.md
-4
View File
@@ -915,7 +915,3 @@ void templated_json_throw(ExceptionType exception)
#ifndef JSON_DISABLE_ENUM_SERIALIZATION #ifndef JSON_DISABLE_ENUM_SERIALIZATION
#define JSON_DISABLE_ENUM_SERIALIZATION 0 #define JSON_DISABLE_ENUM_SERIALIZATION 0
#endif #endif
#ifndef JSON_USE_GLOBAL_UDLS
#define JSON_USE_GLOBAL_UDLS 1
#endif
@@ -25,7 +25,6 @@
#undef JSON_INLINE_VARIABLE #undef JSON_INLINE_VARIABLE
#undef JSON_NO_UNIQUE_ADDRESS #undef JSON_NO_UNIQUE_ADDRESS
#undef JSON_DISABLE_ENUM_SERIALIZATION #undef JSON_DISABLE_ENUM_SERIALIZATION
#undef JSON_USE_GLOBAL_UDLS
#ifndef JSON_TEST_KEEP_MACROS #ifndef JSON_TEST_KEEP_MACROS
#undef JSON_CATCH #undef JSON_CATCH
+9 -60
View File
@@ -6423,55 +6423,6 @@ std::string format_as(const NLOHMANN_BASIC_JSON_TPL& j)
return j.dump(); return j.dump();
} }
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<const char*>(s),
reinterpret_cast<const char*>(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<const char*>(s), n));
}
#endif
} // namespace json_literals
} // namespace literals
NLOHMANN_JSON_NAMESPACE_END NLOHMANN_JSON_NAMESPACE_END
/////////////////////// ///////////////////////
@@ -6606,17 +6557,6 @@ struct formatter<nlohmann::NLOHMANN_BASIC_JSON_TPL, char> // NOLINT(cert-dcl58-c
} // namespace std } // namespace std
#if JSON_USE_GLOBAL_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 <nlohmann/detail/macro_unscope.hpp> #include <nlohmann/detail/macro_unscope.hpp>
// End of GCC diagnostic pragmas for C++ modules support // End of GCC diagnostic pragmas for C++ modules support
@@ -6624,4 +6564,13 @@ struct formatter<nlohmann::NLOHMANN_BASIC_JSON_TPL, char> // NOLINT(cert-dcl58-c
#pragma GCC diagnostic pop #pragma GCC diagnostic pop
#endif #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 <nlohmann/json_literals.hpp> only
// where needed.
#ifndef JSON_NO_AUTOMATIC_UDLS
// NOLINTNEXTLINE(misc-header-include-cycle): json_literals.hpp includes this header
#include <nlohmann/json_literals.hpp>
#endif
#endif // INCLUDE_NLOHMANN_JSON_HPP_ #endif // INCLUDE_NLOHMANN_JSON_HPP_
+84
View File
@@ -0,0 +1,84 @@
// __ _____ _____ _____
// __| | __| | | | JSON for Modern C++
// | | |__ | | | | | | version 3.12.0
// |_____|_____|_____|_|___| https://github.com/nlohmann/json
//
// SPDX-FileCopyrightText: 2013-2026 Niels Lohmann <https://nlohmann.me>
// SPDX-License-Identifier: MIT
#ifndef INCLUDE_NLOHMANN_JSON_LITERALS_HPP_
#define INCLUDE_NLOHMANN_JSON_LITERALS_HPP_
#include <cstddef> // size_t
#include <string> // string
// NOLINTNEXTLINE(misc-header-include-cycle): json.hpp includes this header at its end
#include <nlohmann/json.hpp>
// This header is included at the end of <nlohmann/json.hpp> 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<const char*>(s),
reinterpret_cast<const char*>(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<const char*>(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_
+1
View File
@@ -15,6 +15,7 @@ nlohmann_json_multiple_headers = declare_dependency(
if not meson.is_subproject() if not meson.is_subproject()
install_headers('single_include/nlohmann/json.hpp', subdir: 'nlohmann') 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_fwd.hpp', subdir: 'nlohmann')
install_headers('single_include/nlohmann/json_literals.hpp', subdir: 'nlohmann')
pkgc = import('pkgconfig') pkgc = import('pkgconfig')
pkgc.generate(name: 'nlohmann_json', pkgc.generate(name: 'nlohmann_json',
+95 -65
View File
@@ -3327,10 +3327,6 @@ void templated_json_throw(ExceptionType exception)
#define JSON_DISABLE_ENUM_SERIALIZATION 0 #define JSON_DISABLE_ENUM_SERIALIZATION 0
#endif #endif
#ifndef JSON_USE_GLOBAL_UDLS
#define JSON_USE_GLOBAL_UDLS 1
#endif
#if JSON_HAS_THREE_WAY_COMPARISON #if JSON_HAS_THREE_WAY_COMPARISON
#include <compare> // partial_ordering #include <compare> // partial_ordering
#endif #endif
@@ -32504,55 +32500,6 @@ std::string format_as(const NLOHMANN_BASIC_JSON_TPL& j)
return j.dump(); return j.dump();
} }
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<const char*>(s),
reinterpret_cast<const char*>(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<const char*>(s), n));
}
#endif
} // namespace json_literals
} // namespace literals
NLOHMANN_JSON_NAMESPACE_END NLOHMANN_JSON_NAMESPACE_END
/////////////////////// ///////////////////////
@@ -32687,17 +32634,6 @@ struct formatter<nlohmann::NLOHMANN_BASIC_JSON_TPL, char> // NOLINT(cert-dcl58-c
} // namespace std } // namespace std
#if JSON_USE_GLOBAL_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 <nlohmann/detail/macro_unscope.hpp> // #include <nlohmann/detail/macro_unscope.hpp>
// __ _____ _____ _____ // __ _____ _____ _____
// __| | __| | | | JSON for Modern C++ // __| | __| | | | JSON for Modern C++
@@ -32726,7 +32662,6 @@ struct formatter<nlohmann::NLOHMANN_BASIC_JSON_TPL, char> // NOLINT(cert-dcl58-c
#undef JSON_INLINE_VARIABLE #undef JSON_INLINE_VARIABLE
#undef JSON_NO_UNIQUE_ADDRESS #undef JSON_NO_UNIQUE_ADDRESS
#undef JSON_DISABLE_ENUM_SERIALIZATION #undef JSON_DISABLE_ENUM_SERIALIZATION
#undef JSON_USE_GLOBAL_UDLS
#ifndef JSON_TEST_KEEP_MACROS #ifndef JSON_TEST_KEEP_MACROS
#undef JSON_CATCH #undef JSON_CATCH
@@ -32919,4 +32854,99 @@ struct formatter<nlohmann::NLOHMANN_BASIC_JSON_TPL, char> // NOLINT(cert-dcl58-c
#pragma GCC diagnostic pop #pragma GCC diagnostic pop
#endif #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 <nlohmann/json_literals.hpp> only
// where needed.
#ifndef JSON_NO_AUTOMATIC_UDLS
// NOLINTNEXTLINE(misc-header-include-cycle): json_literals.hpp includes this header
// #include <nlohmann/json_literals.hpp>
// __ _____ _____ _____
// __| | __| | | | JSON for Modern C++
// | | |__ | | | | | | version 3.12.0
// |_____|_____|_____|_|___| https://github.com/nlohmann/json
//
// SPDX-FileCopyrightText: 2013-2026 Niels Lohmann <https://nlohmann.me>
// SPDX-License-Identifier: MIT
#ifndef INCLUDE_NLOHMANN_JSON_LITERALS_HPP_
#define INCLUDE_NLOHMANN_JSON_LITERALS_HPP_
#include <cstddef> // size_t
#include <string> // string
// NOLINTNEXTLINE(misc-header-include-cycle): json.hpp includes this header at its end
// #include <nlohmann/json.hpp>
// This header is included at the end of <nlohmann/json.hpp> 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<const char*>(s),
reinterpret_cast<const char*>(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<const char*>(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_ #endif // INCLUDE_NLOHMANN_JSON_HPP_
+84
View File
@@ -0,0 +1,84 @@
// __ _____ _____ _____
// __| | __| | | | JSON for Modern C++
// | | |__ | | | | | | version 3.12.0
// |_____|_____|_____|_|___| https://github.com/nlohmann/json
//
// SPDX-FileCopyrightText: 2013-2026 Niels Lohmann <https://nlohmann.me>
// SPDX-License-Identifier: MIT
#ifndef INCLUDE_NLOHMANN_JSON_LITERALS_HPP_
#define INCLUDE_NLOHMANN_JSON_LITERALS_HPP_
#include <cstddef> // size_t
#include <string> // string
// NOLINTNEXTLINE(misc-header-include-cycle): json.hpp includes this header at its end
#include <nlohmann/json.hpp>
// This header is included at the end of <nlohmann/json.hpp> 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<const char*>(s),
reinterpret_cast<const char*>(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<const char*>(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_
+1
View File
@@ -18,6 +18,7 @@ module;
// See: https://github.com/nlohmann/json/issues/5103 // See: https://github.com/nlohmann/json/issues/5103
#include <nlohmann/json.hpp> #include <nlohmann/json.hpp>
#include <nlohmann/json_literals.hpp>
export module nlohmann.json; export module nlohmann.json;
+108
View File
@@ -0,0 +1,108 @@
// __ _____ _____ _____
// __| | __| | | | JSON for Modern C++ (supporting code)
// | | |__ | | | | | | version 3.12.0
// |_____|_____|_____|_|___| https://github.com/nlohmann/json
//
// SPDX-FileCopyrightText: 2013-2026 Niels Lohmann <https://nlohmann.me>
// SPDX-License-Identifier: MIT
// This translation unit checks JSON_NO_AUTOMATIC_UDLS, which keeps
// <nlohmann/json.hpp> from including <nlohmann/json_literals.hpp> and thereby
// leaves out the user-defined string literals operator""_json and
// operator""_json_pointer (see #5294), and that including
// <nlohmann/json_literals.hpp> afterwards brings them back.
#define JSON_NO_AUTOMATIC_UDLS 1
#include "doctest_compatibility.h"
#include <cstddef>
#include <utility>
#include <nlohmann/json.hpp>
using json = nlohmann::json;
// An argument type whose associated namespace is the library namespace, so
// 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_automatic_udls_probe
{
operator const char* () const // NOLINT(google-explicit-constructor,hicpp-explicit-conversions)
{
return "";
}
};
NLOHMANN_JSON_NAMESPACE_END
namespace
{
// The calls below use a dependent argument, so a literal operator that is not
// declared at all is a substitution failure rather than a hard error: lookup is
// deferred to the point of instantiation, where it considers the declarations
// visible from here (the global using-declarations of JSON_USE_GLOBAL_UDLS) plus
// argument-dependent lookup (the literals in the library namespace).
#if !defined(__GNUC__) || defined(__clang__) || __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 9)
template<typename T>
using json_udl_t = decltype(operator""_json(std::declval<T>(), std::size_t()));
template<typename T>
using json_pointer_udl_t = decltype(operator""_json_pointer(std::declval<T>(), std::size_t()));
#else
// GCC 4.8 requires a space between "" and suffix
template<typename T>
using json_udl_t = decltype(operator"" _json(std::declval<T>(), std::size_t()));
template<typename T>
using json_pointer_udl_t = decltype(operator"" _json_pointer(std::declval<T>(), std::size_t()));
#endif
template<typename T>
using has_json_udl = nlohmann::detail::is_detected<json_udl_t, T>;
template<typename T>
using has_json_pointer_udl = nlohmann::detail::is_detected<json_pointer_udl_t, T>;
} // namespace
TEST_CASE("JSON_NO_AUTOMATIC_UDLS")
{
SECTION("literals are not declared")
{
// global namespace (JSON_USE_GLOBAL_UDLS defaults to 1)
CHECK_FALSE(has_json_udl<const char*>::value);
CHECK_FALSE(has_json_pointer_udl<const char*>::value);
// nlohmann::literals::json_literals
CHECK_FALSE(has_json_udl<nlohmann::no_automatic_udls_probe>::value);
CHECK_FALSE(has_json_pointer_udl<nlohmann::no_automatic_udls_probe>::value);
}
SECTION("the rest of the library keeps working")
{
const json j = json::parse(R"({"foo": {"bar": 42}})");
CHECK(j.dump() == R"({"foo":{"bar":42}})");
const json::json_pointer ptr("/foo/bar");
CHECK(j.at(ptr) == 42);
CHECK(j.contains(ptr));
}
}
// the literals can still be added where they are needed
#include <nlohmann/json_literals.hpp>
TEST_CASE("JSON_NO_AUTOMATIC_UDLS with <nlohmann/json_literals.hpp>")
{
#if !defined(JSON_USE_GLOBAL_UDLS) || JSON_USE_GLOBAL_UDLS
SECTION("global namespace")
{
CHECK("[1,2]"_json == json({1, 2}));
CHECK("/a/0"_json_pointer == json::json_pointer("/a/0"));
}
#endif
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);
}
}