[Bug libstdc++/85828] std::shuffle tries to swap element with itself
redi at gcc dot gnu.org
gcc-bugzilla@gcc.gnu.org
Fri May 18 15:39:00 GMT 2018
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=85828
--- Comment #2 from Jonathan Wakely <redi at gcc dot gnu.org> ---
This is ugly but it works:
--- a/libstdc++-v3/include/bits/stl_algo.h
+++ b/libstdc++-v3/include/bits/stl_algo.h
@@ -3827,7 +3827,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
if ((__urange % 2) == 0)
{
__distr_type __d{0, 1};
- std::iter_swap(__i++, __first + __d(__g));
+ if (__d(__g) == 0)
+ std::iter_swap(__i, __first);
+ ++__i;
}
// Now we know that __last - __i is even, so we do the rest in pairs,
@@ -3841,8 +3843,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
const pair<__uc_type, __uc_type> __pospos =
__gen_two_uniform_ints(__swap_range, __swap_range + 1, __g);
- std::iter_swap(__i++, __first + __pospos.first);
- std::iter_swap(__i++, __first + __pospos.second);
+ _RandomAccessIterator __pos1 = __first + __pospos.first;
+ _RandomAccessIterator __pos2 = __first + __pospos.second;
+ if (__i != __pos1)
+ std::iter_swap(__i, __pos1);
+ ++__i;
+ if (__i != __pos2)
+ std::iter_swap(__i, __pos2);
+ ++__i;
}
return;
I think we also want to remove the __glibcxx_check_self_move_assign assertions
completely.
More information about the Gcc-bugs
mailing list