<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Issue 431: Swapping containers with unequal allocators</title>
<meta property="og:title" content="Issue 431: Swapping containers with unequal allocators">
<meta property="og:description" content="C++ library issue. Status: Resolved">
<meta property="og:url" content="https://cplusplus.github.io/LWG/issue431.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#Resolved">Resolved</a> status.</em></p>
<h3 id="431"><a href="lwg-defects.html#431">431</a>. Swapping containers with unequal allocators</h3>
<p><b>Section:</b> 16.4.4.6 <a href="https://wg21.link/allocator.requirements">[allocator.requirements]</a>, 26 <a href="https://wg21.link/algorithms">[algorithms]</a> <b>Status:</b> <a href="lwg-active.html#Resolved">Resolved</a>
 <b>Submitter:</b> Matt Austern <b>Opened:</b> 2003-09-20 <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#allocator.requirements">active issues</a> in [allocator.requirements].</p>
<p><b>View all other</b> <a href="lwg-index.html#allocator.requirements">issues</a> in [allocator.requirements].</p>
<p><b>View all issues with</b> <a href="lwg-status.html#Resolved">Resolved</a> status.</p>
<p><b>Discussion:</b></p>
<p>Clause 16.4.4.6 <a href="https://wg21.link/allocator.requirements">[allocator.requirements]</a> paragraph 4 says that implementations
  are permitted to supply containers that are unable to cope with
  allocator instances and that container implementations may assume
  that all instances of an allocator type compare equal.  We gave
  implementers this latitude as a temporary hack, and eventually we
  want to get rid of it.  What happens when we're dealing with
  allocators that <i>don't</i> compare equal?
</p>

<p>In particular: suppose that <code>v1</code> and <code>v2</code> are both
  objects of type <code>vector&lt;int, my_alloc&gt;</code> and that
  <code>v1.get_allocator() != v2.get_allocator()</code>.  What happens if
  we write <code>v1.swap(v2)</code>?  Informally, three possibilities:</p>

<p>1. This operation is illegal.  Perhaps we could say that an
  implementation is required to check and to throw an exception, or
  perhaps we could say it's undefined behavior.</p>
<p>2. The operation performs a slow swap (i.e. using three
  invocations of <code>operator=</code>, leaving each allocator with its
  original container.  This would be an O(N) operation.</p>
<p>3. The operation swaps both the vectors' contents and their
  allocators.  This would be an O(1) operation. That is:</p>
  <blockquote>
  <pre>
    my_alloc a1(...);
    my_alloc a2(...);
    assert(a1 != a2);

    vector&lt;int, my_alloc> v1(a1);
    vector&lt;int, my_alloc> v2(a2);
    assert(a1 == v1.get_allocator());
    assert(a2 == v2.get_allocator());

    v1.swap(v2);
    assert(a1 == v2.get_allocator());
    assert(a2 == v1.get_allocator());
  </pre>
  </blockquote>

<p><i>[Kona: This is part of a general problem.  We need a paper
  saying how to deal with unequal allocators in general.]</i></p>


<p><i>[pre-Sydney: Howard argues for option 3 in
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2004/n1599.html">N1599</a>.
]</i></p>


<p><i>[
2007-01-12, Howard:  This issue will now tend to come up more often with move constructors
and move assignment operators.  For containers, these members transfer resources (i.e.
the allocated memory) just like swap.
]</i></p>


<p><i>[
Batavia:  There is agreement to overload the container <code>swap</code> on the allocator's Swappable
requirement using concepts.  If the allocator supports Swappable, then container's swap will
swap allocators, else it will perform a "slow swap" using copy construction and copy assignment.
]</i></p>


<p><i>[
2009-04-28 Pablo adds:
]</i></p>

<blockquote><p>
Fixed in
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2525.pdf">N2525</a>.
I argued for marking this Tentatively-Ready right after Bellevue,
but there was a concern that
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2525.pdf">N2525</a>
would break in the presence of the RVO. (That breakage had nothing to do with
swap, but never-the-less). I addressed that breakage in in
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2009/n2840.pdf">N2840</a>
(Summit) by means of a non-normative reference:
</p>
<blockquote><p>
[<i>Note:</i> in situations where the copy constructor for a container is elided,
this function is not called. The behavior in these cases is as if
<code>select_on_container_copy_construction</code> returned <code>x</code> &mdash; <i>end note</i>]
</p></blockquote>

</blockquote>

<p><i>[
2009-10 Santa Cruz:
]</i></p>


<blockquote><p>
<del>NAD Editorial</del><ins>Resolved</ins>.  Addressed by
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2009/n2982.pdf">N2982</a>.
</p></blockquote>



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





</body>
</html>
