Repository navigation
Conversation
Defining JSON_DELETE_DEPRECATED_FUNCTIONS to 1 (or the CMake option JSON_DeleteDeprecatedFunctions) declares every deprecated function as deleted instead of deprecated, so that code that is not ready for 4.0.0 no longer compiles. A deleted function still takes part in overload resolution, so from_*(ptr, len) cannot silently bind len to the strict parameter of from_*(InputType&&, bool); the roadmap now plans to keep these overloads deleted in 4.0.0 instead of removing them. The legacy discarded-value comparison is left to its own macro. Also update the 4.0 roadmap: add JSON_DISABLE_TUPLE_REFERENCE_CONVERSION and JSON_DELETE_DEPRECATED_FUNCTIONS to the macro table, add the from_bjdata/from_bon8 (ptr, len) overloads to the deprecated functions, document the macro in the migration guide, and fix the docs style check findings (example titles, missing docset entry for JSON_STRICT_BINARY_UTF8). Signed-off-by: Niels Lohmann <mail@nlohmann.me>
🔴 Amalgamation check failed! 🔴The source code has not been amalgamated and/or formatted correctly, or 📎 A ready-to-apply patch is attached to the failed workflow run as the git apply amalgamation.patchThis does not require installing astyle yourself. |
…5648' into HEAD Signed-off-by: Niels Lohmann <mail@nlohmann.me> # Conflicts: # docs/mkdocs/docs/api/macros/json_use_implicit_conversions.md
| /// @sa https://json.nlohmann.me/api/json_pointer/operator_string_t/ | ||
| #if JSON_DELETE_DEPRECATED_FUNCTIONS | ||
| operator string_t() const = delete; | ||
| #else |
There was a problem hiding this comment.
I wonder if this can avoid duplicating the declaration:
#if JSON_DELETE_DEPRECATED_FUNCTIONS
#define JSON_DELETE_DEPRECATED_FUNCTIONS_DEPRECATED(ver, func)
#define JSON_DELETE_DEPRECATED_FUNCTIONS_DELETE = delete
#else
#define JSON_DELETE_DEPRECATED_FUNCTIONS_DEPRECATED(ver, func) JSON_HEDLEY_DEPRECATED_FOR(ver, func)
#define JSON_DELETE_DEPRECATED_FUNCTIONS_DELETE
#endif
JSON_DELETE_DEPRECATED_FUNCTIONS_DEPRECATED(3.11.0, to_string())
operator string_t() const
JSON_DELETE_DEPRECATED_FUNCTIONS_DELETE()
{
return to_string();
}
Still has the body, which would need guarding as well, but I have to run now.
There was a problem hiding this comment.
Thanks, good point. I went with a slightly simpler variant in fe5bc3d: no new macros, and each declaration (with its deprecation attribute) appears only once. Only the end of the function is switched:
JSON_HEDLEY_DEPRECATED_FOR(3.11.0, to_string())
operator string_t() const
#if JSON_DELETE_DEPRECATED_FUNCTIONS
= delete;
#else
{
return to_string();
}
#endifPassing the body as a macro argument would have broken bodies with // NOLINTNEXTLINE comments (e.g., sax_parse), and keeping the deprecation attribute on a deleted function is allowed. The unit-delete_deprecated_functions test passes with the macro set to 0 and 1 (clang, GCC 15).
(Written by Claude Code.)
There was a problem hiding this comment.
I wasn't sure if you'd want to keep the JSON_HEDLEY_DEPRECATED_FOR around for things beyond 4.0.0. Otherwise I'm fine with this.
There was a problem hiding this comment.
I thought about this as well, and kicked the can down the road. Let's see how much more will add up and decide then.
Instead of repeating every deprecated declaration in an #if JSON_DELETE_DEPRECATED_FUNCTIONS branch, keep one declaration (with its deprecation attribute) and switch only between "= delete;" and the function body. Suggested by @gregmarr in the review. Signed-off-by: Niels Lohmann <mail@nlohmann.me>
…e-deprecated-functions Signed-off-by: Niels Lohmann <mail@nlohmann.me>
MSVC 2015 does not treat selecting a deleted function in decltype as a substitution failure, so the detection traits in unit-delete_deprecated_functions (#5755) and the integral-key checks in unit-element_access2 (#5657) report deleted overloads as callable there. Calling them still fails to compile. Skip those checks for _MSC_VER < 1910, and use the stream operators for real in the runtime section, so MSVC 2015 still compiles them with the macro set. Signed-off-by: Niels Lohmann <mail@nlohmann.me>
* Fix CI on develop after #5600, #5607, and #5755 - binary_reader: cast the result of -1 - number back to number_integer_t, because a number_integer_t narrower than int is promoted to int, which GCC's -Warith-conversion rejects (ci_test_gcc, ci_test_standards_gcc) - JSON_DELETE_DEPRECATED_FUNCTIONS: declare the deleted stream operators as function templates at namespace scope, because GCC < 5 rejects deleted friend functions ("can't initialize friend function") and Clang 7-9 report a redefinition when a class template has a deleted friend function - docs: give the examples of JSON_USE_OBJECTS_FOR_ENUM_KEYED_MAPS "Example:" titles and add the page to the docset (style_check) Signed-off-by: Niels Lohmann <mail@nlohmann.me> * Ignore libstdc++'s <format> sign change in the sanitizer job libstdc++ 14's <format> initializes a size_t parameter with -1 (GCC bug 119429), so every std::format call fails ci_test_clang_sanitizer under -fsanitize=integer (test-std-format_cpp20). Exclude only the implicit-integer-sign-change check and only that header via -fsanitize-ignorelist. Signed-off-by: Niels Lohmann <mail@nlohmann.me> * Fix the AppVeyor (MSVC 2015-2019) build - binary_reader: emit_signed/emit_unsigned pass integers that do not fit the number types to emit_float as long double, because MSVC's <cmath> has no integer overloads of std::isfinite (C2668 'fpclassify'), from #5607 - scalar comparisons: the friend operators take the JSON type for their noexcept from their parameter, because MSVC 2015/2017 take basic_json as the class template there (C3203) and MSVC 2019 16.0 does not see member types or template parameters, from #5751 - unit-conversions2: skip the !is_nothrow_constructible static_assert for std::optional on MSVC 2017, which evaluates the conditional noexcept as true (C2607), from #5754 Signed-off-by: Niels Lohmann <mail@nlohmann.me> * Re-amalgamate Signed-off-by: Niels Lohmann <mail@nlohmann.me> * Avoid MSVC 2015's C4800 for enums with underlying type bool MSVC 2015 warns about any conversion to bool (C4800), even with an explicit cast, so the enum conversions from #5754 (#5671) failed the AppVeyor build with /WX. Convert to bool by comparing with zero via the new detail::bool_aware_static_cast, and keep doctest from printing the enum in the test. Signed-off-by: Niels Lohmann <mail@nlohmann.me> * Skip the #5650 allocator test on MSVC 2015 debug builds MSVC 2015's debug STL constructs the containers' debug proxies through the allocator in noexcept constructors, so countdown_allocator's failing construction crashes test-allocator (SIGSEGV) instead of throwing std::bad_alloc. Use the guard #5585 uses for the same reason. Signed-off-by: Niels Lohmann <mail@nlohmann.me> * Skip deleted-function detection checks on MSVC 2015 MSVC 2015 does not treat selecting a deleted function in decltype as a substitution failure, so the detection traits in unit-delete_deprecated_functions (#5755) and the integral-key checks in unit-element_access2 (#5657) report deleted overloads as callable there. Calling them still fails to compile. Skip those checks for _MSC_VER < 1910, and use the stream operators for real in the runtime section, so MSVC 2015 still compiles them with the macro set. Signed-off-by: Niels Lohmann <mail@nlohmann.me> * Split the Visual Studio 2017 AppVeyor jobs in two The VS 2017 jobs hit AppVeyor's 60-minute limit per job while still compiling the tests (77 of about 108 test targets after 58 minutes). They pass /std:c++17 for everything anyway, so build only the C++17 variant of each test (JSON_TestStandards=17), and split the unit test files across two jobs each with the new JSON_TestShard=<index>/<count> option, which keeps every <count>-th test file starting at <index>. The extra variants of single test files are built in shard 0 only. CMAKE_OPTIONS is no longer quoted in appveyor.yml, so that it can hold more than one option. Signed-off-by: Niels Lohmann <mail@nlohmann.me> * Fix std::terminate when converting std::optional with MSVC 2017 MSVC 2017 evaluates std::is_nothrow_assignable<json&, const T&> as true even if T's to_json throws, so to_json(json&, const std::optional<T>&) was noexcept there and the exception from #5642's test called std::terminate instead of propagating. Make that conversion never noexcept on MSVC 2017; all other compilers keep the exact condition. The static_asserts on the condition are skipped for MSVC 2017; the runtime check that the exception propagates still runs there. Signed-off-by: Niels Lohmann <mail@nlohmann.me> --------- Signed-off-by: Niels Lohmann <mail@nlohmann.me>
JSON_StrictBinaryUTF8 (#5741) and JSON_DeleteDeprecatedFunctions (#5755) arrived with develop but were missing from the Meson build and the pkg-config file, so check_build_options failed. Both Meson options default to false and add JSON_STRICT_BINARY_UTF8=1 and JSON_DELETE_DEPRECATED_FUNCTIONS=1 to the dependency, the pkg-config file, and the generated CMake target; CMake's pkg-config file now carries both definitions too. The ci_meson_install job sets and checks them in its non-default install. Signed-off-by: Niels Lohmann <mail@nlohmann.me>
JSON_StrictBinaryUTF8 (#5741) and JSON_DeleteDeprecatedFunctions (#5755) arrived with develop but were missing from the Meson build and the pkg-config file, so check_build_options failed. Both Meson options default to false and add JSON_STRICT_BINARY_UTF8=1 and JSON_DELETE_DEPRECATED_FUNCTIONS=1 to the dependency, the pkg-config file, and the generated CMake target; CMake's pkg-config file now carries both definitions too. The ci_meson_install job sets and checks them in its non-default install. Signed-off-by: Niels Lohmann <mail@nlohmann.me>
…5587) * Install CMake package config files with Meson, and add Meson options Squashed onto develop from: - Install CMake package config files with Meson - meson: Indent code inside an if block - meson: set a minimum Meson version - meson: use `override_dependency()` to set dependencies - meson: use `install_subdir` for headers - meson: set the C++ standard to C++11 - meson: handle single header and multiheader the same way CMake does - meson: add support for the GlobalUDLs option - meson: add support for the ImplictConversions option - Add meson information to FILES.md - Complete the Meson options and match CMake's compile definitions - Add the JSON_* definitions to the CMake pkg-config file - Document the Meson options and check them in CI - Fix the Meson CMake target for includedir or datadir outside the prefix - Avoid //include in Meson-generated CMake target for prefix / - Add DisableTupleReferenceConversion to Meson and the CMake pkg-config file - Check in CI that Meson and pkg-config offer the CMake options - Remove accidentally committed Python bytecode Co-authored-by: Dylan Baker <dylan@pnwbakers.com> Signed-off-by: Dylan Baker <dylan@pnwbakers.com> Signed-off-by: Niels Lohmann <mail@nlohmann.me> * Add the StrictBinaryUTF8 and DeleteDeprecatedFunctions Meson options JSON_StrictBinaryUTF8 (#5741) and JSON_DeleteDeprecatedFunctions (#5755) arrived with develop but were missing from the Meson build and the pkg-config file, so check_build_options failed. Both Meson options default to false and add JSON_STRICT_BINARY_UTF8=1 and JSON_DELETE_DEPRECATED_FUNCTIONS=1 to the dependency, the pkg-config file, and the generated CMake target; CMake's pkg-config file now carries both definitions too. The ci_meson_install job sets and checks them in its non-default install. Signed-off-by: Niels Lohmann <mail@nlohmann.me> --------- Signed-off-by: Dylan Baker <dylan@pnwbakers.com> Signed-off-by: Niels Lohmann <mail@nlohmann.me> Co-authored-by: Dylan Baker <dylan@pnwbakers.com>
Adds an opt-in macro
JSON_DELETE_DEPRECATED_FUNCTIONS, with the CMake optionJSON_DeleteDeprecatedFunctions. When it is defined to1, every deprecated function is declared= deleteinstead ofJSON_HEDLEY_DEPRECATED_FOR. Code that is not ready for 4.0.0 then stops compiling, even if deprecation warnings are switched off. This follows the "try 4.0 today" approach from the roadmap (#5593).This came out of @gregmarr's review of #5688 (comment). A deleted function, unlike a removed one, still takes part in overload resolution. So with the macro,
from_cbor(ptr, len)is a hard error ("call to deleted function"). With the overload removed, the call would still compile: it would bindlentobool strictand readptras a NUL-terminated string. For the same reason, the roadmap now plans to keep thefrom_*(ptr, len)overloads deleted in 4.0.0 instead of removing them.Changes
Library: the 30 deprecated functions in
json.hppandjson_pointer.hppeach get an#if JSON_DELETE_DEPRECATED_FUNCTIONSbranch that declares them deleted. The parameter list and default arguments stay the same, so the deleted overload is still selected wherever the deprecated one would have been. This covers:from_cbor,from_msgpack,from_ubjson,from_bjdata,from_bon8,from_bsonwith(ptr, len), and the first four plusfrom_bsonwith an initializer listparse,accept,sax_parsewith an initializer listiterator_wrapperj << isandj >> osjson_pointer::operator string_tjson_pointerwith a stringvalue,contains,operator[],attaking ajson_pointer<basic_json>The legacy discarded-value comparison keeps its own macro (
JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON). The new macro gets no ABI tag: it changes no layout and no behavior, it only turns calls that compile into calls that don't (the same asJSON_USE_IMPLICIT_CONVERSIONS).Tests:
unit-delete_deprecated_functions.cppdefines the macro itself. Using SFINAE traits, it checks that each of the 32 deprecated calls is ill-formed and that the replacements still compile. I checked that all 32 checks flip when the macro is0, so they are not trivially false.json.hpp, the same way as forJSON_STRICT_NUL_HANDLING, and skip those calls when it is set.unit-regression2's [json.exception.type_error.317] cannot serialize binary data to text JSON #2067 test and the "preserve state after parsing" stream test.CI: new target
ci_test_delete_deprecated_functionsinci_cmake_options. The CMake option is also added to theci_cmake_flagschecks.Docs:
JSON_DELETE_DEPRECATED_FUNCTIONSand the previously missingJSON_DISABLE_TUPLE_REFERENCE_CONVERSION(Add JSON_DISABLE_TUPLE_REFERENCE_CONVERSION to fix std::tuple conversions #5598) to the macro table and the#defineblock.(ptr, len)overloads stay deleted.from_bjdata/from_bon8(ptr, len)overloads from Add deprecated from_bon8/from_bjdata(ptr, len) overloads #5688 to the deprecated functions.from_bjdata/from_bon8overloads.JSON_DISABLE_TUPLE_REFERENCE_CONVERSION's version history now says it is planned to become the default in 4.0.0.check_structure.pyon develop: example titles on theJSON_STRICT_BINARY_UTF8andJSON_USE_IMPLICIT_CONVERSIONSpages, and the missing docset entry forJSON_STRICT_BINARY_UTF8.Stacked on #5688, because it also deletes the new
from_bjdata/from_bon8overloads.Testing
-DJSON_DeleteDeprecatedFunctions=ON: all tests pass excepttest-alt-string, which fails to build on develop itself (fixed in Fix CI on develop after merging the ready-to-merge PRs #5754).unit-delete_deprecated_functionspasses at C++11, 14, 17, and 20.mkdocs build --strictandcheck_structure.pypass.Public API
No breaking changes. The macro defaults to
0, which keeps everything as it is. With1, calls to deprecated functions fail to compile, which is the purpose of the opt-in.This PR was written by Claude Code.
🤖 Generated with Claude Code