From 4cd438d3f6c4e0e7e0fd0132d0d52ea3cadf5c99 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Kami=C5=84ski?= Date: Mon, 3 Nov 2025 22:31:42 +0100 Subject: [PATCH 1/4] New issue to address US 161-258: ranges::rotate do not handle sized-but-not-sized-sentinel ranges correctly --- xml/issue4441.xml | 122 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 122 insertions(+) create mode 100644 xml/issue4441.xml diff --git a/xml/issue4441.xml b/xml/issue4441.xml new file mode 100644 index 0000000000..9d19e8a089 --- /dev/null +++ b/xml/issue4441.xml @@ -0,0 +1,122 @@ + + + + +<tt>ranges::rotate</tt> do not handle sized-but-not-sized-sentinel ranges correctly +
+ + + + +
+Tomasz KamiƄski +03 Nov 2025 +99 + + +Addresses US 161-258 +

These do not handle sized-but-not-sized-sentinel ranges correctly.

+
+ + +

+This wording is relative to . +

+ +
    + +
  1. Modify as indicated:

    + +
    +template<execution-policy Ep, sized-random-access-range R>
    +  requires permutable<iterator_t<R>>
    +  borrowed_subrange_t<R> ranges::rotate(Ep&& exec, R&& r, iterator_t<R> middle);
    +
    +
    +
    +

    -6- Effects Equivalent to: +return ranges::rotate(std::forward<Ep>(exec), ranges::begin(r), middle, +ranges::end(r)ranges::begin(r) + ranges::distance(r)); +

    +
    + +[…] + +
    +template<execution-policy Ep, sized-random-access-range R, sized-random-access-range OutR>
    +  requires indirectly_copyable<iterator_t<R>, iterator_t<OutR>>
    +  ranges::rotate_copy_truncated_result<borrowed_iterator_t<R>, borrowed_iterator_t<OutR>>
    +	  ranges::rotate_copy(Ep&& exec, R&& r, iterator_t<R> middle, OutR&& result_r);
    +
    +
    +

    -18- Effects Equivalent to: +return ranges::rotate(std::forward<Ep>(exec), ranges::begin(r), middle, +ranges::end(r)ranges::begin(r)+ranges::distance(r) +ranges::begin(result_r), ranges::end(result_r)ranges::begin(result_r) + ranges::distance(result_r)); +

    +
    + +
  2. + +
  3. Modify as indicated:

    + +
    +template<execution-policy Ep, sized-random-access-range R,
    +         class Comp = ranges::less, class Proj = identity>
    +  requires sortable<iterator_t<R>, Comp, Proj>
    +  borrowed_iterator_t<R>
    +    ranges::partial_sort(Ep&& exec, R&& r, iterator_t<R> middle, Comp comp = {},
    +                         Proj proj = {});
    +
    +
    +

    -7- Effects Equivalent to: +return ranges::partial_sort(std::forward<Ep>(exec), ranges::begin(r), middle, +ranges::end(r)ranges::begin(r) + ranges::distance(r), comp, proj); +

    +
    + +
  4. + +
  5. Modify as indicated:

    + +
    +template<execution-policy Ep, sized-random-access-range R, class Comp = ranges::less,
    +         class Proj = identity>
    +  requires sortable<iterator_t<R>, Comp, Proj>
    +  borrowed_iterator_t<R>
    +    ranges::nth_element(Ep&& exec, R&& r, iterator_t<R> nth, Comp comp = {}, Proj proj = {});
    +
    +
    +

    -7- Effects Equivalent to: +return ranges::nth_element(std::forward<Ep>(exec), ranges::begin(r), nth, +ranges::end(r)ranges::begin(r) + ranges::distance(r), comp, proj); +

    +
    + +
  6. + +
  7. Modify as indicated:

    + +
    +template<execution-policy Ep, sized-random-access-range R, class Comp = ranges::less,
    +         class Proj = identity>
    +  requires sortable<iterator_t<R>, Comp, Proj>
    +  borrowed_iterator_t<R>
    +    ranges::inplace_merge(Ep&& exec, R&& r, iterator_t<R> middle, Comp comp = {},
    +                          Proj proj = {});
    +
    +
    +

    -14- Effects Equivalent to: +return ranges::inplace_merge(std::forward<Ep>(exec), ranges::begin(r), middle, +ranges::end(r)ranges::begin(r) + ranges::distance(r), comp, proj); +

    +
    + +
  8. + + +
+ +
+ +
From f122fa96fe7e8407075ee19f76a4e906b8020f0c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Kami=C5=84ski?= Date: Mon, 3 Nov 2025 23:14:57 +0100 Subject: [PATCH 2/4] Updates P/R for 4316, following reflector discussion --- xml/issue4316.xml | 87 +++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 84 insertions(+), 3 deletions(-) diff --git a/xml/issue4316.xml b/xml/issue4316.xml index a08766fb5b..982fac7a74 100644 --- a/xml/issue4316.xml +++ b/xml/issue4316.xml @@ -43,9 +43,7 @@ Set priority to 1 after reflector poll.

2025-10-27; Tomasz provides wording. - - - +

This wording is relative to . @@ -126,6 +124,89 @@ context, the program is ill-formed. — end note] + + +2025-10-27; Reflector comments. +

+We lost definition of `Z`. Use TARG-SPLICE([:Args:]).... +

+ +2025-11-03; Tomasz provides wording. + + + + +

+This wording is relative to . +

+ +
    + +
  1. Modify as indicated:

    + +
    +
    +

    +-1- For value `x` of type `info`, and prvalue constant expression `X` that computes the +reflection held by `x`, let TARG-SPLICE(x) be: +

      +
    • -1.1- template [: X :] if `is_template(x)` is `true`, otherwise
    • +
    • -1.2- typename [: X :] if `is_type(x)` is `true`, otherwise
    • +
    • -1.3- ([: X :])
    • +
    +

    +
    + +
    +template<reflection_range R = initializer_list<info>>
    +  consteval bool can_substitute(info templ, R&& arguments);
    +
    +
    +

    +-1- Let `Z` be the template represented by `templ` and let `Args...` be a +sequence of prvalue constant expressions that compute the reflections held by +the elements of `arguments`, in order. +

    +

    +-2- Returns: `true` if Z<TARG-SPLICE([:Args:])...> is a valid template-id +() that does not name a function whose type contains an undeduced placeholder type. +Otherwise, `false`. +

    +

    +-3- Throws: `meta::exception` unless `templ` represents a template, and every reflection +in `arguments` represents a construct usable as a template argument (). +

    +

    +-4- [Note: If forming Z<TARG-SPLICE([:Args:])...> +leads to a failure outside of the immediate context, the program is ill-formed. — end note] +

    +
    + +
    +template<reflection_range R = initializer_list<info>>
    +  consteval info substitute(info templ, R&& arguments);
    +
    +
    +

    +-5- Let `Z` be the template represented by `templ` and let `Args...` be a +sequence of prvalue constant expressions that compute the reflections held by +the elements of `arguments`, in order. +

    +

    +-6- Returns: Z<TARG-SPLICE([:Args:])...>.

    +

    +-7- Throws: `meta::exception` unless `can_substitute(templ, arguments)` is `true`. +

    +

    +-8- [Note: If forming Z<TARG-SPLICE([:Args:])...> +leads to a failure outside of the immediate context, the program is ill-formed. — end note] +

    +
    + +
    +
  2. +
+
From aaa76fcd2dccd1bc957d300c687e3b69e2fff610 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Kami=C5=84ski?= Date: Tue, 4 Nov 2025 00:08:59 +0100 Subject: [PATCH 3/4] Updates P/R for 4251, covering polymorphic --- xml/issue4251.xml | 157 ++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 153 insertions(+), 4 deletions(-) diff --git a/xml/issue4251.xml b/xml/issue4251.xml index 57944547a5..ab231ad04a 100644 --- a/xml/issue4251.xml +++ b/xml/issue4251.xml @@ -3,7 +3,10 @@ Move assignment for `indirect` unnecessarily requires copy construction -
+
+ + +
Jonathan Wakely 01 May 2025 1 @@ -46,15 +49,14 @@ Set priority to 1 after reflector poll. Similar change needed for `std::polymorphic`.

- - +

This wording is relative to .

    -
  1. Modify as indicated:

    +
  2. Modify as indicated:

    
     constexpr indirect& operator=(indirect&& other)
    @@ -122,6 +124,153 @@ the allocator in `*this` is replaced with a copy of the allocator in `other`.
     
  3. +
+
+ +2025-11-03; Tomasz provides wording. + + + +

+This wording is relative to . +

+
    + +
  1. Modify as indicated:

    +
    +
    
    +constexpr indirect& operator=(indirect&& other)
    +  noexcept(allocator_traits<Allocator>::propagate_on_container_move_assignment::value ||
    +           allocator_traits<Allocator>::is_always_equal::value);
    +
    +
    +

    +-5- Mandates: + +If +allocator_traits<Allocator>::propagate_on_container_move_assignment::value +is `false` +and +allocator_traits<Allocator>::is_always_equal::value +is `false`, + +is_copymove_constructible_t<T> is `true`. +

    +

    +-6- Effects: +If `addressof(other) == this` is `true`, there are no effects. +Otherwise: +

      +
    1. (6.1) — +The allocator needs updating if +allocator_traits<Allocator>::propagate_on_container_move_assignment::value +is `true`. +
    2. +
    3. (6.2) — +If `other` is valueless, `*this` becomes valueless and the owned object +in `*this`, if any, is destroyed using +allocator_traits<Allocator>::destroy +and then the storage is deallocated. +
    4. +
    5. (6.3) — +Otherwise, +if the allocator needs updating or +if alloc == other.alloc is `true`, + +swaps the owned objects in `*this` and `other`; +the owned object in `other`, if any, is then destroyed using +allocator_traits<Allocator>::destroy +and then the storage is deallocated + +`*this` takes ownership of the owned object of `other`. +
    6. +
    7. (6.4) — +Otherwise, constructs a new owned object with the owned object of `other` +as the argument as an rvalue, using either the allocator in `*this` +or the allocator in `other` if the allocator needs updating. +
    8. +
    9. (6.5) — +The previously owned object in `*this`, if any, is destroyed using +allocator_traits<Allocator>::destroy +and then the storage is deallocated. +
    10. +
    11. (6.6) — +If the allocator needs updating, +the allocator in `*this` is replaced with a copy of the allocator in `other`. +
    12. +
    +

    +

    -7- Postcondition: `other` is valueless.

    +
    +
    +
  2. + +
  3. Modify as indicated:

    +
    +
    
    +constexpr polymorphic& operator=(polymorphic&& other)
    +  noexcept(allocator_traits<Allocator>::propagate_on_container_move_assignment::value ||
    +           allocator_traits<Allocator>::is_always_equal::value);
    +
    +
    +

    +-5- Mandates: +If + +allocator_traits<Allocator>::propagate_on_container_move_assignment::value +is `false` +and + +allocator_traits<Allocator>::is_always_equal::value +is `false`, +`T` is complete type. +

    +

    +-6- Effects: +If `addressof(other) == this` is `true`, there are no effects. +Otherwise: +

      +
    1. (6.1) — +The allocator needs updating if +allocator_traits<Allocator>::propagate_on_container_move_assignment::value +is `true`. +
    2. +
    3. (6.?) — If `other` is valueless, `*this` becomes valueless.
    4. +
    5. (6.2) — +Otherwise, if the allocator needs updating orIf +alloc == other.alloc is `true`, + +swaps the owned objects in `*this` and `other`; +the owned object in `other`, if any, is then destroyed using +allocator_traits<Allocator>::destroy +and then the storage is deallocated + +`*this` takes ownership of the owned object of `other`. +
    6. +
    7. (6.3) — +Otherwise, if `alloc != other.alloc` is `true`; if `other` is not valueless, +a new owned object is constructed in `*this` using allocator_traits::construct +with the owned object from +Otherwise, constructs a new owned object with the owned object of +`other` as the argument as an rvalue, using either the allocator in `*this` +or the allocator in `other` if the allocator needs updating. +
    8. +
    9. (6.4) — +The previously owned object in `*this`, if any, is destroyed using +allocator_traits<Allocator>::destroy +and then the storage is deallocated. +
    10. +
    11. (6.5) — +If the allocator needs updating, +the allocator in `*this` is replaced with a copy of the allocator in `other`. +
    12. +
    +

    +[…] +
    +
    +
  4. +
From e8c8f822cef08f3356fa8af88e791611aeb213e2 Mon Sep 17 00:00:00 2001 From: Jonathan Wakely Date: Tue, 4 Nov 2025 01:07:53 +0000 Subject: [PATCH 4/4] Fix working paper number in 4251 --- xml/issue4251.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/xml/issue4251.xml b/xml/issue4251.xml index ab231ad04a..0901c074a2 100644 --- a/xml/issue4251.xml +++ b/xml/issue4251.xml @@ -132,7 +132,7 @@ the allocator in `*this` is replaced with a copy of the allocator in `other`.

-This wording is relative to . +This wording is relative to .