<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Issue 341: Vector reallocation and swap</title>
<meta property="og:title" content="Issue 341: Vector reallocation and swap">
<meta property="og:description" content="C++ library issue. Status: CD1">
<meta property="og:url" content="https://cplusplus.github.io/LWG/issue341.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#CD1">CD1</a> status.</em></p>
<h3 id="341"><a href="lwg-defects.html#341">341</a>. Vector reallocation and swap</h3>
<p><b>Section:</b> 23.3.13.3 <a href="https://wg21.link/vector.capacity">[vector.capacity]</a> <b>Status:</b> <a href="lwg-active.html#CD1">CD1</a>
 <b>Submitter:</b> Anthony Williams <b>Opened:</b> 2001-09-27 <b>Last modified:</b> 2016-01-28</p>
<p><b>Priority: </b>Not Prioritized
</p>
<p><b>View other</b> <a href="lwg-index-open.html#vector.capacity">active issues</a> in [vector.capacity].</p>
<p><b>View all other</b> <a href="lwg-index.html#vector.capacity">issues</a> in [vector.capacity].</p>
<p><b>View all issues with</b> <a href="lwg-status.html#CD1">CD1</a> status.</p>
<p><b>Discussion:</b></p>
<p>It is a common idiom to reduce the capacity of a vector by swapping it with
an empty one:</p>
<pre>
  std::vector&lt;SomeType&gt; vec;
  // fill vec with data
  std::vector&lt;SomeType&gt;().swap(vec);
  // vec is now empty, with minimal capacity
</pre>

<p>However, the wording of 23.3.13.3 <a href="https://wg21.link/vector.capacity">[vector.capacity]</a>paragraph 5 prevents
the capacity of a vector being reduced, following a call to
reserve(). This invalidates the idiom, as swap() is thus prevented
from reducing the capacity. The proposed wording for issue <a href="lwg-defects.html#329" title="vector capacity, reserve and reallocation (Status: CD1)">329</a><sup><a href="https://cplusplus.github.io/LWG/issue329" title="Latest snapshot">(i)</a></sup> does not affect this.  Consequently, the example above
requires the temporary to be expanded to cater for the contents of
vec, and the contents be copied across. This is a linear-time
operation.</p>

<p>However, the container requirements state that swap must have constant
complexity (23.2 <a href="https://wg21.link/container.requirements">[container.requirements]</a> note to table 65).</p>

<p>This is an important issue, as reallocation affects the validity of
references and iterators.</p>

<p>If the wording of 23.2.4.2p5 is taken to be the desired intent, then
references and iterators remain valid after a call to swap, if they refer to
an element before the new end() of the vector into which they originally
pointed, in which case they refer to the element at the same index position.
Iterators and references that referred to an element whose index position
was beyond the new end of the vector are invalidated.</p>

<p>If the note to table 65 is taken as the desired intent, then there are two
possibilities with regard to iterators and references:</p>

<ol>
<li>All Iterators and references into both vectors are invalidated.</li>
<li>Iterators and references into either vector remain valid, and remain
pointing to the same element. Consequently iterators and references that
referred to one vector now refer to the other, and vice-versa.</li>
</ol>


<p id="res-341"><b>Proposed resolution:</b></p>
<p>Add a new paragraph after 23.3.13.3 <a href="https://wg21.link/vector.capacity">[vector.capacity]</a> paragraph 5:</p>
<blockquote>
<pre>
  void swap(vector&lt;T,Allocator&gt;&amp; x);
</pre>
<p><b>Effects:</b> Exchanges the contents and capacity() of <code>*this</code>
with that of <code>x</code>.</p>
<p><b>Complexity:</b> Constant time.</p>
</blockquote>

<p><i>[This solves the problem reported for this issue.  We may also
have a problem with a circular definition of swap() for other
containers.]</i></p>




<p><b>Rationale:</b></p>
<p>
swap should be constant time.  The clear intent is that it should just
do pointer twiddling, and that it should exchange all properties of
the two vectors, including their reallocation guarantees.
</p>





</body>
</html>
