fix(json): add missing iterator traits to Value iterators

json::ValueConstIterator and ValueIterator declared difference_type,
reference and pointer but not value_type or iterator_category. Under
C++23, std::iterator_traits then classifies them as output iterators,
so std::all_of over a Value's members (isValidJson2 in RPCCall.cpp)
fails to instantiate on GCC 13/14 with:
  cannot convert 'output_iterator_tag' to 'std::input_iterator_tag'

GCC 15 masks this via LWG-3798/P2609, but the perf CI image ships
GCC 13, so the source needs the traits regardless. The iterators wrap
a std::map iterator (++/-- only), so the category is bidirectional.

Add value_type + iterator_category to both iterators, include <iterator>,
and add a regression test asserting the traits and that std::all_of /
std::count_if compile and run over Value members.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Pratik Mankawde
2026-07-24 15:05:51 +01:00
parent 6bfc25ddf9
commit a050e0fae6
2 changed files with 51 additions and 0 deletions

View File

@@ -4,6 +4,7 @@
#include <xrpl/json/json_forwards.h>
#include <cstring>
#include <iterator>
#include <limits>
#include <map>
#include <string>
@@ -623,6 +624,12 @@ class ValueConstIterator : public ValueIteratorBase
public:
using size_t = unsigned int;
using difference_type = int;
// std::iterator_traits needs value_type and iterator_category to classify
// this as a Cpp17InputIterator; without them it defaults to output-only,
// which breaks standard algorithms (e.g. std::all_of). The iterator walks a
// map both ways via ++/--, so it is bidirectional.
using value_type = Value;
using iterator_category = std::bidirectional_iterator_tag;
using reference = Value const&;
using pointer = Value const*;
using SelfType = ValueConstIterator;
@@ -687,6 +694,10 @@ class ValueIterator : public ValueIteratorBase
public:
using size_t = unsigned int;
using difference_type = int;
// See ValueConstIterator: value_type and iterator_category are required for
// std::iterator_traits to treat this as a bidirectional iterator.
using value_type = Value;
using iterator_category = std::bidirectional_iterator_tag;
using reference = Value&;
using pointer = Value*;
using SelfType = ValueIterator;