<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Issue 1238: Defining algorithms taking iterator for range</title>
<meta property="og:title" content="Issue 1238: Defining algorithms taking iterator for range">
<meta property="og:description" content="C++ library issue. Status: Open">
<meta property="og:url" content="https://cplusplus.github.io/LWG/issue1238.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#Open">Open</a> status.</em></p>
<h3 id="1238"><a href="lwg-active.html#1238">1238</a>. Defining algorithms taking iterator for range</h3>
<p><b>Section:</b> 26 <a href="https://wg21.link/algorithms">[algorithms]</a> <b>Status:</b> <a href="lwg-active.html#Open">Open</a>
 <b>Submitter:</b> Alisdair Meredith <b>Opened:</b> 2009-10-15 <b>Last modified:</b> 2020-09-06</p>
<p><b>Priority: </b>3
</p>
<p><b>View other</b> <a href="lwg-index-open.html#algorithms">active issues</a> in [algorithms].</p>
<p><b>View all other</b> <a href="lwg-index.html#algorithms">issues</a> in [algorithms].</p>
<p><b>View all issues with</b> <a href="lwg-status.html#Open">Open</a> status.</p>
<p><b>Discussion:</b></p>
<p>
The library has many algorithms that take a source range represented by
a pair of iterators, and the start of some second sequence given by a
single iterator. Internally, these algorithms will produce undefined
behaviour if the second 'range' is not as large as the input range, but
none of the algorithms spell this out in Requires clauses, and there is
no catch-all wording to cover this in clause 17 or the front matter of
25.
</p>

<p>
There was an attempt to provide such wording in paper <a href="https://wg21.link/n2944">n2944</a>
but this seems incidental to the focus of the paper, and getting the wording of
this issue right seems substantially more difficult than the simple
approach taken in that paper.  Such wording will be removed from an
updated paper, and hopefully tracked via the LWG issues list instead.
</p>

<p>
It seems there are several classes of problems here and finding wording
to solve all in one paragraph could be too much.  I suspect we need
several overlapping requirements that should cover the desired range of
behaviours.
</p>

<p>
Motivating examples:
</p>

<p>
A good initial example is the <code>swap_ranges</code> algorithm.  Here there is a
clear requirement that <code>first2</code> refers to the start of a valid range at
least as long as the range <code>[first1, last1)</code>.  <a href="https://wg21.link/n2944">n2944</a> tries to solve this
by positing a hypothetical <code>last2</code> iterator that is implied by the
signature, and requires <code>distance(first2,last2) &lt; distance(first1,last1)</code>.
 This mostly works, although I am uncomfortable assuming that <code>last2</code> is
clearly defined and well known without any description of how to obtain
it (and I have no idea how to write that).
</p>

<p>
A second motivating example might be the <code>copy</code> algorithm.  Specifically,
let us image a call like:
</p>

<blockquote><pre>
copy(istream_iterator&lt;int&gt;(is),istream_iterator(),ostream_iterator&lt;int&gt;(os));
</pre></blockquote>

<p>
In this case, our input iterators are literally simple <code>InputIterators</code>,
and the destination is a simple <code>OutputIterator</code>.  In neither case am I
happy referring to <code>std::distance</code>, in fact it is not possible for the
<code>ostream_iterator</code> at all as it does not meet the requirements.  However,
any wording we provide must cover both cases.  Perhaps we might deduce
<code>last2 == ostream_iterator&lt;int&gt;{}</code>, but that might not always be valid for
user-defined iterator types.  I can well imagine an 'infinite range'
that writes to <code>/dev/null</code> and has no meaningful <code>last2</code>.
</p>

<p>
The motivating example in <a href="https://wg21.link/n2944">n2944</a> is <code>std::equal</code>, 
and that seems to fall somewhere between the two.
</p>

<p>
Outlying examples might be <code>partition_copy</code> that takes two output
iterators, and the <code>_n</code> algorithms where a range is specified by a
specific number of iterations, rather than traditional iterator pair. 
We should also <em>not</em> accidentally apply inappropriate constraints to
<code>std::rotate</code> which takes a third iterator that is not intended to be a
separate range at all.
</p>

<p>
I suspect we want some wording similar to:
</p>

<blockquote><p>
For algorithms that operate on ranges where the end iterator of the
second range is not specified, the second range shall contain at least
as many elements as the first.
</p></blockquote>

<p>
I don't think this quite captures the intent yet though.  I am not sure
if 'range' is the right term here rather than sequence.  More awkwardly,
I am not convinced we can describe an Output sequence such as produce by
an <code>ostream_iterator</code> as "containing elements", at least not as a
precondition to the call before they have been written.
</p>

<p>
Another idea was to describe require that the trailing iterator support
at least distance(input range) applications of <code>operator++</code> and may be
written through the same number of times if a mutable/output iterator.
</p>

<p>
We might also consider handling the case of an output range vs. an input
range in separate paragraphs, if that simplifies how we describe some of
these constraints.
</p>

<p><i>[
2009-11-03 Howard adds:
]</i></p>


<blockquote><p>
Moved to Tentatively NAD Future after 5 positive votes on c++std-lib.
</p></blockquote>

<p><i>[LEWG Kona 2017]</i></p>

<p>Recommend Open: The design is clear here; we just need wording</p>

<p><i>[2019-01-20 Reflector prioritization]</i></p>

<p>Set Priority to 3</p>


<p><b>Rationale:</b></p>
<p>
Does not have sufficient support at this time. May wish to reconsider for a
future standard.
</p>


<p id="res-1238"><b>Proposed resolution:</b></p>





</body>
</html>
