Created on 2025-10-02.00:00:00 last changed 1 week ago
Proposed resolution:
This wording is relative to N5014.
Modify [range.join.view] as indicated:
[Drafting note: The proposed wording follows the
tiny-range
's way to check if `R::size()` is a constant expression instead of further checking `ranges::size(r)` for simplicity.]
namespace std::ranges { template<auto> struct require-constant; // exposition only template<class R> concept static-sized-range = // exposition only sized_range<R> && requires { typename require-constant<remove_reference_t<R>::size()>; }; template<input_range V> requires view<V> && input_range<range_reference_t<V>>> class join_view : public view_interface<join_view<V>> { […] public: […] constexpr auto size() requires sized_range<V> && static-sized-range<InnerRng> { using CT = common_type_t<range_size_t<V>, range_size_t<InnerRng>>; return CT(ranges::size(base_)) * CT(remove_reference_t<InnerRng>::size()); } constexpr auto size() const requires sized_range<const V> && static-sized-range<range_reference_t<const V>> { using InnerConstRng = range_reference_t<const V>; using CT = common_type_t<range_size_t<V>, range_size_t<InnerConstRng>>; return CT(ranges::size(base_)) * CT(remove_reference_t<InnerConstRng>::size()); } }; […] }
Modify [range.join.with.view] as indicated:
namespace std::ranges { […] template<input_range V, forward_range Pattern> requires view<V> && input_range<range_reference_t<V>> && view<Pattern> && concatable<range_reference_t<V>, Pattern> class join_with_view : public view_interface<join_with_view<V, Pattern>> { […] public: […] constexpr auto size() requires sized_range<V> && sized_range<Pattern> && static-sized-range<InnerRng> { using CT = common_type_t< range_size_t<V>, range_size_t<InnerRng>, range_size_t<Pattern>>; const auto base_size = ranges::size(base_); if (base_size == 0) return CT(0); return CT(base_size) * CT(remove_reference_t<InnerRng>::size()) + CT(base_size - 1) * CT(ranges::size(pattern_)); } constexpr auto size() const requires sized_range<const V> && sized_range<const Pattern> && static-sized-range<range_reference_t<const V>> { using InnerConstRng = range_reference_t<const V>; using CT = common_type_t< range_size_t<const V>, range_size_t<InnerConstRng>, range_size_t<const Pattern>>; const auto base_size = ranges::size(base_); if (base_size == 0) return CT(0); return CT(base_size) * CT(remove_reference_t<InnerConstRng>::size()) + CT(base_size - 1) * CT(ranges::size(pattern_)); } }; […] }
Modify [range.lazy.split.view] as indicated:
namespace std::ranges {template<auto> struct require-constant; // exposition onlytemplate<class R> concept tiny-range = // exposition only static-sized-range<R>sized_range<R> && requires { typename require-constant<remove_reference_t<R>::size()>; }&& (remove_reference_t<R>::size() <= 1); […] }
Consider:
Collecting a `simd::vec` into a `vector` for output is a common use case. P3480R6 makes `simd::vec` a range so we can simply flatten it with `views::join` (original example from the paper):std::vector<std::simd::vec<float>> data; auto range_of_float = data | std::views::join;
In this case, it makes sense for `join_view` to be `sized_range` because `simd::vec::size()` is a constant expression that can be multiplied by the original `vector` size to get the result size of the `join_view`.
In<ranges>
, we use the tiny-range
concept
to consider types that can obtain static sizes specifically, and `simd::vec`
seems to be a good fit.
History | |||
---|---|---|---|
Date | User | Action | Args |
2025-10-04 13:39:45 | admin | set | messages: + msg15120 |
2025-10-02 00:00:00 | admin | create |