<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Issue 742: Enabling swap for proxy iterators</title>
<meta property="og:title" content="Issue 742: Enabling swap for proxy iterators">
<meta property="og:description" content="C++ library issue. Status: Resolved">
<meta property="og:url" content="https://cplusplus.github.io/LWG/issue742.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="742"><a href="lwg-defects.html#742">742</a>. Enabling <code>swap</code> for proxy iterators</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#Resolved">Resolved</a>
 <b>Submitter:</b> Howard Hinnant <b>Opened:</b> 2007-10-10 <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#Resolved">Resolved</a> status.</p>
<p><b>Discussion:</b></p>
<p>
This issue was split from <a href="lwg-defects.html#672" title="Swappable requirements need updating (Status: CD1)">672</a><sup><a href="https://cplusplus.github.io/LWG/issue672" title="Latest snapshot">(i)</a></sup>. <a href="lwg-defects.html#672" title="Swappable requirements need updating (Status: CD1)">672</a><sup><a href="https://cplusplus.github.io/LWG/issue672" title="Latest snapshot">(i)</a></sup> now just
deals with changing the requirements of <code>T</code> in the <code>Swappable</code>
requirement from <code>CopyConstructible</code> and <code>CopyAssignable</code> to
<code>MoveConstructible</code> and <code>MoveAssignable</code>.
</p>

<p>
This issue seeks to widen the <code>Swappable</code> requirement to support proxy iterators.  Here
is example code:
</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;
<b>swap(*i1, a);</b>
</pre></blockquote>

<p>
The key point to note in the above code is that in the call to <code>swap</code>, <code>*i1</code>
and <code>a</code> are different types (currently types can only be <code>Swappable</code> with the
same type).  A secondary point is that to support proxies, one must be able to pass rvalues
to <code>swap</code>.  But note that I am not stating that the general purpose <code>std::swap</code>
should accept rvalues!  Only that overloaded <code>swap</code>s, as in the example above, be allowed
to take rvalues.
</p>

<p>
That is, no standard library code needs to change.  We simply need to have a more flexible
definition of <code>Swappable</code>.
</p>

<p><i>[
Bellevue:
]</i></p>


<blockquote>
<p>
While we believe Concepts work will define a swappable concept, we
should still resolve this issue if possible to give guidance to the
Concepts work.
</p>
<p>
Would an ambiguous swap function in two namespaces found by ADL break
this wording? Suggest that the phrase "valid expression" means such a
pair of types would still not be swappable.
</p>
<p>
Motivation is proxy-iterators, but facility is considerably more
general. Are we happy going so far?
</p>
<p>
We think this wording is probably correct and probably an improvement on
what's there in the WP. On the other hand, what's already there in the
WP is awfully complicated. Why do we need the two bullet points? They're
too implementation-centric. They don't add anything to the semantics of
what swap() means, which is there in the post-condition. What's wrong
with saying that types are swappable if you can call swap() and it
satisfies the semantics of swapping?
</p>
</blockquote>

<p><i>[
2009-07-28 Reopened by Alisdair.  No longer solved by concepts.
]</i></p>


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


<blockquote><p>
Leave as Open. Dave to provide wording.
</p></blockquote>

<p><i>[
2009-11-08 Howard adds:
]</i></p>


<blockquote><p>
Updated wording to sync with
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2009/n3000.pdf">N3000</a>.
Also this issue is very closely related to <a href="lwg-defects.html#594" title="Disadvantages of defining Swappable in terms of CopyConstructible and Assignable (Status: Resolved)">594</a><sup><a href="https://cplusplus.github.io/LWG/issue594" title="Latest snapshot">(i)</a></sup>.
</p></blockquote>

<p><i>[
2010 Pittsburgh:
]</i></p>


<blockquote><p>
Moved to <del>NAD Editorial</del><ins>Resolved</ins>.  Rationale added.
</p></blockquote>



<p><b>Rationale:</b></p>
<p>
Solved by N3048.
</p>


<p id="res-742"><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> <ins>and <code>V</code> are</ins> <del>is a</del> type<ins>s</ins> 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>; <del>and</del> <code>rv</code> is a non-<code>const</code>
rvalue of type <code>T</code><ins>; <code>w</code> is a value of type <code>T</code>; and <code>v</code> is a value of type <code>V</code></ins>.
</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(<del>s</del><ins>w</ins>,<del>t</del><ins>v</ins>)</code></td><td><code>void</code></td>
<td><del><code>t</code></del><ins><code>w</code></ins> has the value originally
held by <del><code>u</code></del><ins><code>v</code></ins>, and
<del><code>u</code></del><ins><code>v</code></ins> has the value originally held
by <del><code>t</code></del><ins><code>w</code></ins></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 <ins><code>T</code> and <code>V</code> are
the same type and </ins> <code>T</code> satisfies the
<code>MoveConstructible</code> requirements (Table 
33) and the 
<code>MoveAssignable</code> requirements (Table 
35);
</li>
<li>
<code>T</code> is <code>Swappable</code> <ins>with <code>V</code></ins> if a namespace scope function named
<code>swap</code> exists in the same namespace as the definition of
<code>T</code> <ins>or <code>V</code></ins>, such that the expression
<code>swap(<del>s</del><ins>w</ins>,<del>t</del> <ins>v</ins>)</code> is valid and has the
semantics described in this table.
</li>
<li>
<code>T</code> is <code>Swappable</code> if <code>T</code> is an array type whose
element type is <code>Swappable</code>.
</li>
</ul>
</td></tr>
</table>
</blockquote>



<p><b>Rationale:</b></p>
<p><i>[
post San Francisco:
]</i></p>


<blockquote><p>
Solved by
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2758.pdf">N2758</a>.
</p></blockquote>






</body>
</html>
