<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Issue 1310: forward_list splice_after from lvalues</title>
<meta property="og:title" content="Issue 1310: forward_list splice_after from lvalues">
<meta property="og:description" content="C++ library issue. Status: C++11">
<meta property="og:url" content="https://cplusplus.github.io/LWG/issue1310.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++11">C++11</a> status.</em></p>
<h3 id="1310"><a href="lwg-defects.html#1310">1310</a>. <code>forward_list splice_after</code> from lvalues</h3>
<p><b>Section:</b> 23.3.7.6 <a href="https://wg21.link/forward.list.ops">[forward.list.ops]</a> <b>Status:</b> <a href="lwg-active.html#C++11">C++11</a>
 <b>Submitter:</b> Howard Hinnant <b>Opened:</b> 2010-02-05 <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#forward.list.ops">issues</a> in [forward.list.ops].</p>
<p><b>View all issues with</b> <a href="lwg-status.html#C++11">C++11</a> status.</p>
<p><b>Discussion:</b></p>
<p>
We've moved <a href="lwg-defects.html#1133" title="Does N2844 break current specification of list::splice? (Status: C++11)">1133</a><sup><a href="https://cplusplus.github.io/LWG/issue1133" title="Latest snapshot">(i)</a></sup> to Tentatively Ready and I'm fine with that.
</p>

<p>
<a href="lwg-defects.html#1133" title="Does N2844 break current specification of list::splice? (Status: C++11)">1133</a><sup><a href="https://cplusplus.github.io/LWG/issue1133" title="Latest snapshot">(i)</a></sup> adds lvalue-references to the <code>splice</code> signatures for <code>list</code>.  So now
<code>list</code> can <code>splice</code> from lvalue and rvalue lists (which was the intent of the
original move papers btw).  During the discussion of this issue it was mentioned
that if we want to give the same treatment to <code>forward_list</code>, that should be a
separate issue.
</p>

<p>
This is that separate issue.
</p>

<p>
Consider the following case where you want to splice elements from one place in
a <code>forward_list</code> to another.  Currently this must be coded like so:
</p>

<blockquote><pre>
fl.splice_after(to_here, std::move(fl), from1, from2);
</pre></blockquote>

<p>
This looks pretty shocking to me.  I would expect to be able to code instead:
</p>

<blockquote><pre>
fl.splice_after(to_here, fl, from1, from2);
</pre></blockquote>

<p>
but we currently don't allow it.
</p>

<p>
When I say <code>move(fl)</code>, I consider that as saying that I don't care about
the value of <code>fl</code> any more (until I assign it a new value).  But in the
above example, this simply isn't true.  I do care about the value of <code>fl</code>
after the move, and I'm not assigning it a new value.  I'm merely permuting its
current value.
</p>

<p>
I propose adding <code>forward_list&amp;</code> overloads to the 3
<code>splice_after</code> members.  For consistency's sake (principal of least
surprise) I'm also proposing to overload <code>merge</code> this way as well.
</p>


<p id="res-1310"><b>Proposed resolution:</b></p>
<p>
Add to the synopsis of  [forwardlist.overview]:
</p>

<blockquote><pre>
template &lt;class T, class Allocator = allocator&lt;T&gt; &gt;
class forward_list {
public:
  ...
  // <i>[forwardlist.ops], forward_list operations:</i>
  <ins>void splice_after(const_iterator p, forward_list&amp; x);</ins>
  void splice_after(const_iterator p, forward_list&amp;&amp; x);
  <ins>void splice_after(const_iterator p, forward_list&amp; x, const_iterator i);</ins>
  void splice_after(const_iterator p, forward_list&amp;&amp; x, const_iterator i);
  <ins>void splice_after(const_iterator p, forward_list&amp; x,
                    const_iterator first, const_iterator last);</ins>
  void splice_after(const_iterator p, forward_list&amp;&amp; x,
                    const_iterator first, const_iterator last);
  ...
  <ins>void merge(forward_list&amp; x);</ins>
  void merge(forward_list&amp;&amp; x);
  <ins>template &lt;class Compare&gt; void merge(forward_list&amp; x, Compare comp);</ins>
  template &lt;class Compare&gt; void merge(forward_list&amp;&amp; x, Compare comp);
  ...
};
</pre></blockquote>

<p>
Add to the signatures of  [forwardlist.ops]:
</p>

<blockquote>
<pre>
<ins>void splice_after(const_iterator p, forward_list&amp; x);</ins>
void splice_after(const_iterator p, forward_list&amp;&amp; x);
</pre>
<blockquote>
<p>1 ...</p>
</blockquote>

<pre>
<ins>void splice_after(const_iterator p, forward_list&amp; x, const_iterator i);</ins>
void splice_after(const_iterator p, forward_list&amp;&amp; x, const_iterator i);
</pre>
<blockquote>
<p>4 ...</p>
</blockquote>

<pre>
<ins>void splice_after(const_iterator p, forward_list&amp; x,
                const_iterator first, const_iterator last);</ins>
void splice_after(const_iterator p, forward_list&amp;&amp; x,
                const_iterator first, const_iterator last);
</pre>
<blockquote>
<p>7 ...</p>
</blockquote>

<pre>
<ins>void merge(forward_list&amp; x);</ins>
void merge(forward_list&amp;&amp; x);
<ins>template &lt;class Compare&gt; void merge(forward_list&amp; x, Compare comp);</ins>
template &lt;class Compare&gt; void merge(forward_list&amp;&amp; x, Compare comp);
</pre>
<blockquote>
<p>16 ...</p>
</blockquote>

</blockquote>






</body>
</html>
