<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Issue 672: Swappable requirements need updating</title>
<meta property="og:title" content="Issue 672: Swappable requirements need updating">
<meta property="og:description" content="C++ library issue. Status: CD1">
<meta property="og:url" content="https://cplusplus.github.io/LWG/issue672.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="672"><a href="lwg-defects.html#672">672</a>. Swappable requirements need updating</h3>
<p><b>Section:</b> 16.4.4.2 <a href="https://wg21.link/utility.arg.requirements">[utility.arg.requirements]</a> <b>Status:</b> <a href="lwg-active.html#CD1">CD1</a>
 <b>Submitter:</b> Howard Hinnant <b>Opened:</b> 2007-05-04 <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#utility.arg.requirements">active issues</a> in [utility.arg.requirements].</p>
<p><b>View all other</b> <a href="lwg-index.html#utility.arg.requirements">issues</a> in [utility.arg.requirements].</p>
<p><b>View all issues with</b> <a href="lwg-status.html#CD1">CD1</a> status.</p>
<p><b>Discussion:</b></p>
<p>
The current <code>Swappable</code> is:
</p>

<blockquote>
<table border="1">
<caption>Table 37: <code>Swappable</code> requirements <b>[swappable]</b></caption>
<tr><th>expression</th><th>return type</th><th>post-condition</th></tr>
<tr><td><code>swap(s,t)</code></td><td><code>void</code></td><td><code>t</code> has the value originally held by <code>u</code>, and <code>u</code> has the value originally 
held by <code>t</code></td></tr>
<tr><td colspan="3">
<p>
The Swappable requirement is met by satisfying one or more of the following conditions:
</p>
<ul>
<li>
<code>T</code> is Swappable if <code>T</code> satisfies the <code>CopyConstructible</code> requirements (Table 34) 
and the <code>CopyAssignable</code> requirements (Table 36);
</li>
<li>
<code>T</code> is Swappable if a namespace scope function named <code>swap</code> exists in the same 
namespace as the definition of <code>T</code>, such that the expression <code>swap(t,u)</code> is valid 
and has the semantics described in this table.
</li>
</ul>
</td></tr>
</table>
</blockquote>

<p>
With the passage of rvalue reference into the language, <code>Swappable</code> needs to be updated to
require only <code>MoveConstructible</code> and <code>MoveAssignable</code>.  This is a minimum.
</p>

<p>
Additionally we may want to support proxy references such that the following code is acceptable:
</p>

<blockquote><pre>
namespace Mine {

template &lt;class T&gt;
struct proxy {...};

template &lt;class T&gt;
struct proxied_iterator
{
   typedef T value_type;
   typedef proxy&lt;T&gt; reference;
   reference operator*() const;
   ...
};

struct A
{
   // heavy type, has an optimized swap, maybe isn't even copyable or movable, just swappable
   void swap(A&amp;);
   ...
};

void swap(A&amp;, A&amp;);
void swap(proxy&lt;A&gt;, A&amp;);
void swap(A&amp;, proxy&lt;A&gt;);
void swap(proxy&lt;A&gt;, proxy&lt;A&gt;);

}  // Mine

...

Mine::proxied_iterator&lt;Mine::A&gt; i(...)
Mine::A a;
swap(*i1, a);
</pre></blockquote>

<p>
I.e. here is a call to <code>swap</code> which the user enables swapping between a proxy to a class and the class
itself.  We do not need to anything in terms of implementation except not block their way with overly
constrained concepts.  That is, the <code>Swappable</code> concept should be expanded to allow swapping
between two different types for the case that one is binding to a user-defined <code>swap</code>.
</p>



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

<p>
Change 16.4.4.2 <a href="https://wg21.link/utility.arg.requirements">[utility.arg.requirements]</a>:
</p>

<blockquote>

<p>
-1- The template definitions in the C++ Standard Library refer to various
named requirements whose details are set out in tables 31-38. In these
tables, <code>T</code> is a type to be supplied by a C++ program
instantiating a template; <code>a</code>, <code>b</code>, and <code>c</code> are
values of type <code>const T</code>; <code>s</code> and <code>t</code> are modifiable
lvalues of type <code>T</code>; <code>u</code> is a value of type (possibly
<code>const</code>) <code>T</code>; and <code>rv</code> is a non-<code>const</code>
rvalue of type <code>T</code>.
</p>

<table border="1">
<caption>Table 37: <code>Swappable</code> requirements <b>[swappable]</b></caption>
<tr><th>expression</th><th>return type</th><th>post-condition</th></tr>
<tr><td><code>swap(s,t)</code></td><td><code>void</code></td>
<td><code>t</code> has the value originally
held by <code>u</code>, and
<code>u</code> has the value originally held
by <code>t</code></td></tr>
<tr><td colspan="3">
<p>
The <code>Swappable</code> requirement is met by satisfying one or more of the following conditions:
</p>
<ul>
<li>
<code>T</code> is <code>Swappable</code> if <code>T</code> satisfies the
<del><code>CopyConstructible</code></del> <ins>MoveConstructible</ins>
requirements (Table <del>34</del> <ins>33</ins>) and the <del><code>CopyAssignable</code></del> <ins>MoveAssignable</ins>
requirements (Table <del>36</del> <ins>35</ins>);
</li>
<li>
<code>T</code> is <code>Swappable</code> if a namespace scope function named
<code>swap</code> exists in the same namespace as the definition of
<code>T</code>, such that the expression
<code>swap(t,u)</code> is valid and has the
semantics described in this table.
</li>
</ul>
</td></tr>
</table>
</blockquote>



<p><i>[
Kona (2007): We like the change to the <code>Swappable</code> requirements to use
move semantics. The issue relating to the support of proxies is
separable from the one relating to move semantics, and it's bigger than
just swap. We'd like to address only the move semantics changes under
this issue, and open a separated issue (<a href="lwg-defects.html#742" title="Enabling swap for proxy iterators (Status: Resolved)">742</a><sup><a href="https://cplusplus.github.io/LWG/issue742" title="Latest snapshot">(i)</a></sup>) to handle proxies. Also, there
may be a third issue, in that the current definition of <code>Swappable</code> does
not permit rvalues to be operands to a swap operation, and Howard's
proposed resolution would allow the right-most operand to be an rvalue,
but it would not allow the left-most operand to be an rvalue (some swap
functions in the library have been overloaded to permit left operands to
swap to be rvalues).
]</i></p>





</body>
</html>
