Relax the ArrayType and ObjectType requirements

Two requirements forced users of otherwise suitable containers to write a
wrapper, and neither was load-bearing.

array_t::capacity() was read in push_back(), emplace_back(), operator+=(), and
operator[](size_type), but set_parent() only looks at the value under
JSON_DIAGNOSTICS; without diagnostics it was computed and discarded. Read it
through array_capacity(), which reports unknown_size() when diagnostics are off
or when the array type has no capacity() at all, and treat an unknown capacity
as "the elements may have moved" so the parent pointers are refreshed
conservatively. std::deque now works as ArrayType, in both builds, and
capacity() is no longer named at all in a default build. Since the capacity is
now only meaningful for array insertions, it moves out of set_parent() into
set_parent_after_array_insert().

basic_json::erase(iterator) assigned the object's erase() return value, which
requires the container to return the following iterator. Abseil's hash maps
return void to avoid computing a successor the caller may not need. Detect that
and compute the successor before erasing; containers that return an iterator,
including the vector-backed ordered_map where a precomputed successor would be
wrong, keep the existing path.

Together these leave an Abseil hash map needing only an alias that restores the
template argument order, and no adapter at all for std::deque.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018hxZxz8svM54c6ATEvXp5E
Signed-off-by: Niels Lohmann <mail@nlohmann.me>
This commit is contained in:
Niels Lohmann
2026-08-28 17:38:56 +00:00
co-authored by Claude Opus 5
parent 96806af2dc
commit 5d93f35463
8 changed files with 344 additions and 79 deletions
+4 -3
View File
@@ -14,9 +14,9 @@ To store objects in C++, a type is defined by the template parameters explained
## Template parameters
`ArrayType`
: container type to store arrays. It must be a vector-like container: the library uses `operator[]`, `at()`,
`resize()`, and `capacity()`, and requires random-access iterators. `#!cpp std::deque` and `#!cpp std::list` do
not provide `capacity()` and therefore cannot be used as-is -- see
: container type to store arrays. It must be a vector-like container: the library uses `operator[]`, `at()`, and
`resize()`, and requires random-access iterators. `#!cpp std::vector` and `#!cpp std::deque` qualify;
`#!cpp std::list` does not. See
[Template Parameter Requirements](../../features/types/template_parameters.md#arraytype) for the full list of
requirements.
@@ -70,3 +70,4 @@ Arrays are stored as pointers in a `basic_json` type. That is, for any access to
## Version history
- Added in version 1.0.0.
- Made `capacity()` optional, so that array types such as `#!cpp std::deque` can be used, in version 3.13.0.