<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Issue 2279: Carefully state effects of list::splice function</title>
<meta property="og:title" content="Issue 2279: Carefully state effects of list::splice function">
<meta property="og:description" content="C++ library issue. Status: NAD">
<meta property="og:url" content="https://cplusplus.github.io/LWG/issue2279.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#NAD">NAD</a> status.</em></p>
<h3 id="2279"><a href="lwg-closed.html#2279">2279</a>. Carefully state effects of <code>list::splice</code> function</h3>
<p><b>Section:</b> 23.3.11.5 <a href="https://wg21.link/list.ops">[list.ops]</a>, 23.3.7.6 <a href="https://wg21.link/forward.list.ops">[forward.list.ops]</a> <b>Status:</b> <a href="lwg-active.html#NAD">NAD</a>
 <b>Submitter:</b> Arseny Klimovsky <b>Opened:</b> 2013-08-15 <b>Last modified:</b> 2023-02-07</p>
<p><b>Priority: </b>Not Prioritized
</p>
<p><b>View all other</b> <a href="lwg-index.html#list.ops">issues</a> in [list.ops].</p>
<p><b>View all issues with</b> <a href="lwg-status.html#NAD">NAD</a> status.</p>
<p><b>Discussion:</b></p>
<p>
I think that the effects of <code>list::splice</code> function should be stated more carefully.
<p/>
Function transferring a single element is described now in the following way (23.3.11.5 <a href="https://wg21.link/list.ops">[list.ops]</a> p7):
</p>

<blockquote>
<pre>
void splice(const_iterator position, list&amp; x, const_iterator i);
void splice(const_iterator position, list&amp;&amp; x, const_iterator i);
</pre>
<blockquote>
<p>
<i>Effects:</i> Inserts an element pointed to by <code>i</code> from list <code>x</code> before position and removes the element from
<code>x</code>. The result is unchanged if <code>position == i</code> or <code>position == ++i</code>. Pointers and references to <code>*i</code>
continue to refer to this same element but as a member of <code>*this</code>. Iterators to <code>*i</code> (including <code>i</code> itself)
continue to refer to the same element, but now behave as iterators into <code>*this</code>, not into <code>x</code>.
</p>
</blockquote>
</blockquote>

<p>
But it is incorrect to talk about <code>operator==</code> for iterators that are not from the same container (after acceptance of 
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3066.html">N3066</a>, 24.3.5.5 <a href="https://wg21.link/forward.iterators">[forward.iterators]</a> p2). 
So, the text operates with an undefined behaviour.
</p>

<p>
One is formally allowed to have list implementation where two iterators from different lists return true to <code>operator==</code>.
For example, this can only happen to non-dereferenceable iterators, and <code>position</code> and <code>++i</code> can be 
non-dereferenceable. So, literally according to the standard, it is not allowed in this implementation to transfer 
such elements with <code>splice</code> function.
</p>

<p><i>[2013-09 Chicago (late night issues)]</i></p>

<p>
Moved to NAD.
</p>
<p>
The condition under which the <code>list</code> is unchanged is not program code, so there is no undefined behavior to protect against.
Rather, the precondition that the evaluation can be performed is implicit if determining when the condition applies.
</p>



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

<ol>
<li><p>Modify  [forwardlist.ops] p6 as indicated:</p>

<blockquote>
<pre>
void splice_after(const_iterator position, forward_list&amp; x, const_iterator i);
void splice_after(const_iterator position, forward_list&amp;&amp; x, const_iterator i);
</pre>
<blockquote>
<p>
[&hellip;]
<p/>
-6- <i>Effects:</i> Inserts the element following <code>i</code> into <code>*this</code>, following <code>position</code>, 
and removes it from <code>x</code>. The result is unchanged if <ins><code>&amp;x == this</code> and the following 
condition is satisfied:</ins> <code>position == i</code> or <code>position == ++i</code>. Pointers and references to 
<code>*++i</code> continue to refer to the same element but as a member of <code>*this</code>. Iterators to <code>*++i</code> 
continue to refer to the same element, but now behave as iterators into <code>*this</code>, not into <code>x</code>.
</p>
</blockquote>
</blockquote>
</li>

<li><p>Modify 23.3.11.5 <a href="https://wg21.link/list.ops">[list.ops]</a> p7 as indicated:</p>

<blockquote>
<pre>
void splice(const_iterator position, list&amp; x, const_iterator i);
void splice(const_iterator position, list&amp;&amp; x, const_iterator i);
</pre>
<blockquote>
<p>
-7- <i>Effects:</i> Inserts an element pointed to by <code>i</code> from list <code>x</code> before position and removes 
the element from <code>x</code>. The result is unchanged if <ins><code>&amp;x == this</code> and the following 
condition is satisfied:</ins> <code>position == i</code> or <code>position == ++i</code>. Pointers and references to 
<code>*i</code> continue to refer to this same element but as a member of <code>*this</code>. Iterators to <code>*i</code> 
(including <code>i</code> itself) continue to refer to the same element, but now behave as iterators into <code>*this</code>, 
not into <code>x</code>.
</p>
</blockquote>
</blockquote>
</li>

</ol>





</body>
</html>
