From 3a04f785078e224c318a3c70e246351b09f26367 Mon Sep 17 00:00:00 2001 From: Niels Lohmann Date: Wed, 30 Sep 2026 21:31:58 +0200 Subject: [PATCH] Make convert_null_to() take the container type as a template argument Passing array_t or object_t instead of a value_t makes an invalid target a compile error instead of a runtime assertion, and removes the branch. Signed-off-by: Niels Lohmann --- include/nlohmann/json.hpp | 49 ++++++++++++++++++-------------- single_include/nlohmann/json.hpp | 49 ++++++++++++++++++-------------- 2 files changed, 56 insertions(+), 42 deletions(-) diff --git a/include/nlohmann/json.hpp b/include/nlohmann/json.hpp index 8e91cd4d8..1bec188df 100644 --- a/include/nlohmann/json.hpp +++ b/include/nlohmann/json.hpp @@ -2741,26 +2741,33 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec return (*j.m_data.m_value.array)[idx]; } - /// @brief convert a null value to an empty container of type @a t (array or object) - void convert_null_to(value_t t) + /// @brief convert a null value to an empty container of type @a Container + /// @tparam Container array_t or object_t; any other type does not compile + template + void convert_null_to() { JSON_ASSERT(is_null()); - JSON_ASSERT(t == value_t::array || t == value_t::object); // create the container before touching the type, so a throwing // allocation leaves this value as a valid null rather than a type // tag with a dangling/null pointer behind it - if (t == value_t::array) - { - m_data.m_value.array = create(); - } - else - { - m_data.m_value.object = create(); - } - m_data.m_type = t; + set_container(create()); assert_invariant(); } + /// @brief store a freshly created array and set the matching type + void set_container(array_t* array) noexcept + { + m_data.m_value.array = array; + m_data.m_type = value_t::array; + } + + /// @brief store a freshly created object and set the matching type + void set_container(object_t* object) noexcept + { + m_data.m_value.object = object; + m_data.m_type = value_t::object; + } + public: //////////////////// // element access // @@ -2823,7 +2830,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec // implicitly convert a null value to an empty array if (is_null()) { - convert_null_to(value_t::array); + convert_null_to(); } // operator[] only works for arrays @@ -2881,7 +2888,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec // implicitly convert a null value to an empty object if (is_null()) { - convert_null_to(value_t::object); + convert_null_to(); } // operator[] only works for objects @@ -2932,7 +2939,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec // implicitly convert a null value to an empty object if (is_null()) { - convert_null_to(value_t::object); + convert_null_to(); } // operator[] only works for objects @@ -3804,7 +3811,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec // transform a null object into an array if (is_null()) { - convert_null_to(value_t::array); + convert_null_to(); } // add the element to the array (move semantics) @@ -3835,7 +3842,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec // transform a null object into an array if (is_null()) { - convert_null_to(value_t::array); + convert_null_to(); } // add the element to the array @@ -3865,7 +3872,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec // transform a null object into an object if (is_null()) { - convert_null_to(value_t::object); + convert_null_to(); } // add the element to the object @@ -3919,7 +3926,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec // transform a null object into an array if (is_null()) { - convert_null_to(value_t::array); + convert_null_to(); } // add the element to the array (perfect forwarding) @@ -3942,7 +3949,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec // transform a null object into an object if (is_null()) { - convert_null_to(value_t::object); + convert_null_to(); } // add the element to the array (perfect forwarding) @@ -4137,7 +4144,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec // implicitly convert a null value to an empty object if (is_null()) { - convert_null_to(value_t::object); + convert_null_to(); } if (JSON_HEDLEY_UNLIKELY(!is_object())) diff --git a/single_include/nlohmann/json.hpp b/single_include/nlohmann/json.hpp index 288163777..87367bfd6 100644 --- a/single_include/nlohmann/json.hpp +++ b/single_include/nlohmann/json.hpp @@ -28775,26 +28775,33 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec return (*j.m_data.m_value.array)[idx]; } - /// @brief convert a null value to an empty container of type @a t (array or object) - void convert_null_to(value_t t) + /// @brief convert a null value to an empty container of type @a Container + /// @tparam Container array_t or object_t; any other type does not compile + template + void convert_null_to() { JSON_ASSERT(is_null()); - JSON_ASSERT(t == value_t::array || t == value_t::object); // create the container before touching the type, so a throwing // allocation leaves this value as a valid null rather than a type // tag with a dangling/null pointer behind it - if (t == value_t::array) - { - m_data.m_value.array = create(); - } - else - { - m_data.m_value.object = create(); - } - m_data.m_type = t; + set_container(create()); assert_invariant(); } + /// @brief store a freshly created array and set the matching type + void set_container(array_t* array) noexcept + { + m_data.m_value.array = array; + m_data.m_type = value_t::array; + } + + /// @brief store a freshly created object and set the matching type + void set_container(object_t* object) noexcept + { + m_data.m_value.object = object; + m_data.m_type = value_t::object; + } + public: //////////////////// // element access // @@ -28857,7 +28864,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec // implicitly convert a null value to an empty array if (is_null()) { - convert_null_to(value_t::array); + convert_null_to(); } // operator[] only works for arrays @@ -28915,7 +28922,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec // implicitly convert a null value to an empty object if (is_null()) { - convert_null_to(value_t::object); + convert_null_to(); } // operator[] only works for objects @@ -28966,7 +28973,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec // implicitly convert a null value to an empty object if (is_null()) { - convert_null_to(value_t::object); + convert_null_to(); } // operator[] only works for objects @@ -29838,7 +29845,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec // transform a null object into an array if (is_null()) { - convert_null_to(value_t::array); + convert_null_to(); } // add the element to the array (move semantics) @@ -29869,7 +29876,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec // transform a null object into an array if (is_null()) { - convert_null_to(value_t::array); + convert_null_to(); } // add the element to the array @@ -29899,7 +29906,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec // transform a null object into an object if (is_null()) { - convert_null_to(value_t::object); + convert_null_to(); } // add the element to the object @@ -29953,7 +29960,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec // transform a null object into an array if (is_null()) { - convert_null_to(value_t::array); + convert_null_to(); } // add the element to the array (perfect forwarding) @@ -29976,7 +29983,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec // transform a null object into an object if (is_null()) { - convert_null_to(value_t::object); + convert_null_to(); } // add the element to the array (perfect forwarding) @@ -30171,7 +30178,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec // implicitly convert a null value to an empty object if (is_null()) { - convert_null_to(value_t::object); + convert_null_to(); } if (JSON_HEDLEY_UNLIKELY(!is_object()))