<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Issue 3345: Incorrect usages of "models" versus "satisfies"</title>
<meta property="og:title" content="Issue 3345: Incorrect usages of &quot;models&quot; versus &quot;satisfies&quot;">
<meta property="og:description" content="C++ library issue. Status: Resolved">
<meta property="og:url" content="https://cplusplus.github.io/LWG/issue3345.html">
<meta property="og:type" content="website">
<meta property="og:image" content="http://cplusplus.github.io/LWG/images/cpp_logo.png">
<meta property="og:image:alt" content="C++ logo">
<style>
  p {text-align:justify}
  li {text-align:justify}
  pre code.backtick::before { content: "`" }
  pre code.backtick::after { content: "`" }
  blockquote.note
  {
    background-color:#E0E0E0;
    padding-left: 15px;
    padding-right: 15px;
    padding-top: 1px;
    padding-bottom: 1px;
  }
  ins {background-color:#A0FFA0}
  del {background-color:#FFA0A0}
  table.issues-index { border: 1px solid; border-collapse: collapse; }
  table.issues-index th { text-align: center; padding: 4px; border: 1px solid; }
  table.issues-index td { padding: 4px; border: 1px solid; }
  table.issues-index td:nth-child(1) { text-align: right; }
  table.issues-index td:nth-child(2) { text-align: left; }
  table.issues-index td:nth-child(3) { text-align: left; }
  table.issues-index td:nth-child(4) { text-align: left; }
  table.issues-index td:nth-child(5) { text-align: center; }
  table.issues-index td:nth-child(6) { text-align: center; }
  table.issues-index td:nth-child(7) { text-align: left; }
  table.issues-index td:nth-child(5) span.no-pr { color: red; }
  @media (prefers-color-scheme: dark) {
     html {
        color: #ddd;
        background-color: black;
     }
     ins {
        background-color: #225522
     }
     del {
        background-color: #662222
     }
     a {
        color: #6af
     }
     a:visited {
        color: #6af
     }
     blockquote.note
     {
        background-color: rgba(255, 255, 255, .10)
     }
  }
</style>
</head>
<body>
<hr>
<p><em>This page is a snapshot from the LWG issues list, see the <a href="lwg-active.html">Library Active Issues List</a> for more information and the meaning of <a href="lwg-active.html#Resolved">Resolved</a> status.</em></p>
<h3 id="3345"><a href="lwg-defects.html#3345">3345</a>. Incorrect usages of "models" versus "satisfies"</h3>
<p><b>Section:</b> 18.4.9 <a href="https://wg21.link/concept.swappable">[concept.swappable]</a>, 24.3.3.2 <a href="https://wg21.link/iterator.cust.swap">[iterator.cust.swap]</a>, 24.4.4.2 <a href="https://wg21.link/range.iter.op.advance">[range.iter.op.advance]</a>, 24.4.4.3 <a href="https://wg21.link/range.iter.op.distance">[range.iter.op.distance]</a>, 24.5.1.2 <a href="https://wg21.link/reverse.iterator">[reverse.iterator]</a>, 24.5.4.2 <a href="https://wg21.link/move.iterator">[move.iterator]</a>, 24.5.4.7 <a href="https://wg21.link/move.iter.nav">[move.iter.nav]</a>, 24.5.5.2 <a href="https://wg21.link/common.iter.types">[common.iter.types]</a>, 24.5.5.5 <a href="https://wg21.link/common.iter.nav">[common.iter.nav]</a>, 25.3 <a href="https://wg21.link/range.access">[range.access]</a>, 25.6.4.3 <a href="https://wg21.link/range.iota.iterator">[range.iota.iterator]</a>, 25.7 <a href="https://wg21.link/range.adaptors">[range.adaptors]</a>, 26 <a href="https://wg21.link/algorithms">[algorithms]</a> <b>Status:</b> <a href="lwg-active.html#Resolved">Resolved</a>
 <b>Submitter:</b> Daniel Kr&uuml;gler <b>Opened:</b> 2019-11-23 <b>Last modified:</b> 2020-05-01</p>
<p><b>Priority: </b>2
</p>
<p><b>View other</b> <a href="lwg-index-open.html#concept.swappable">active issues</a> in [concept.swappable].</p>
<p><b>View all other</b> <a href="lwg-index.html#concept.swappable">issues</a> in [concept.swappable].</p>
<p><b>View all issues with</b> <a href="lwg-status.html#Resolved">Resolved</a> status.</p>
<p><b>Discussion:</b></p>
<p>
The current working draft uses at several places within normative wording the term "models" instead
of "satisfies" even though it is clear from the context that these are conditions to be tested by
the implementation. Since "models" includes both syntactic requirements as well as semantic requirements, 
such wording would require (at least in general) heroic efforts for an implementation. Just to name a 
few examples for such misusage:
</p>
<ul>
<li><p>The specification of the customization objects in 18.4.9 <a href="https://wg21.link/concept.swappable">[concept.swappable]</a>,
24.3.3.2 <a href="https://wg21.link/iterator.cust.swap">[iterator.cust.swap]</a>, 25.3 <a href="https://wg21.link/range.access">[range.access]</a></p></li>
<li><p>The algorithmic decision logic for the effects of the functions specified in 
24.4.4.2 <a href="https://wg21.link/range.iter.op.advance">[range.iter.op.advance]</a>, 24.4.4.3 <a href="https://wg21.link/range.iter.op.distance">[range.iter.op.distance]</a></p></li>
</ul>
<p>
The correct way to fix these presumably unintended extra requirements is to use the term 
"satisfies" at the places where it is clear that an implementation has to test them.
<p/>
Note: There exists similar misusage in regard to wording for types that "meet <i>Cpp17XX</i> 
requirements, but those are not meant to be covered as part of this issue. This additional wording 
problem should be handled by a separate issue.
</p>

<p><i>[2019-12-08 Issue Prioritization]</i></p>

<p>Priority to 2 after reflector discussion.</p>

<p><i>[2019-12-15; Daniel synchronizes wording with <a href="https://wg21.link/n4842">N4842</a>]</i></p>


<strong>Previous resolution [SUPERSEDED]:</strong>
<blockquote class="note">
<p>This wording is relative to <a href="https://wg21.link/n4842">N4842</a>.</p>

<blockquote class="note">
<p>
[<i>Drafting note:</i> The proposed wording does intentionally not touch the definition of 
<code>enable_view</code>, whose definition is radically changed by LWG <a href="lwg-defects.html#3326" title="enable_view has false positives (Status: C++20)">3326</a><sup><a href="https://cplusplus.github.io/LWG/issue3326" title="Latest snapshot">(i)</a></sup> in a manner
that does no longer need similar adjustments.]
</p>
</blockquote>
<ol>
<li><p>Modify 18.4.9 <a href="https://wg21.link/concept.swappable">[concept.swappable]</a> as indicated:</p>

<blockquote>
<p>
-2- The name <code>ranges::swap</code> denotes a customization point object (16.3.3.3.5 <a href="https://wg21.link/customization.point.object">[customization.point.object]</a>). 
The expression <code>ranges::swap(E1, E2)</code> for some subexpressions <code>E1</code> and <code>E2</code> is 
expression-equivalent to an expression <code>S</code> determined as follows:
</p>
<ol style="list-style-type: none">
<li><p>(2.1) &mdash; [&hellip;]</p></li>
<li><p>(2.2) &mdash; [&hellip;]</p></li>
<li><p>(2.3) &mdash; Otherwise, if <code>E1</code> and <code>E2</code> are lvalues of the same type <code>T</code> that 
<del>models</del><ins>satisfies</ins> <code>move_constructible&lt;T&gt;</code> and <code>assignable_from&lt;T&amp;, 
T&gt;</code>, <code>S</code> is an expression that exchanges the denoted values. <code>S</code> is a constant expression 
if [&hellip;]</p></li>
<li><p>(2.4) &mdash; [&hellip;]</p></li>
</ol>
</blockquote>
</li>

<li><p>Modify 24.3.3.2 <a href="https://wg21.link/iterator.cust.swap">[iterator.cust.swap]</a> as indicated:</p>

<blockquote>
<p>
-4- The expression <code>ranges::iter_swap(E1, E2)</code> for some subexpressions <code>E1</code> and <code>E2</code> 
is expression-equivalent to:
</p>
<ol style="list-style-type: none">
<li><p>(4.1) &mdash; [&hellip;]</p></li>
<li><p>(4.2) &mdash; Otherwise, if the types of <code>E1</code> and <code>E2</code> each <del>model</del><ins>satisfy</ins> 
<code>indirectly_readable</code>, and if the reference types of <code>E1</code> and <code>E2</code> <del>model</del><ins>satisfy</ins> 
<code>swappable_with</code> (18.4.9 <a href="https://wg21.link/concept.swappable">[concept.swappable]</a>), then <code>ranges::swap(*E1, *E2)</code>.</p></li>
<li><p>(4.3) &mdash; Otherwise, if the types <code>T1</code> and <code>T2</code> of <code>E1</code> and <code>E2</code> 
<del>model</del><ins>satisfy</ins> <code>indirectly_movable_storable&lt;T1, T2&gt;</code> and 
<code>indirectly_movable_storable&lt;T2, T1&gt;</code>, then <code>(void)(*E1 = <i>iter-exchange-move</i>(E2, E1))</code>,
except that <code>E1</code> is evaluated only once.</p></li>
<li><p>(4.4) &mdash; [&hellip;]</p></li>
</ol>
</blockquote>
</li>

<li><p>Modify 24.4.4 <a href="https://wg21.link/range.iter.ops">[range.iter.ops]</a> as indicated:</p>

<blockquote>
<p>
-1- The library includes the function templates <code>ranges::advance</code>, <code>ranges::distance</code>, 
<code>ranges::next</code>, and <code>ranges::prev</code> to manipulate iterators. These operations adapt to the 
set of operators provided by each iterator category to provide the most efficient implementation possible 
for a concrete iterator type. [<i>Example:</i> <code>ranges::advance</code> uses the <code>+</code> operator 
to move a <code>random_access_iterator</code> forward <code>n</code> steps in constant time. For an iterator type 
that does not <del>model</del><ins>satisfy</ins> <code>random_access_iterator</code>, <code>ranges::advance</code> 
instead performs <code>n</code> individual increments with the <code>++</code> operator. &mdash; <i>end example</i>]
</p>
</blockquote>
</li>

<li><p>Modify 24.4.4.2 <a href="https://wg21.link/range.iter.op.advance">[range.iter.op.advance]</a> as indicated:</p>

<blockquote>
<pre>
template&lt;input_or_output_iterator I&gt;
  constexpr void ranges::advance(I&amp; i, iter_difference_t&lt;I&gt; n);
</pre>
<blockquote>
<p>
-1- <i>Preconditions:</i> [&hellip;]
<p/>
-2- <i>Effects:</i>
<ol style="list-style-type: none">
<li><p>(2.1) &mdash; If <code>I</code> <del>models</del><ins>satisfies</ins> <code>random_access_iterator</code>, 
equivalent to <code>i += n</code>.</p></li>
<li><p>(2.2) &mdash; [&hellip;]</p></li>
<li><p>(2.3) &mdash; [&hellip;]</p></li>
</ol>
</p>
</blockquote>
<pre>
template&lt;input_or_output_iterator I, sentinel_for&lt;I&gt; S&gt;
  constexpr void ranges::advance(I&amp; i, S bound);
</pre>
<blockquote>
<p>
-3- <i>Preconditions:</i> [&hellip;]
<p/>
-4- <i>Effects:</i>
<ol style="list-style-type: none">
<li><p>(4.1) &mdash; If <code>I</code> and <code>S</code> <del>model</del><ins>satisfy</ins> <code>assignable_from&lt;I&amp;, 
S&gt;</code>, equivalent to <code>i = std::move(bound)</code>.</p></li>
<li><p>(4.2) &mdash; Otherwise, if <code>S</code> and <code>I</code> <del>model</del><ins>satisfy</ins> 
<code>sized_sentinel_for&lt;S, I&gt;</code>, equivalent to <code>ranges::advance(i, bound - i)</code>.</p></li>
<li><p>(4.3) &mdash; [&hellip;]</p></li>
</ol>
</p>
</blockquote>
<pre>
template&lt;input_or_output_iterator I, sentinel_for&lt;I&gt; S&gt;
  constexpr iter_difference_t&lt;I&gt; ranges::advance(I&amp; i, iter_difference_t&lt;I&gt; n, S bound);
</pre>
<blockquote>
<p>
-5- <i>Preconditions:</i> [&hellip;]
<p/>
-6- <i>Effects:</i>
<ol style="list-style-type: none">
<li><p>(6.1) &mdash; If <code>S</code> and <code>I</code> <del>model</del><ins>satisfy</ins> 
<code>sized_sentinel_for&lt;S, I&gt;</code>: [&hellip;]</p></li>
<li><p>(6.2) &mdash; [&hellip;]</p></li>
</ol>
</p>
</blockquote>
</blockquote>
</li>

<li><p>Modify 24.4.4.3 <a href="https://wg21.link/range.iter.op.distance">[range.iter.op.distance]</a> as indicated:</p>

<blockquote>
<pre>
template&lt;input_or_output_iterator I, sentinel_for&lt;I&gt; S&gt;
  constexpr iter_difference_t&lt;I&gt; ranges::distance(I first, S last);
</pre>
<blockquote>
<p>
-1- <i>Preconditions:</i> [&hellip;]
<p/>
-2- <i>Effects:</i> If <code>S</code> and <code>I</code> <del>model</del><ins>satisfy</ins> <code>sized_sentinel_for&lt;S, 
I&gt;</code>, returns <code>(last - first)</code>; otherwise, returns the number of increments needed to get from 
<code>first</code> to <code>last</code>.
</p>
</blockquote>
<pre>
template&lt;range R&gt;
  range_difference_t&lt;R&gt; ranges::distance(R&amp;&amp; r);
</pre>
<blockquote>
<p>
-3- <i>Effects:</i> If <code>R</code> <del>models</del><ins>satisfies</ins> <code>sized_range</code>, equivalent to:
</p>
<blockquote><pre>
return static_cast&lt;range_difference_t&lt;R&gt;&gt;(ranges::size(r)); <i>// 25.3.10 <a href="https://wg21.link/range.prim.size">[range.prim.size]</a></i>
</pre></blockquote>
<p>
Otherwise, equivalent to:
</p>
<blockquote><pre>
return ranges::distance(ranges::begin(r), ranges::end(r)); <i>// 25.3 <a href="https://wg21.link/range.access">[range.access]</a></i>
</pre></blockquote>
</blockquote>
</blockquote>
</li>

<li><p>Modify 24.5.1.2 <a href="https://wg21.link/reverse.iterator">[reverse.iterator]</a> as indicated:</p>

<blockquote>
<p>
-1- The member <i>typedef-name</i> <code>iterator_concept</code> denotes
<ol style="list-style-type: none">
<li><p>(1.1) &mdash; <code>random_access_iterator_tag</code> if <code>Iterator</code> <del>models</del><ins>satisfies</ins>
<code>random_access_iterator</code>, and</p></li>
<li><p>(1.2) &mdash; <code>bidirectional_iterator_tag</code> otherwise.</p></li>
</ol>
<p/>
-2-  The member <i>typedef-name</i> <code>iterator_category</code> denotes
<ol style="list-style-type: none">
<li><p>(2.1) &mdash; <code>random_access_iterator_tag</code> if the type 
<code>iterator_traits&lt;Iterator&gt;::iterator_category</code> <del>models</del><ins>satisfies</ins> 
<code>derived_from&lt;random_access_iterator_tag&gt;</code>, and</p></li>
<li><p>(2.2) &mdash; <code>iterator_traits&lt;Iterator&gt;::iterator_category</code> otherwise.</p></li>
</ol>
</p>
</blockquote>
</li>

<li><p>Modify 24.5.4.2 <a href="https://wg21.link/move.iterator">[move.iterator]</a> as indicated:</p>

<blockquote>
<p>
-1- The member <i>typedef-name</i> <code>iterator_category</code> denotes
<ol style="list-style-type: none">
<li><p>(1.1) &mdash; <code>random_access_iterator_tag</code> if the type 
<code>iterator_traits&lt;Iterator&gt;::iterator_category</code> <del>models</del><ins>satisfies</ins> 
<code>derived_from&lt;random_access_iterator_tag&gt;</code>, and</p></li>
<li><p>(1.2) &mdash; <code>iterator_traits&lt;Iterator&gt;::iterator_category</code> otherwise.</p></li>
</ol>
</p>
</blockquote>
</li>

<li><p>Modify 24.5.4.7 <a href="https://wg21.link/move.iter.nav">[move.iter.nav]</a> as indicated:</p>

<blockquote>
<pre>
constexpr auto operator++(int);
</pre>
<blockquote>
<p>
-3- <i>Effects:</i> <code>Iterator</code> <del>models</del><ins>satisfies</ins> <code>forward_iterator</code>, 
equivalent to:
</p>
<blockquote><pre>
move_iterator tmp = *this;
++current;
return tmp;
</pre></blockquote>
<p>
Otherwise, equivalent to <code>++current</code>.
</p>
</blockquote>
</blockquote>
</li>

<li><p>Modify 24.5.5.2 <a href="https://wg21.link/common.iter.types">[common.iter.types]</a> as indicated:</p>

<blockquote>
<p>
-1- The nested <i>typedef-name</i>s of the specialization of <code>iterator_traits</code> for 
<code>common_iterator&lt;I, S&gt;</code> are defined as follows.
<ol style="list-style-type: none">
<li><p>(1.1) &mdash; <code>iterator_concept</code> denotes <code>forward_iterator_tag</code> if <code>I</code> 
<del>models</del><ins>satisfies</ins> <code>forward_iterator</code>; otherwise it denotes <code>input_iterator_tag</code>.</p></li>
<li><p>(1.2) &mdash; <code>iterator_category</code> denotes <code>forward_iterator_tag</code> if 
<code>iterator_traits&lt;I&gt;::iterator_category</code> <del>models</del><ins>satisfies</ins> 
<code>derived_from&lt;forward_iterator_tag&gt;</code>; otherwise it denotes <code>input_iterator_tag</code>.</p></li>
<li><p>(1.3) &mdash; [&hellip;]</p></li>
</ol>
</p>
</blockquote>
</li>

<li><p>Modify 24.5.5.5 <a href="https://wg21.link/common.iter.nav">[common.iter.nav]</a> as indicated:</p>

<blockquote>
<pre>
decltype(auto) operator++(int);
</pre>
<blockquote>
<p>
-4- <i>Preconditions:</i> [&hellip;]
<p/>
-5- <i>Effects:</i> If <code>I</code> <del>models</del><ins>satisfies</ins> <code>forward_iterator</code>, equivalent to:
</p>
<blockquote><pre>
common_iterator tmp = *this;
++*this;
return tmp;
</pre></blockquote>
<p>
Otherwise, equivalent to <code>return get&lt;I&gt;(v_)++;</code>
</p>
</blockquote>
</blockquote>
</li>

<li><p>Modify 25.3.2 <a href="https://wg21.link/range.access.begin">[range.access.begin]</a> as indicated:</p>

<blockquote>
<p>
-1- The name <code>ranges::begin</code> denotes a customization point object (16.3.3.3.5 <a href="https://wg21.link/customization.point.object">[customization.point.object]</a>). 
Given a subexpression <code>E</code> and an lvalue <code>t</code> that denotes the same object as <code>E</code>, if <code>E</code> 
is an rvalue and <code>enable_safe_range&lt;remove_cvref_t&lt;decltype((E))&gt;&gt;</code> is <code>false</code>, 
<code>ranges::begin(E)</code> is ill-formed. Otherwise, <code>ranges::begin(E)</code> is expression-equivalent to:
</p>
<ol style="list-style-type: none">
<li><p>(1.1) &mdash; [&hellip;]</p></li>
<li><p>(1.2) &mdash; Otherwise, <code><i>decay-copy</i>(t.begin())</code> if it is a 
valid expression and its type <code>I</code> <del>models</del><ins>satisfies</ins> <code>input_or_output_iterator</code>.</p></li>
<li><p>(1.3) &mdash; Otherwise, <code><i>decay-copy</i>(begin(t))</code> if it is a valid expression and its 
type <code>I</code> <del>models</del><ins>satisfies</ins> <code>input_or_output_iterator</code> with overload resolution 
performed in a context that includes the declarations:</p>
<blockquote><pre>
template&lt;class T&gt; void begin(T&amp;&amp;) = delete;
template&lt;class T&gt; void begin(initializer_list&lt;T&gt;&amp;&amp;) = delete;
</pre></blockquote>
<p>
and does not include a declaration of <code>ranges::begin</code>.
</p>
</li>
<li><p>(1.4) &mdash; [&hellip;]</p></li>
</ol>
</blockquote>
</li>

<li><p>Modify 25.3.3 <a href="https://wg21.link/range.access.end">[range.access.end]</a> as indicated:</p>

<blockquote>
<p>
-1- The name <code>ranges::end</code> denotes a customization point object (16.3.3.3.5 <a href="https://wg21.link/customization.point.object">[customization.point.object]</a>). 
Given a subexpression <code>E</code> and an lvalue <code>t</code> that denotes the same object as <code>E</code>, if <code>E</code> 
is an rvalue and <code>enable_safe_range&lt;remove_cvref_t&lt;decltype((E))&gt;&gt;</code> is <code>false</code>, 
<code>ranges::end(E)</code> is ill-formed. Otherwise, <code>ranges::end(E)</code> is expression-equivalent to:
</p>
<ol style="list-style-type: none">
<li><p>(1.1) &mdash; [&hellip;]</p></li>
<li><p>(1.2) &mdash; Otherwise, <code><i>decay-copy</i>(t.end())</code> if it is a valid expression and its type 
<code>S</code> <del>models</del><ins>satisfies</ins> <code>sentinel_for&lt;decltype(ranges::begin(E))&gt;</code>.</p></li>
<li><p>(1.3) &mdash; Otherwise, <code><i>decay-copy</i>(end(t))</code> if it is a valid expression and its 
type <code>S</code> <del>models</del><ins>satisfies</ins> <code>sentinel_for&lt;decltype(ranges::begin(E))&gt;</code> 
with overload resolution performed in a context that includes the declarations:
<blockquote><pre>
template&lt;class T&gt; void end(T&amp;&amp;) = delete;
template&lt;class T&gt; void end(initializer_list&lt;T&gt;&amp;&amp;) = delete;
</pre></blockquote>
and does not include a declaration of <code>ranges::end</code>.</p></li>
<li><p>(1.4) &mdash; [&hellip;]</p></li>
</ol>
</blockquote>
</li>

<li><p>Modify 25.3.6 <a href="https://wg21.link/range.access.rbegin">[range.access.rbegin]</a> as indicated:</p>

<blockquote>
<p>
-1- The name <code>ranges::rbegin</code> denotes a customization point object (16.3.3.3.5 <a href="https://wg21.link/customization.point.object">[customization.point.object]</a>). 
Given a subexpression <code>E</code> and an lvalue <code>t</code> that denotes the same object as <code>E</code>, if <code>E</code> 
is an rvalue and <code>enable_safe_range&lt;remove_cvref_t&lt;decltype((E))&gt;&gt;</code> is <code>false</code>, 
<code>ranges::rbegin(E)</code> is ill-formed. Otherwise, <code>ranges::rbegin(E)</code> is expression-equivalent to:
</p>
<ol style="list-style-type: none">
<li><p>(1.1) &mdash; <code><i>decay-copy</i>(t.rbegin())</code> if it is a valid expression and its type 
<code>I</code> <del>models</del><ins>satisfies</ins> <code>input_or_output_iterator</code>.</p></li>
<li><p>(1.2) &mdash; Otherwise, <code><i>decay-copy</i>(rbegin(t))</code> if it is a valid expression and its 
type <code>I</code> <del>models</del><ins>satisfies</ins> <code>input_or_output_iterator</code> with overload resolution 
performed in a context that includes the declaration:
<blockquote><pre>
template&lt;class T&gt; void rbegin(T&amp;&amp;) = delete;
</pre></blockquote>
and does not include a declaration of <code>ranges::rbegin</code>.</p></li>
<li><p>(1.3) &mdash; Otherwise, <code>make_reverse_iterator(ranges::end(t))</code> if both 
<code>ranges::begin(t)</code> and <code>ranges::end(t)</code> are valid expressions of the same type <code>I</code> 
which <del>models</del><ins>satisfies</ins> <code>bidirectional_iterator</code> (24.3.4.12 <a href="https://wg21.link/iterator.concept.bidir">[iterator.concept.bidir]</a>).
</p></li>
<li><p>(1.4) &mdash; [&hellip;]</p></li>
</ol>
</blockquote>
</li>

<li><p>Modify 25.3.7 <a href="https://wg21.link/range.access.rend">[range.access.rend]</a> as indicated:</p>

<blockquote>
<p>
-1- The name <code>ranges::rend</code> denotes a customization point object (16.3.3.3.5 <a href="https://wg21.link/customization.point.object">[customization.point.object]</a>). 
Given a subexpression <code>E</code> and an lvalue <code>t</code> that denotes the same object as <code>E</code>, if <code>E</code> 
is an rvalue and <code>enable_safe_range&lt;remove_cvref_t&lt;decltype((E))&gt;&gt;</code> is <code>false</code>, 
<code>ranges::rend(E)</code> is ill-formed. Otherwise, <code>ranges::rend(E)</code> is expression-equivalent to:
</p>
<ol style="list-style-type: none">
<li><p>(1.1) &mdash; <code><i>decay-copy</i>(t.rend())</code> if it is a valid expression and its type <code>S</code> 
<del>models</del><ins>satisfies</ins> <code>sentinel_for&lt;decltype(ranges::rbegin(E))&gt;</code>.</p></li>
<li><p>(1.2) &mdash; Otherwise, <code><i>decay-copy</i>(rend(t))</code> if it is a valid expression and its 
type <code>S</code> <del>models</del><ins>satisfies</ins> <code>sentinel_for&lt;decltype(ranges::rbegin(E))&gt;</code> 
with overload resolution performed in a context that includes the declaration:
<blockquote><pre>
template&lt;class T&gt; void rend(T&amp;&amp;) = delete;
</pre></blockquote>
and does not include a declaration of <code>ranges::rend</code>.</p></li>
<li><p>(1.3) &mdash; Otherwise, <code>make_reverse_iterator(ranges::begin(t))</code> if both 
<code>ranges::begin(t)</code> and <code>ranges::end(t)</code> are valid expressions of the same type <code>I</code> 
which <del>models</del><ins>satisfies</ins> <code>bidirectional_iterator</code> 
(24.3.4.12 <a href="https://wg21.link/iterator.concept.bidir">[iterator.concept.bidir]</a>).
</p></li>
<li><p>(1.4) &mdash; [&hellip;]</p></li>
</ol>
</blockquote>
</li>

<li><p>Modify 25.3.10 <a href="https://wg21.link/range.prim.size">[range.prim.size]</a> as indicated:</p>

<blockquote class="note">
<p>
[<i>Drafting note:</i> The term "is integer-like" is very specifically defined to be related to
semantic requirements as well, and the term "satisfy integer-like" seems to be undefined.
Fortunately, 24.3.4.4 <a href="https://wg21.link/iterator.concept.winc">[iterator.concept.winc]</a> also introduces the exposition-only variable
template <code><i>is-integer-like</i></code> which we use as predicate below to describe the syntactic 
constraints of "integer-like" alone. This wording change regarding "is integer-like" is strictly
speaking not required because of the "if and only if" definition provided in 
24.3.4.4 <a href="https://wg21.link/iterator.concept.winc">[iterator.concept.winc]</a> p12, but it has been made nonetheless to improve the 
consistency between discriminating compile-time tests from potentially semantic requirements]
</p>
</blockquote>

<blockquote>
<p>
-1- The name <code>size</code> denotes a customization point object (16.3.3.3.5 <a href="https://wg21.link/customization.point.object">[customization.point.object]</a>). 
The expression <code>ranges::size(E)</code> for some subexpression <code>E</code> with type <code>T</code> is 
expression-equivalent to:
</p>
<ol style="list-style-type: none">
<li><p>(1.1) &mdash; [&hellip;]</p></li>
<li><p>(1.2) &mdash; Otherwise, if <code>disable_sized_range&lt;remove_cv_t&lt;T&gt;&gt;</code> 
(25.4.4 <a href="https://wg21.link/range.sized">[range.sized]</a>) is <code>false</code>:</p>
<ol style="list-style-type: none">
<li><p>(1.2.1) &mdash; <code><i>decay-copy</i>(E.size())</code> if it is a valid expression and <del>its type <code>I</code> 
is integer-like</del><ins><code><i>is-integer-like</i>&lt;I&gt;</code> is <code>true</code></ins> 
(24.3.4.4 <a href="https://wg21.link/iterator.concept.winc">[iterator.concept.winc]</a>).</p></li>
<li><p>(1.2.2) &mdash; Otherwise, <code><i>decay-copy</i>(size(E))</code> if it is a valid expression and <del>its type 
<code>I</code> is integer-like</del><ins><code><i>is-integer-like</i>&lt;I&gt;</code> is <code>true</code></ins> with 
overload resolution performed in a context that includes the declaration:
<blockquote><pre>
template&lt;class T&gt; void size(T&amp;&amp;) = delete;
</pre></blockquote>
and does not include a declaration of <code>ranges::size</code>.</p></li>
</ol>
</li>
<li><p>(1.3) &mdash; Otherwise, <code><i>make-unsigned-like</i>(ranges::end(E) - ranges::begin(E))</code> 
(25.5.4 <a href="https://wg21.link/range.subrange">[range.subrange]</a>) if it is a valid expression and the types <code>I</code> and <code>S</code> of 
<code>ranges::begin(E)</code> and <code>ranges::end(E)</code> (respectively) <del>model</del><ins>satisfy</ins> both
<code>sized_sentinel_for&lt;S, I&gt;</code> (24.3.4.8 <a href="https://wg21.link/iterator.concept.sizedsentinel">[iterator.concept.sizedsentinel]</a>) and 
<code>forward_iterator&lt;I&gt;</code>. However, <code>E</code> is evaluated only once.
</p></li>
<li><p>(1.4) &mdash; [&hellip;]</p></li>
</ol>
</blockquote>
</li>

<li><p>Modify 25.3.13 <a href="https://wg21.link/range.prim.empty">[range.prim.empty]</a> as indicated:</p>

<blockquote>
<p>
-1- The name <code>empty</code> denotes a customization point object (16.3.3.3.5 <a href="https://wg21.link/customization.point.object">[customization.point.object]</a>). 
The expression <code>ranges::empty(E)</code> for some subexpression <code>E</code> is expression-equivalent to:
</p>
<ol style="list-style-type: none">
<li><p>(1.1) &mdash; [&hellip;]</p></li>
<li><p>(1.2) &mdash; [&hellip;]</p></li>
<li><p>(1.3) &mdash; Otherwise, <code>EQ</code>, where <code>EQ</code> is <code>bool(ranges::begin(E) == ranges::end(E))</code> 
except that <code>E</code> is only evaluated once, if <code>EQ</code> is a valid expression and the type of 
<code>ranges::begin(E)</code> <del>models</del><ins>satisfies</ins> <code>forward_iterator</code>.
</p></li>
<li><p>(1.4) &mdash; [&hellip;]</p></li>
</ol>
</blockquote>
</li>

<li><p>Modify 25.3.14 <a href="https://wg21.link/range.prim.data">[range.prim.data]</a> as indicated:</p>

<blockquote>
<p>
-1- The name <code>data</code> denotes a customization point object (16.3.3.3.5 <a href="https://wg21.link/customization.point.object">[customization.point.object]</a>). 
The expression <code>ranges::data(E)</code> for some subexpression <code>E</code> is expression-equivalent to:
</p>
<ol style="list-style-type: none">
<li><p>(1.1) &mdash; [&hellip;]</p></li>
<li><p>(1.2) &mdash; Otherwise, if <code>ranges::begin(E)</code> is a valid expression whose type 
<del>models</del><ins>satisfies</ins> <code>contiguous_iterator</code>, <code>to_address(ranges::begin(E))</code>.</p></li>
<li><p>(1.3) &mdash; [&hellip;]</p></li>
</ol>
</blockquote>
</li>


<li><p>Modify 25.5.5 <a href="https://wg21.link/range.dangling">[range.dangling]</a> as indicated:</p>

<blockquote>
<p>
-1- The tag type <code>dangling</code> is used together with the template aliases <code>safe_iterator_t</code> 
and <code>safe_subrange_t</code> to indicate that an algorithm that typically returns an iterator into or 
subrange of a range argument does not return an iterator or subrange which could potentially reference 
a range whose lifetime has ended for a particular rvalue range argument which does not 
<del>model</del><ins>satisfy</ins> <code><i>forwarding-range</i></code> (25.4.2 <a href="https://wg21.link/range.range">[range.range]</a>).
</p>
[&hellip;]
<p>
-2- [<i>Example:</i>
</p>
<blockquote><pre>
vector&lt;int&gt; f();
auto result1 = ranges::find(f(), 42); <i>// #1</i>
static_assert(same_as&lt;decltype(result1), ranges::dangling&gt;);
auto vec = f();
auto result2 = ranges::find(vec, 42); <i>// #2</i>
static_assert(same_as&lt;decltype(result2), vector&lt;int&gt;::iterator&gt;);
auto result3 = ranges::find(subrange{vec}, 42); <i>// #3</i>
static_assert(same_as&lt;decltype(result3), vector&lt;int&gt;::iterator&gt;);
</pre></blockquote>
<p>
The call to <code>ranges::find</code> at <i>#1</i> returns <code>ranges::dangling</code> since <code>f()</code> is 
an rvalue <code>vector</code>; the <code>vector</code> could potentially be destroyed before a returned iterator 
is dereferenced. However, the calls at <i>#2</i> and <i>#3</i> both return iterators since the lvalue 
<code>vec</code> and specializations of subrange <del>model</del><ins>satisfy</ins> 
<code><i>forwarding-range</i></code>. &mdash; <i>end example</i>]
</p>
</blockquote>
</li>

<li><p>Modify 25.6.4.3 <a href="https://wg21.link/range.iota.iterator">[range.iota.iterator]</a> as indicated:</p>

<blockquote>
<p>
-1- <code>iterator::iterator_category</code> is defined as follows:
<ol style="list-style-type: none">
<li><p>(1.1) &mdash; If <code>W</code> <del>models</del><ins>satisfies</ins> <code><i>advanceable</i></code>, then 
<code>iterator_category</code> is <code>random_access_iterator_tag</code>.</p></li>
<li><p>(1.2) &mdash; Otherwise, if <code>W</code> <del>models</del><ins>satisfies</ins> <code><i>decrementable</i></code>, 
then <code>iterator_category</code> is <code>bidirectional_iterator_tag</code>.</p></li>
<li><p>(1.3) &mdash; Otherwise, if <code>W</code> <del>models</del><ins>satisfies</ins> <code>incrementable</code>, 
then <code>iterator_category</code> is <code>forward_iterator_tag</code>.</p></li>
<li><p>(1.4) &mdash; Otherwise, <code>iterator_category</code> is <code>input_iterator_tag</code>.</p></li>
</ol>
</p>
</blockquote>
</li>

<li><p>Modify  [range.semi.wrap] as indicated:</p>

<blockquote>
<p>
-1- Many types in this subclause are specified in terms of an exposition-only class template 
<code><i>semiregular-box</i></code>. <code><i>semiregular-box</i>&lt;T&gt;</code> behaves exactly like 
<code>optional&lt;T&gt;</code> with the following differences:
<ol style="list-style-type: none">
<li><p>(1.1) &mdash; [&hellip;]</p></li>
<li><p>(1.2) &mdash; If <code>T</code> <del>models</del><ins>satisfies</ins> <code>default_constructible</code>, 
the default constructor of <code><i>semiregular-box</i>&lt;T&gt;</code> is equivalent to: [&hellip;]</p></li>
<li><p>(1.3) &mdash; If <code>assignable_from&lt;T&amp;, const T&amp;&gt;</code> is not 
<del>modeled</del><ins>satisfied</ins>, the copy assignment operator is equivalent to: [&hellip;]</p></li>
<li><p>(1.4) &mdash; If <code>assignable_from&lt;T&amp;, T&gt;</code> is not <del>modeled</del><ins>satisfied</ins>, 
the move assignment operator is equivalent to: [&hellip;]</p></li>
</ol>
</p>
</blockquote>
</li>

<li><p>Modify 25.7.6 <a href="https://wg21.link/range.all">[range.all]</a> as indicated:</p>

<blockquote>
<p>
-2- The name <code>views::all</code> denotes a range adaptor object (25.7.2 <a href="https://wg21.link/range.adaptor.object">[range.adaptor.object]</a>). 
For some subexpression <code>E</code>, the expression <code>views::all(E)</code> is expression-equivalent to:
<ol style="list-style-type: none">
<li><p>(2.1) &mdash; <code><i>decay-copy</i>(E)</code> if the decayed type of <code>E</code> 
<del>models</del><ins>satisfies</ins> <code>view</code>.</p></li>
<li><p>(2.2) &mdash; [&hellip;]</p></li>
<li><p>(2.3) &mdash; [&hellip;]</p></li>
</ol>
</p>
</blockquote>
</li>

<li><p>Modify 25.7.8.3 <a href="https://wg21.link/range.filter.iterator">[range.filter.iterator]</a> as indicated:</p>

<blockquote>
<p>
-2- <code>iterator::iterator_concept</code> is defined as follows:
<ol style="list-style-type: none">
<li><p>(2.1) &mdash; If <code>V</code> <del>models</del><ins>satisfies</ins> <code>bidirectional_range</code>, 
then <code>iterator_concept</code> denotes <code>bidirectional_iterator_tag</code>.</p></li>
<li><p>(2.2) &mdash; Otherwise, if <code>V</code> <del>models</del><ins>satisfies</ins> <code>forward_range</code>, 
then <code>iterator_concept</code> denotes <code>forward_iterator_tag</code>.</p></li>
<li><p>(2.3) &mdash; [&hellip;]</p></li>
</ol>
<p/>
-3- <code>iterator::iterator_category</code> is defined as follows:
<ol style="list-style-type: none">
<li><p>(3.1) &mdash; Let <code>C</code> denote the type <code>iterator_traits&lt;iterator_t&lt;V&gt;&gt;::iterator_category</code>.</p></li>
<li><p>(3.2) &mdash; If <code>C</code> <del>models</del><ins>satisfies</ins> 
<code>derived_from&lt;bidirectional_iterator_tag&gt;</code>, then <code>iterator_category</code> denotes 
<code>bidirectional_iterator_tag</code>.</p></li>
<li><p>(3.3) &mdash; Otherwise, if <code>C</code> <del>models</del><ins>satisfies</ins> 
<code>derived_from&lt;forward_iterator_tag&gt;</code>, then <code>iterator_category</code> denotes <code>forward_iterator_tag</code>.</p></li>
<li><p>(3.4) &mdash; [&hellip;]</p></li>
</ol>
</p>
</blockquote>
</li>

<li><p>Modify 25.7.9.3 <a href="https://wg21.link/range.transform.iterator">[range.transform.iterator]</a> as indicated:</p>

<blockquote>
<p>
-1- <code>iterator::iterator_concept</code> is defined as follows:
<ol style="list-style-type: none">
<li><p>(1.1) &mdash; If <code>V</code> <del>models</del><ins>satisfies</ins> <code>random_access_range</code>, then 
<code>iterator_concept</code> denotes <code>random_access_iterator_tag</code>.</p></li>
<li><p>(1.2) &mdash; Otherwise, if <code>V</code> <del>models</del><ins>satisfies</ins> <code>bidirectional_range</code>, 
then <code>iterator_concept</code> denotes <code>bidirectional_iterator_tag</code>.</p></li>
<li><p>(1.3) &mdash; Otherwise, if <code>V</code> <del>models</del><ins>satisfies</ins> <code>forward_range</code>, 
then <code>iterator_concept</code> denotes <code>forward_iterator_tag</code>.</p></li>
<li><p>(1.4) &mdash; [&hellip;]</p></li>
</ol>
<p/>
-2- Let <code>C</code> denote the type <code>iterator_traits&lt;iterator_t&lt;Base&gt;&gt;::iterator_category</code>. 
If <code>C</code> <del>models</del><ins>satisfies</ins> <code>derived_from&lt;contiguous_iterator_tag&gt;</code>, 
then <code>iterator_category</code> denotes <code>random_access_iterator_tag</code>; otherwise, <code>iterator_category</code> 
denotes <code>C</code>.
</p>
</blockquote>
</li>

<li><p>Modify 25.7.14.3 <a href="https://wg21.link/range.join.iterator">[range.join.iterator]</a> as indicated:</p>

<blockquote>
<p>
-1- <code>iterator::iterator_concept</code> is defined as follows:
<ol style="list-style-type: none">
<li><p>(1.1) &mdash; If <code>ref_is_glvalue</code> is <code>true</code> and <code>Base</code> and 
<code>range_reference_t&lt;Base&gt;</code> each <del>model</del><ins>satisfy</ins> 
<code>bidirectional_range</code>, then <code>iterator_concept</code> denotes <code>bidirectional_iterator_tag</code>.</p></li>
<li><p>(1.2) &mdash; Otherwise, if <code>ref_is_glvalue</code> is <code>true</code> and <code>Base</code> and 
<code>range_reference_t&lt;Base&gt;</code> each <del>model</del><ins>satisfy</ins> 
<code>forward_range</code>, then <code>iterator_concept</code> denotes <code>forward_iterator_tag</code>.</p></li>
<li><p>(1.3) &mdash; [&hellip;]</p></li>
</ol>
<p/>
-2- <code>iterator::iterator_category</code> is defined as follows:
<ol style="list-style-type: none">
<li><p>(2.1) &mdash; Let [&hellip;]</p></li>
<li><p>(2.2) &mdash; If <code>ref_is_glvalue</code> is <code>true</code> and <code><i>OUTERC</i></code> and 
<code><i>INNERC</i></code> each <del>model</del><ins>satisfy</ins> 
<code>derived_from&lt;bidirectional_iterator_tag&gt;</code>, <code>iterator_category</code> denotes 
<code>bidirectional_iterator_tag</code>.</p></li>
<li><p>(2.3) &mdash; Otherwise, if <code>ref_is_glvalue</code> is <code>true</code> and <code><i>OUTERC</i></code> 
and <code><i>INNERC</i></code> each <del>model</del><ins>satisfy</ins> 
<code>derived_from&lt;forward_iterator_tag&gt;</code>, <code>iterator_category</code> denotes 
<code>forward_iterator_tag</code>.</p></li>
<li><p>(2.4) &mdash; Otherwise, if <code><i>OUTERC</i></code> and <code><i>INNERC</i></code> each 
<del>model</del><ins>satisfy</ins> <code>derived_from&lt;input_iterator_tag&gt;</code>, 
<code>iterator_category</code> denotes <code>input_iterator_tag</code>.</p></li>
<li><p>(2.5) &mdash; [&hellip;]</p></li>
</ol>
</p>
</blockquote>
</li>

<li><p>Modify  [range.split.outer] as indicated:</p>

<blockquote>
<pre>
[&hellip;]
Parent* parent_ = nullptr; <i>// exposition only</i>
iterator_t&lt;Base&gt; current_ = <i>// exposition only, present only if <code>V</code> <del>models</del><ins>satisfies</ins> <code>forward_range</code></i>
  iterator_t&lt;Base&gt;();
[&hellip;]
</pre>
<p>
-1- Many of the following specifications refer to the notional member <code><i>current</i></code> of 
<code>outer_iterator</code>. <code><i>current</i></code> is equivalent to <code>current_</code> if <code>V</code> 
<del>models</del><ins>satisfies</ins> <code>forward_range</code>, and <code>parent_-&gt;current_</code> otherwise.
</p>
</blockquote>
</li>


<li><p>Modify  [range.split.inner] as indicated:</p>

<blockquote>
<p>
-1- The <i>typedef-name</i> <code>iterator_category</code> denotes
</p>
<ol style="list-style-type: none">
<li><p>(1.1) &mdash; <code>forward_iterator_tag</code> if 
<code>iterator_traits&lt;iterator_t&lt;Base&gt;&gt;::iterator_category</code> <del>models</del><ins>satisfies</ins> 
<code>derived_from&lt;forward_iterator_tag&gt;</code>;</p></li>
<li><p>(1.2) &mdash; otherwise, <code>iterator_traits&lt;iterator_t&lt;Base&gt;&gt;::iterator_category</code>.</p></li>
</ol> 
</blockquote>
</li>

<li><p>Modify 25.7.19 <a href="https://wg21.link/range.counted">[range.counted]</a> as indicated:</p>

<blockquote>
<p>
-2- The name <code>views::counted</code> denotes a customization point object (16.3.3.3.5 <a href="https://wg21.link/customization.point.object">[customization.point.object]</a>). 
Let <code>E</code> and <code>F</code> be expressions, and let <code>T</code> be <code>decay_t&lt;decltype((E))&gt;</code>. Then 
the expression <code>views::counted(E, F)</code> is expression-equivalent to:
<ol style="list-style-type: none">
<li><p>(2.1) &mdash; If <code>T</code> <del>models</del><ins>satisfies</ins> <code>input_or_output_iterator</code> 
and <code>decltype((F))</code> <del>models</del><ins>satisfies</ins> <code>convertible_to&lt;iter_difference_t&lt;T&gt;&gt;</code>,</p>
<ol style="list-style-type: none">
<li><p>(2.1.1) &mdash; <code>subrange{E, E + static_cast&lt;iter_difference_t&lt;T&gt;&gt;(F)}</code> if <code>T</code> 
<del>models</del><ins>satisfies</ins> <code>random_access_iterator</code>.</p></li>
<li><p>(2.1.2) &mdash; [&hellip;]</p></li>
</ol>
</li>
<li><p>(2.2) &mdash; [&hellip;]</p></li>
</ol>
</p>
</blockquote>
</li>

<li><p>Modify  [range.common.adaptor] as indicated:</p>

<blockquote>
<p>
-1- The name <code>views::common denotes</code> a range adaptor object (25.7.2 <a href="https://wg21.link/range.adaptor.object">[range.adaptor.object]</a>). 
For some subexpression <code>E</code>, the expression <code>views::common(E)</code> is expression-equivalent to:
<ol style="list-style-type: none">
<li><p>(1.1) &mdash; <code>views::all(E)</code>, if <code>decltype((E))</code> <del>models</del><ins>satisfies</ins> 
<code>common_range</code> and <code>views::all(E)</code> is a well-formed expression.</p></li>
<li><p>(1.2) &mdash; [&hellip;]</p></li>
</ol>
</p>
</blockquote>
</li>

<li><p>Modify 26.6.13 <a href="https://wg21.link/alg.equal">[alg.equal]</a> as indicated:</p>

<blockquote>
<pre>
template&lt;class InputIterator1, class InputIterator2&gt;
  constexpr bool equal(InputIterator1 first1, InputIterator1 last1,
                       InputIterator2 first2);
[&hellip;]
template&lt;input_range R1, input_range R2, class Pred = ranges::equal_to,
          class Proj1 = identity, class Proj2 = identity&gt;
  requires indirectly_comparable&lt;iterator_t&lt;R1&gt;, iterator_t&lt;R2&gt;, Pred, Proj1, Proj2&gt;
  constexpr bool ranges::equal(R1&amp;&amp; r1, R2&amp;&amp; r2, Pred pred = {},
                               Proj1 proj1 = {}, Proj2 proj2 = {});
</pre>
<blockquote>
<p>
[&hellip;]
<p/>
-3- <i>Complexity:</i> If the types of <code>first1</code>, <code>last1</code>, <code>first2</code>, and <code>last2</code>:
<ol style="list-style-type: none">
<li><p>(3.1) &mdash; meet the <i>Cpp17RandomAccessIterator</i> requirements (24.3.5.7 <a href="https://wg21.link/random.access.iterators">[random.access.iterators]</a>) 
for the overloads in namespace <code>std</code>, or</p></li>
<li><p>(3.2) &mdash; pairwise <del>model</del><ins>satisfy</ins> <code>sized_sentinel_for</code> 
(24.3.4.8 <a href="https://wg21.link/iterator.concept.sizedsentinel">[iterator.concept.sizedsentinel]</a>) for the overloads in namespace <code>ranges</code>, and 
<code>last1 - first1 != last2 - first2</code>, then no applications of the corresponding predicate and
each projection; otherwise,</p></li>
<li><p>(3.3) &mdash; [&hellip;]</p></li>
<li><p>(3.4) &mdash; [&hellip;]</p></li>
</ol>
</p>
</blockquote>
</blockquote>
</li>

<li><p>Modify 26.6.14 <a href="https://wg21.link/alg.is.permutation">[alg.is.permutation]</a> as indicated:</p>

<blockquote>
<pre>
template&lt;forward_iterator I1, sentinel_for&lt;I1&gt; S1, forward_iterator I2,
         sentinel_for&lt;I2&gt; S2, class Pred = ranges::equal_to, class Proj1 = identity,
         class Proj2 = identity&gt;
  requires indirectly_comparable&lt;I1, I2, Pred, Proj1, Proj2&gt;
  constexpr bool ranges::is_permutation(I1 first1, S1 last1, I2 first2, S2 last2,
                                        Pred pred = {},
                                        Proj1 proj1 = {}, Proj2 proj2 = {});
template&lt;forward_range R1, forward_range R2, class Pred = ranges::equal_to,
         class Proj1 = identity, class Proj2 = identity&gt;
  requires indirectly_comparable&lt;iterator_t&lt;R1&gt;, iterator_t&lt;R2&gt;, Pred, Proj1, Proj2&gt;
  constexpr bool ranges::is_permutation(R1&amp;&amp; r1, R2&amp;&amp; r2, Pred pred = {},
                                        Proj1 proj1 = {}, Proj2 proj2 = {});
</pre>
<blockquote>
<p>
[&hellip;]
<p/>
-7- <i>Complexity:</i> No applications of the corresponding predicate and projections if:
<ol style="list-style-type: none">
<li><p>(7.1) &mdash; <code>S1</code> and <code>I1</code> <del>model</del><ins>satisfy</ins> 
<code>sized_sentinel_for&lt;S1, I1&gt;</code>,</p></li>
<li><p>(7.2) &mdash; <code>S2</code> and <code>I2</code> <del>model</del><ins>satisfy</ins> 
<code>sized_sentinel_for&lt;S2, I2&gt;</code>, and</p></li>
<li><p>(7.3) &mdash; [&hellip;]</p></li>
</ol>
</p>
</blockquote>
</blockquote>
</li>

<li><p>Modify 26.8.5 <a href="https://wg21.link/alg.partitions">[alg.partitions]</a> as indicated:</p>

<blockquote>
<pre>
template&lt;class ForwardIterator, class Predicate&gt;
  constexpr ForwardIterator
    partition(ForwardIterator first, ForwardIterator last, Predicate pred);
[&hellip;]
template&lt;forward_range R, class Proj = identity,
         indirect_unary_predicate&lt;projected&lt;iterator_t&lt;R&gt;, Proj&gt;&gt; Pred&gt;
  requires permutable&lt;iterator_t&lt;R&gt;&gt;
  constexpr safe_subrange_t&lt;R&gt;
    ranges::partition(R&amp;&amp; r, Pred pred, Proj proj = {});
</pre>
<blockquote>
<p>
[&hellip;]
<p/>
-8- <i>Complexity:</i> Let <code><i>N</i> = last - first</code>:
<ol style="list-style-type: none">
<li><p>(8.1) &mdash; For the overload with no <code>ExecutionPolicy</code>, exactly <code><i>N</i></code> 
applications of the predicate and projection. At most <code><i>N</i>/2</code> swaps if the type of 
<code>first</code> meets the <i>Cpp17BidirectionalIterator</i> requirements for the
overloads in namespace <code>std</code> or <del>models</del><ins>satisfies</ins> <code>bidirectional_iterator</code> 
for the overloads in namespace <code>ranges</code>, and at most <code><i>N</i></code> swaps otherwise.</p></li>
<li><p>(8.2) [&hellip;]</p></li>
</ol>
</p>
</blockquote>
</blockquote>
</li>

</ol>
</blockquote>

<p><i>[2020-02-10, Prague; Daniel comments]</i></p>

<p>
I expect that <a href="https://wg21.link/p2101r0">P2101R0</a> (See 
<a href="https://wiki.edg.com/pub/Wg21prague/LibraryWorkingGroup/d2101r0.html">D2101R0</a>)
is going to resolve this issue.
<p/>
This proposal should also resolve the corresponding NB comments
<a href="https://github.com/cplusplus/nbballot/issues/294">US-298</a>
and <a href="https://github.com/cplusplus/nbballot/issues/296">US-300</a>.
</p>

<p><i>[2020-05-01; reflector discussions]</i></p>

<p>
Resolved by <a href="https://wg21.link/p2101r0">P2101R0</a> voted in in Prague.
</p>



<p id="res-3345"><b>Proposed resolution:</b></p>
<p>
Resolved by <a href="https://wg21.link/p2101r0">P2101R0</a>.
</p>




</body>
</html>
