Skip to content

Commit 177f761

Browse files
committed
New issue from Ruslan Arutyunyan: "Missing permutable constraint for iterator overloads in Parallel Range Algorithms"
1 parent 7d9a16b commit 177f761

File tree

1 file changed

+142
-0
lines changed

1 file changed

+142
-0
lines changed

xml/issue4297.xml

Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
<?xml version='1.0' encoding='utf-8' standalone='no'?>
2+
<!DOCTYPE issue SYSTEM "lwg-issue.dtd">
3+
4+
<issue num="4297" status="New">
5+
<title>Missing `permutable` constraint for iterator overloads in Parallel Range Algorithms</title>
6+
<section><sref ref="[algorithm.syn]"/><sref ref="[alg.remove]"/><sref ref="[alg.partitions]"/></section>
7+
<submitter>Ruslan Arutyunyan</submitter>
8+
<date>27 Jun 2025</date>
9+
<priority>99</priority>
10+
11+
<discussion>
12+
<p>
13+
The <paper num="P3179R9"/>: Parallel Range Algorithms paper was accepted to C++ working draft for C++ 26.
14+
Unfortunately, there is an oversight for three algorithms &mdash; `remove`, `remove_if` and `partition` &mdash;
15+
where the `permutable` constraint is missing. This applies to "Iterator and Sentinel" overloads only. The
16+
issue exists in <sref ref="[algorithm.syn]"/> as well as in per-algorithm sections:
17+
<sref ref="[alg.partitions]"/> and <sref ref="[alg.remove]"/>.
18+
</p>
19+
</discussion>
20+
21+
<resolution>
22+
<p>
23+
This wording is relative to this
24+
<a href="https://github.com/cplusplus/draft/actions/runs/16433597877/artifacts/3583518547">CD preview draft</a>.
25+
</p>
26+
27+
28+
<ol>
29+
30+
<li><p>Modify <sref ref="[algorithm.syn]"/>, header <tt>&lt;algorithm&gt;</tt>, as indicated:</p>
31+
32+
<blockquote>
33+
<pre>
34+
[&hellip;]
35+
template&lt;<i>execution-policy</i> Ep, random_access_iterator I, sized_sentinel_for&lt;I&gt; S,
36+
class Proj = identity, class T = projected_value_t&lt;I, Proj&gt;&gt;
37+
requires <ins>permutable&lt;I&gt; &amp;&amp;</ins>
38+
indirect_binary_predicate&lt;ranges::equal_to, projected&lt;I, Proj&gt;, const T*&gt;
39+
subrange&lt;I&gt; remove(Ep&amp; exec, I first, S last, const T&amp; value,
40+
Proj proj = {}); <i>// freestanding-deleted</i>
41+
template&lt;<i>execution-policy</i> Ep, <i>sized-random-access-range</i> R, class Proj = identity,
42+
class T = projected_value_t&lt;iterator_t&lt;R&gt;, Proj&gt;&gt;
43+
requires permutable&lt;iterator_t&lt;R&gt;&gt; &amp;&amp;
44+
indirect_binary_predicate&lt;ranges::equal_to,
45+
projected&lt;iterator_t&lt;R&gt;, Proj&gt;, const T*&gt;
46+
borrowed_subrange_t&lt;R&gt;
47+
remove(Ep&amp;&amp; exec, R&amp;&amp; r, const T&amp; value, Proj proj = {}); <i>// freestanding-deleted</i>
48+
[&hellip;]
49+
template&lt;<i>execution-policy</i> Ep, random_access_iterator I, sized_sentinel_for&lt;I&gt; S,
50+
class Proj = identity, indirect_unary_predicate&lt;projected&lt;I, Proj&gt;&gt; Pred&gt;
51+
<ins>requires permutable&lt;I&gt;</ins>
52+
subrange&lt;I&gt;
53+
remove_if(Ep&amp; exec, I first, S last, Pred pred, Proj proj = {}); <i>// freestanding-deleted</i>
54+
template&lt;<i>execution-policy</i> Ep, <i>sized-random-access-range</i> R, class Proj = identity,
55+
indirect_unary_predicate&lt;projected&lt;iterator_t&lt;R&gt;, Proj&gt;&gt; Pred&gt;
56+
requires permutable&lt;iterator_t&lt;R&gt;&gt;
57+
borrowed_subrange_t&lt;R&gt;
58+
remove_if(Ep&amp; exec, R&amp; r, Pred pred, Proj proj = {}); <i>// freestanding-deleted</i>
59+
[&hellip;]
60+
template&lt;execution-policy Ep, random_access_iterator I, sized_sentinel_for&lt;I&gt; S,
61+
class Proj = identity, indirect_unary_predicate&lt;projected&lt;I, Proj&gt;&gt; Pred&gt;
62+
<ins>requires permutable&lt;I&gt;</ins>
63+
subrange&lt;I&gt;
64+
partition(Ep&amp;&amp; exec, I first, S last, Pred pred, Proj proj = {}); <i>// freestanding-deleted</i>
65+
template&lt;<i>execution-policy</i> Ep, <i>sized-random-access-range</i> R, class Proj = identity,
66+
indirect_unary_predicate&lt;projected&lt;iterator_t&lt;R&gt;, Proj&gt;&gt; Pred&gt;
67+
requires permutable&lt;iterator_t&lt;R&gt;&gt;
68+
borrowed_subrange_t&lt;R&gt;
69+
partition(Ep&amp;&amp; exec, R&amp;&amp; r, Pred pred, Proj proj = {}); <i>// freestanding-deleted</i>
70+
[&hellip;]
71+
</pre>
72+
</blockquote>
73+
</li>
74+
75+
76+
<li><p>Modify <sref ref="[alg.remove]"/> as indicated:</p>
77+
78+
<blockquote>
79+
<pre>
80+
[&hellip;]
81+
template&lt;<i>execution-policy</i> Ep, random_access_iterator I, sized_sentinel_for&lt;I&gt; S,
82+
class Proj = identity, class T = projected_value_t&lt;I, Proj&gt;&gt;
83+
requires <ins>permutable&lt;I&gt; &amp;&amp;</ins>
84+
indirect_binary_predicate&lt;ranges::equal_to, projected&lt;I, Proj&gt;, const T*&gt;
85+
subrange&lt;I&gt;
86+
ranges::remove(Ep&amp; exec, I first, S last, const T&amp; value, Proj proj = {});
87+
template&lt;<i>execution-policy</i> Ep, <i>sized-random-access-range</i> R, class Proj = identity,
88+
class T = projected_value_t&lt;iterator_t&lt;R&gt;, Proj&gt;&gt;
89+
requires permutable&lt;iterator_t&lt;R&gt;&gt; &amp;&amp;
90+
indirect_binary_predicate&lt;ranges::equal_to,
91+
projected&lt;iterator_t&lt;R&gt;, Proj&gt;, const T*&gt;
92+
borrowed_subrange_t&lt;R&gt;
93+
ranges::remove(Ep&amp;&amp; exec, R&amp;&amp; r, const T&amp; value, Proj proj = {});
94+
[&hellip;]
95+
template&lt;<i>execution-policy</i> Ep, random_access_iterator I, sized_sentinel_for&lt;I&gt; S,
96+
class Proj = identity, indirect_unary_predicate&lt;projected&lt;I, Proj&gt;&gt; Pred&gt;
97+
<ins>requires permutable&lt;I&gt;</ins>
98+
subrange&lt;I&gt;
99+
ranges::remove_if(Ep&amp; exec, I first, S last, Pred pred, Proj proj = {});
100+
template&lt;<i>execution-policy</i> Ep, <i>sized-random-access-range</i> R, class Proj = identity,
101+
indirect_unary_predicate&lt;projected&lt;iterator_t&lt;R&gt;, Proj&gt;&gt; Pred&gt;
102+
requires permutable&lt;iterator_t&lt;R&gt;&gt;
103+
borrowed_subrange_t&lt;R&gt;
104+
ranges::remove_if(Ep&amp; exec, R&amp; r, Pred pred, Proj proj = {});
105+
</pre>
106+
<blockquote>
107+
<p>
108+
-1- Let <tt><i>E</i></tt> be [&hellip;]
109+
</p>
110+
</blockquote>
111+
</blockquote>
112+
</li>
113+
114+
115+
<li><p>Modify <sref ref="[alg.partitions]"/> as indicated:</p>
116+
117+
<blockquote>
118+
<pre>
119+
[&hellip;]
120+
template&lt;execution-policy Ep, random_access_iterator I, sized_sentinel_for&lt;I&gt; S,
121+
class Proj = identity, indirect_unary_predicate&lt;projected&lt;I, Proj&gt;&gt; Pred&gt;
122+
<ins>requires permutable&lt;I&gt;</ins>
123+
subrange&lt;I&gt;
124+
ranges::partition(Ep&amp;&amp; exec, I first, S last, Pred pred, Proj proj = {});
125+
template&lt;<i>execution-policy</i> Ep, <i>sized-random-access-range</i> R, class Proj = identity,
126+
indirect_unary_predicate&lt;projected&lt;iterator_t&lt;R&gt;, Proj&gt;&gt; Pred&gt;
127+
requires permutable&lt;iterator_t&lt;R&gt;&gt;
128+
borrowed_subrange_t&lt;R&gt;
129+
ranges::partition(Ep&amp;&amp; exec, R&amp;&amp; r, Pred pred, Proj proj = {});
130+
</pre>
131+
<blockquote>
132+
<p>
133+
-1- Let `proj` be `identity{}` for the overloads with no parameter named `proj`.
134+
</p>
135+
</blockquote>
136+
</blockquote>
137+
</li>
138+
139+
</ol>
140+
</resolution>
141+
142+
</issue>

0 commit comments

Comments
 (0)