title: Avoiding self assignment in std::shuffle
body: <p>I stumbled upon the following problem when using the checked implementation of glibcxx:</p>
  <pre><code>/usr/include/c++/4.8.2/debug/vector:159:error: attempt to self move assign.
  Objects involved in the operation:
  sequence &quot;this&quot; @ 0x0x1b3f088 {
    type = NSt7__debug6vectorIiSaIiEEE;
  }
  </code></pre>
  <p>Which I have reduced to this minimal example:</p>
  <pre><code>#include &lt;vector&gt;
  #include &lt;random&gt;
  #include &lt;algorithm&gt;
  
  struct Type {
          std::vector&lt;int&gt; ints;
  };
  
  int main() {
          std::vector&lt;Type&gt; intVectors = {{{1}}, {{1, 2}}};
          std::shuffle(intVectors.begin(), intVectors.end(), std::mt19937());
  }
  </code></pre>
  <p>Tracing the problem I found that <code>shuffle</code> wants to <code>std::swap</code> an element with itself. As the <code>Type</code> is user defined and no specialization for <code>std::swap</code> has been given for it, the default one is used which creates a temporary and uses <code>operator=(&amp;&amp;)</code> to transfer the values:</p>
  <pre><code>  _Tp __tmp = _GLIBCXX_MOVE(__a);
    __a = _GLIBCXX_MOVE(__b);
    __b = _GLIBCXX_MOVE(__tmp);
  </code></pre>
  <p>As <code>Type</code> does not explicitly give <code>operator=(&amp;&amp;)</code> it is default implemented by &quot;recursively&quot; applying the same operation on its members.</p>
  <p>The problem occurs on line 2 of the swap code where <code>__a</code> and <code>__b</code> point to the same object which results in effect in the code <code>__a.operator=(std::move(__a))</code> which then triggers the error in the checked implementation of <code>vector::operator=(&amp;&amp;)</code>.</p>
  <p>My question is: Who's fault is this?</p>
  <ul>
  <li>Is it mine, because I should provide an implementation for <code>swap</code> that makes &quot;self swap&quot; a <code>NOP</code>?</li>
  <li>Is it <code>std::shuffle</code>'s, because it should not try to swap an element with itself?</li>
  <li>Is it the checked implementation's, because self-move-assigment is perfectly fine?</li>
  <li>Everything is correct, the checked implementation is just doing me a favor in doing this extra check (but then how to turn it off)?</li>
  </ul>
  <p>I have read about shuffle requiring the iterators to be ValueSwappable. Does this extend to self-swap (which is a mere runtime problem and can not be enforced by compile-time concept checks)?</p>
  <h2>Addendum</h2>
  <p>To trigger the error more directly one could use:</p>
  <pre><code>#include &lt;vector&gt;
  
  int main() {
      std::vector&lt;int&gt; vectorOfInts;
      vectorOfInts = std::move(vectorOfInts);
  }
  </code></pre>
  <p>Of course this is quite obvious (why would you move a vector to itself?).
  If you where swapping <code>std::vector</code>s directly the error would not occur because of the vector class having a custom implementation of the swap function that does not use <code>operator=(&amp;&amp;)</code>.</p>