<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Issue 2439: unique_copy() sometimes can't fall back to reading its output</title>
<meta property="og:title" content="Issue 2439: unique_copy() sometimes can't fall back to reading its output">
<meta property="og:description" content="C++ library issue. Status: C++17">
<meta property="og:url" content="https://cplusplus.github.io/LWG/issue2439.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#C++17">C++17</a> status.</em></p>
<h3 id="2439"><a href="lwg-defects.html#2439">2439</a>. <code>unique_copy()</code> sometimes can't fall back to reading its output</h3>
<p><b>Section:</b> 26.7.9 <a href="https://wg21.link/alg.unique">[alg.unique]</a> <b>Status:</b> <a href="lwg-active.html#C++17">C++17</a>
 <b>Submitter:</b> Stephan T. Lavavej <b>Opened:</b> 2014-10-01 <b>Last modified:</b> 2017-07-30</p>
<p><b>Priority: </b>3
</p>
<p><b>View other</b> <a href="lwg-index-open.html#alg.unique">active issues</a> in [alg.unique].</p>
<p><b>View all other</b> <a href="lwg-index.html#alg.unique">issues</a> in [alg.unique].</p>
<p><b>View all issues with</b> <a href="lwg-status.html#C++17">C++17</a> status.</p>
<p><b>Discussion:</b></p>
<p>
<code>unique_copy()</code>'s wording says that if it's given input-only and output-only iterators, it needs 
the input's value type to be copyable. This is correct, because in this case the algorithm must have a 
local element copy in order to detect duplicates.
<p/>
The wording also says that if it's given an <code>InputIterator</code> that's forward or stronger, the input's 
value type doesn't have to be copyable. This is also correct, because in this case the algorithm can reread 
the input in order to detect duplicates.
<p/>
Finally, the wording says that if it's given an input-only iterator with an <code>OutputIterator</code> that's 
forward or stronger, the input's value type doesn't have to be copyable. This is telling the algorithm to 
compare its input to its output in order to detect duplicates, but that isn't always possible! If the input 
and output have the same value type, then they can be compared (as long as <code>*result = *first</code> behaves 
sanely; see below). If they have different value types, then we can't compare them.
<p/>
This could be resolved by requiring heterogeneous value types to be comparable in this situation, but that 
would be extremely tricky to wordsmith (as it would challenge the concept of "group of equal elements" used 
by the Effects). It will be vastly simpler and more effective to extend the "local element copy" requirement 
to this scenario.
<p/>
Note that the input-only, output forward-or-stronger, identical value types scenario needs a bit of work too.  
We always require *result = *first to be "valid", but in this case we need to additionally require that the 
assignment actually transfers the value. (Otherwise, we'd be allowing an <code>op=()</code> that ignores <code>*first</code> 
and always sets <code>*result</code> to zero, or other unacceptable behavior.) This is just <code>CopyAssignable</code>.
<p/>
(What happens when <code>unique_copy()</code> is given a <code>move_iterator</code> is a separate issue.)
<p/>
To summarize:
</p>
<blockquote><p>
input forward+: no additional requirements
<p/>
input-only, output forward+, same value types: needs <code>CopyAssignable</code>
<p/>
input-only, output forward+, different value types: needs <code>CopyConstructible</code> and <code>CopyAssignable</code>
<p/>
input-only, output-only: needs <code>CopyConstructible</code> and <code>CopyAssignable</code>
</p></blockquote>

<p><i>[Urbana 2014-11-07: Move to Ready]</i></p>




<p id="res-2439"><b>Proposed resolution:</b></p>
<p>
This wording is relative to N3936.
</p>

<ol>
<li><p>Change 26.7.9 <a href="https://wg21.link/alg.unique">[alg.unique]</a> p5, as depicted:</p>

<blockquote>
<pre>
template&lt;class InputIterator, class OutputIterator>
OutputIterator
unique_copy(InputIterator first, InputIterator last,
            OutputIterator result);
template&lt;class InputIterator, class OutputIterator,
         class BinaryPredicate>
OutputIterator
unique_copy(InputIterator first, InputIterator last,
            OutputIterator result, BinaryPredicate pred);
</pre>
<blockquote>
<p>
-5- <i>Requires</i>: The comparison function shall be an equivalence relation. The ranges [<code>first,last</code>) and
[<code>result,result+(last-first)</code>) shall not overlap. The expression <code>*result = *first</code> shall be valid.
<del>If neither <code>InputIterator</code> nor <code>OutputIterator</code> meets the requirements of forward iterator then the
value type of <code>InputIterator</code> shall be <code>CopyConstructible</code> (Table 21) and <code>CopyAssignable</code> (Table 23).
Otherwise <code>CopyConstructible</code> is not required.</del><ins>Let <code>T</code> be the value type of <code>InputIterator</code>. 
If <code>InputIterator</code> meets the forward iterator requirements, then there are no additional requirements for <code>T</code>. 
Otherwise, if <code>OutputIterator</code> meets the forward iterator requirements and its value type is the same as <code>T</code>, 
then <code>T</code> shall be <code>CopyAssignable</code> (Table 23). Otherwise, <code>T</code> shall be both <code>CopyConstructible</code> 
(Table 21) and <code>CopyAssignable</code>.</ins>
</p>
</blockquote></blockquote></li>
</ol>






</body>
</html>
