From 7cd4db3389c3f4f3e1a9fd08a5e36535e09a6164 Mon Sep 17 00:00:00 2001 From: timsong-cpp Date: Fri, 28 Aug 2026 00:03:40 -0500 Subject: [PATCH] New P/R for 4559 --- xml/issue4559.xml | 144 +++++++++++++++++++++++++++++++++++++++------- 1 file changed, 122 insertions(+), 22 deletions(-) diff --git a/xml/issue4559.xml b/xml/issue4559.xml index ce993ceff3..b4ee509018 100644 --- a/xml/issue4559.xml +++ b/xml/issue4559.xml @@ -18,7 +18,7 @@ Although the original paper P2846 gives a reason for not providing reserve_hint for these three views — namely, uncertainty about what the best approach is — it seems to me that providing them is indeed intuitively unambiguous. We -don't need to consider the inconsistency between const and non-const overloads because +don't need to consider the inconsistency between const and non-const overloads because it's not within reasonable ranges.

Given that we provided reserve_hint for concat_view to resolve NB comment - - - +

This wording is relative to .

@@ -133,22 +131,6 @@ namespace std::ranges { […] -
-
-
-

-

-
-
-
-
-
-
-

-

-
-
-
@@ -163,7 +145,7 @@ namespace std::ranges { template<class... Vs> concept cartesian-product-is-sized = // exposition only (sized_range<Vs> && ...); - + template<class... Vs> concept cartesian-product-is-approximately-sized = // exposition only (approximately_sized_range<Vs> && ...); @@ -199,7 +181,7 @@ constexpr see below size() const -7- The return type is an implementation-defined unsigned-integer-like type.

-8- Recommended practice: The return type should be the smallest unsigned-integer-like type that -is sufficiently wide to store the product of the maximum sizes of all the underlying ranges, if such +is sufficiently wide to store the product of the maximum sizes of all the underlying ranges, if such a type exists.

-9- Let p be the product of the sizes of all the ranges in bases_. @@ -236,6 +218,124 @@ ranges, if such a type exists. + + +2026-08-27; Tim provides new wording +

Dropping the `cartesian_product` change per reflector discussion. +

+It seems to me that, unlike the previous resolution, and as the original paper alluded to, +we could provide `reserve_hint` for `zip` as long as at least one of the ranges +is approximately sized. +

+ + + + +

+This wording is relative to . +

+ +
    +
  1. +

    Modify as indicated:

    + +
    +
    +
    +namespace std::ranges {
    +  […]
    +  template<input_range... Views>
    +    requires (view<Views> && ...) && (sizeof...(Views) > 0)
    +  class zip_view : public view_interface<zip_view<Views...>> {
    +    […]
    +    constexpr auto size() requires (sized_range<Views> && ...);
    +    constexpr auto size() const requires (sized_range<const Views> && ...);
    +
    +    constexpr auto reserve_hint() requires (approximately_sized_range<Views> || ...);
    +    constexpr auto reserve_hint() const requires (approximately_sized_range<const Views> || ...);
    +  };
    +  […]
    +}
    +
    +
    +[…] +
    +constexpr auto size() requires (sized_range<Views> && ...);
    +constexpr auto size() const requires (sized_range<const Views> && ...);
    +
    +
    +

    +-3- Effects: Equivalent to: +

    +
    +return apply([](auto... sizes) {
    +  using CT = make-unsigned-like-t<common_type_t<decltype(sizes)...>>;
    +  return ranges::min({CT(sizes)...});
    +}, tuple-transform(ranges::size, views_));
    +
    +
    +
    +constexpr auto reserve_hint() requires (approximately_sized_range<Views> || ...);
    +constexpr auto reserve_hint() const requires (approximately_sized_range<const Views> || ...);
    +
    +
    +

    +-?- Effects: Let `Const` be `false` for the first overload and `true` for the second overload. +Let I be the largest set of indices such that +approximately_sized_range<maybe-const<Const, Views...[Is]>> is `true`, +and let `Is` be a pack of `size_t` values consisting of the elements of +I in ascending order. Equivalent to: +

    +
    +
    +using CT = make-unsigned-like-t<common_type_t<decltype(ranges::reserve_hint(get<Is>(views_)))...>>;
    +return ranges::min({CT(ranges::reserve_hint(get<Is>(views_)))...});
    +
    +
    +
    +
  2. + +
  3. +

    Modify as indicated:

    + +
    +
    +
    +namespace std::ranges {
    +  […]
    +  namespace std::ranges {
    +  template<move_constructible F, input_range... Views>
    +    requires (view<Views> && ...) && (sizeof...(Views) > 0) && is_object_v<F> &&
    +              regular_invocable<F&, range_reference_t<Views>...> &&
    +              can-reference<invoke_result_t<F&, range_reference_t<Views>...>>
    +  class zip_transform_view : public view_interface<zip_transform_view<F, Views...>> {
    +    […]
    +    constexpr auto size() requires sized_range<InnerView> {
    +      return zip_.size();
    +    }
    +
    +    constexpr auto size() const requires sized_range<const InnerView> {
    +      return zip_.size();
    +    }
    +
    +    constexpr auto reserve_hint() requires approximately_sized_range<InnerView> {
    +      return zip_.reserve_hint();
    +    }
    +
    +    constexpr auto reserve_hint() const requires approximately_sized_range<const InnerView> {
    +      return zip_.reserve_hint();
    +    }
    +  };
    +  […]
    +}
    +
    +
    +[…] +
    +
  4. + +
+