From ae9ef9dde12d0c760d0670881ad5ef263939dddb Mon Sep 17 00:00:00 2001 From: Niels Lohmann Date: Wed, 30 Sep 2026 09:50:52 +0200 Subject: [PATCH] Simplify is_ordered_map to reuse has_capacity is_ordered_map re-detected capacity() with a C++03 sizeof/vararg trick right after has_capacity did the same detection through is_detected. For ordered_map, the old trick took the address of std::vector::capacity, which [namespace.std]/6 makes unspecified. Reuse has_capacity instead, which removes the unspecified-behavior pointer-to-std-member and two NOLINT suppressions. Part of #5708 Signed-off-by: Niels Lohmann --- include/nlohmann/detail/meta/type_traits.hpp | 15 +-------------- single_include/nlohmann/json.hpp | 15 +-------------- tests/src/unit-type_traits.cpp | 12 ++++++++++++ 3 files changed, 14 insertions(+), 28 deletions(-) diff --git a/include/nlohmann/detail/meta/type_traits.hpp b/include/nlohmann/detail/meta/type_traits.hpp index d6615609c..71f2f09fa 100644 --- a/include/nlohmann/detail/meta/type_traits.hpp +++ b/include/nlohmann/detail/meta/type_traits.hpp @@ -805,20 +805,7 @@ struct has_capacity : std::integral_constant -struct is_ordered_map -{ - using one = char; - - struct two - { - char x[2]; // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays) - }; - - template static one test( decltype(&C::capacity) ) ; - template static two test(...); - - enum { value = sizeof(test(nullptr)) == sizeof(char) }; // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg,cppcoreguidelines-use-enum-class) -}; +struct is_ordered_map : has_capacity {}; // to avoid useless casts (see https://github.com/nlohmann/json/issues/2893#issuecomment-889152324) template < typename T, typename U, enable_if_t < !std::is_same::value, int > = 0 > diff --git a/single_include/nlohmann/json.hpp b/single_include/nlohmann/json.hpp index dbf938453..226673d51 100644 --- a/single_include/nlohmann/json.hpp +++ b/single_include/nlohmann/json.hpp @@ -4785,20 +4785,7 @@ struct has_capacity : std::integral_constant -struct is_ordered_map -{ - using one = char; - - struct two - { - char x[2]; // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays) - }; - - template static one test( decltype(&C::capacity) ) ; - template static two test(...); - - enum { value = sizeof(test(nullptr)) == sizeof(char) }; // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg,cppcoreguidelines-use-enum-class) -}; +struct is_ordered_map : has_capacity {}; // to avoid useless casts (see https://github.com/nlohmann/json/issues/2893#issuecomment-889152324) template < typename T, typename U, enable_if_t < !std::is_same::value, int > = 0 > diff --git a/tests/src/unit-type_traits.cpp b/tests/src/unit-type_traits.cpp index 6dc166d03..a3937bf2e 100644 --- a/tests/src/unit-type_traits.cpp +++ b/tests/src/unit-type_traits.cpp @@ -10,10 +10,14 @@ #if JSON_TEST_USING_MULTIPLE_HEADERS #include + #include #else #include #endif +#include +#include + TEST_CASE("type traits") { SECTION("is_c_string") @@ -83,4 +87,12 @@ TEST_CASE("type traits") } } } + + SECTION("is_ordered_map") + { + using nlohmann::detail::is_ordered_map; + + CHECK(is_ordered_map>::value); + CHECK_FALSE(is_ordered_map>::value); + } }