From a9cc4243b7004b5f540f0b52cb6cde1501227f61 Mon Sep 17 00:00:00 2001 From: Niels Lohmann Date: Wed, 30 Sep 2026 09:54:59 +0200 Subject: [PATCH] Fix tautological clause in iter_impl's iterator category assertion The static_assert meant to check the LegacyBidirectionalIterator named requirement had a first clause comparing std::bidirectional_iterator_tag to itself, which is always true and checks nothing; only array_t::iterator was actually being checked, despite the message claiming object iterators were checked too. Drop the tautological clause, reword the message to describe what is actually checked, and note that object_t may use a forward-only iterator as long as reverse iteration and operator-- are unused. The check is intentionally not extended to object_t::iterator, since that would reject object types with forward-only iterators that compile and work correctly today. Part of #5708 Signed-off-by: Niels Lohmann --- include/nlohmann/detail/iterators/iter_impl.hpp | 8 +++++--- single_include/nlohmann/json.hpp | 8 +++++--- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/include/nlohmann/detail/iterators/iter_impl.hpp b/include/nlohmann/detail/iterators/iter_impl.hpp index 22f3ffc39..5f5b6aa0f 100644 --- a/include/nlohmann/detail/iterators/iter_impl.hpp +++ b/include/nlohmann/detail/iterators/iter_impl.hpp @@ -60,9 +60,11 @@ class iter_impl // NOLINT(cppcoreguidelines-special-member-functions,hicpp-speci static_assert(is_basic_json::type>::value, "iter_impl only accepts (const) basic_json"); // superficial check for the LegacyBidirectionalIterator named requirement - static_assert(std::is_base_of::value - && std::is_base_of::iterator_category>::value, - "basic_json iterator assumes array and object type iterators satisfy the LegacyBidirectionalIterator named requirement."); + // note: only array_t::iterator is checked here; object_t::iterator may be + // a forward-only iterator as long as reverse iteration and operator-- + // are never used on it + static_assert(std::is_base_of::iterator_category>::value, + "basic_json iterator assumes array type iterators satisfy the LegacyBidirectionalIterator named requirement."); public: /// The std::iterator class template (used as a base class to provide typedefs) is deprecated in C++17. diff --git a/single_include/nlohmann/json.hpp b/single_include/nlohmann/json.hpp index 897059240..4a5c032f4 100644 --- a/single_include/nlohmann/json.hpp +++ b/single_include/nlohmann/json.hpp @@ -17811,9 +17811,11 @@ class iter_impl // NOLINT(cppcoreguidelines-special-member-functions,hicpp-speci static_assert(is_basic_json::type>::value, "iter_impl only accepts (const) basic_json"); // superficial check for the LegacyBidirectionalIterator named requirement - static_assert(std::is_base_of::value - && std::is_base_of::iterator_category>::value, - "basic_json iterator assumes array and object type iterators satisfy the LegacyBidirectionalIterator named requirement."); + // note: only array_t::iterator is checked here; object_t::iterator may be + // a forward-only iterator as long as reverse iteration and operator-- + // are never used on it + static_assert(std::is_base_of::iterator_category>::value, + "basic_json iterator assumes array type iterators satisfy the LegacyBidirectionalIterator named requirement."); public: /// The std::iterator class template (used as a base class to provide typedefs) is deprecated in C++17.