Skip to content

fix: support constructing json from C++20 range views (#4916)#5205

Open
federicosfriso05-dotcom wants to merge 2 commits into
nlohmann:developfrom
federicosfriso05-dotcom:fix/issue-4916-ranges-view-support
Open

fix: support constructing json from C++20 range views (#4916)#5205
federicosfriso05-dotcom wants to merge 2 commits into
nlohmann:developfrom
federicosfriso05-dotcom:fix/issue-4916-ranges-view-support

Conversation

@federicosfriso05-dotcom

Copy link
Copy Markdown

Description

Fixes #4916.

Constructing a nlohmann::json object from a C++20 range view (e.g. std::views::filter, std::views::transform) failed to compile because is_compatible_array_type did not recognize range views as compatible types.

What changed

  • include/nlohmann/detail/meta/type_traits.hpp: added a new partial specialization of is_compatible_array_type_impl for C++20 range views, guarded by #ifdef JSON_HAS_CPP_20. The specialization matches types satisfying std::ranges::view while excluding character sequences (e.g. std::string_view).
  • include/nlohmann/detail/conversions/to_json.hpp: added a new construct overload for C++20 range views inside external_constructor<value_t::array>, also guarded by #ifdef JSON_HAS_CPP_20.
  • The specialization uses std::ranges::view rather than just std::ranges::range to avoid ambiguity with standard containers like std::string and std::string_view, which already satisfy std::ranges::range but are handled by existing specializations. Character sequences are additionally excluded by checking that the range's value type is not char or wchar_t.

How to test

std::vector<int> nums{1, 2, 37, 42, 21};
auto filtered = nums | std::views::filter([](int i) { return i > 10; });
nlohmann::json j(filtered);
assert(j == nlohmann::json({37, 42, 21}));
  • The changes are described in detail, both the what and why.
  • If applicable, an existing issue is referenced.
  • The Code coverage remained at 100%. A test case for every new line of code.
  • If applicable, the documentation is updated.
  • The source code is amalgamated by running make amalgamate.

Signed-off-by: Federico Sfriso <federicosfriso05@gmail.com>
@federicosfriso05-dotcom federicosfriso05-dotcom force-pushed the fix/issue-4916-ranges-view-support branch from ee84434 to 7593e0c Compare June 7, 2026 16:06
@federicosfriso05-dotcom

Copy link
Copy Markdown
Author

Hi, I noticed the Windows/MinGW builds are failing. After investigating the CI logs, the issue seems to be related to an incomplete C++20 ranges implementation in MinGW GCC 12.2.0, where std::ranges::ref_view and std::ranges::filter_view do not work correctly on that toolchain. The same code compiles and runs correctly on GCC/Linux and Clang/Mac.
Should the test be guarded against MinGW with something like #ifndef __MINGW32__, or is there a different approach you'd recommend for handling this compiler limitation?
Thanks!

@nlohmann

nlohmann commented Jun 8, 2026

Copy link
Copy Markdown
Owner

IIRC we also excluded some other older compilers from other C++20 features. So I guess and ifdef with some specific versions and comments would be sufficient.

Signed-off-by: Federico Sfriso <federicosfriso05@gmail.com>
@federicosfriso05-dotcom

Copy link
Copy Markdown
Author

Updated. Replaced JSON_HAS_CPP_20 with JSON_HAS_RANGES && !defined(__MINGW32__) as suggested, following the existing pattern in macro_scope.hpp

@federicosfriso05-dotcom

Copy link
Copy Markdown
Author

I noticed there's still a failure on GCC 11 in unit-iterators2.cppiteration_proxy, an internal nlohmann type, appears to satisfy std::ranges::view, causing a circular constraint evaluation error. I'm not sure how to exclude internal types cleanly without knowing the codebase better. Any guidance on the right approach would be appreciated

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Constructing array from C++20 ranges view does not work

2 participants