// __ _____ _____ _____ // __| | __| | | | JSON for Modern C++ (supporting code) // | | |__ | | | | | | version 3.12.0 // |_____|_____|_____|_|___| https://github.com/nlohmann/json // // SPDX-FileCopyrightText: 2013-2026 Niels Lohmann // SPDX-License-Identifier: MIT // 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" #include #include #include 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 using json_udl_t = decltype(operator""_json(std::declval(), std::size_t())); template using json_pointer_udl_t = decltype(operator""_json_pointer(std::declval(), std::size_t())); #else // GCC 4.8 requires a space between "" and suffix template using json_udl_t = decltype(operator"" _json(std::declval(), std::size_t())); template using json_pointer_udl_t = decltype(operator"" _json_pointer(std::declval(), std::size_t())); #endif template using has_json_udl = nlohmann::detail::is_detected; template using has_json_pointer_udl = nlohmann::detail::is_detected; } // 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::value); CHECK_FALSE(has_json_pointer_udl::value); // nlohmann::literals::json_literals CHECK_FALSE(has_json_udl::value); CHECK_FALSE(has_json_pointer_udl::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 TEST_CASE("JSON_NO_AUTOMATIC_UDLS with ") { #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); } }