зеркало из https://github.com/microsoft/STL.git
Fix thinko in ranges::iter_swap (#1072)
...by transposing arguments to `_Iter_exchange_move`. Fixes #1067
This commit is contained in:
Родитель
e9f56a6148
Коммит
30777d5adf
|
@ -1038,10 +1038,10 @@ namespace ranges {
|
||||||
// clang-format on
|
// clang-format on
|
||||||
|
|
||||||
template <class _Xty, class _Yty>
|
template <class _Xty, class _Yty>
|
||||||
_NODISCARD constexpr iter_value_t<remove_reference_t<_Xty>> _Iter_exchange_move(
|
_NODISCARD constexpr iter_value_t<remove_reference_t<_Xty>> _Iter_exchange_move(_Xty&& _XVal,
|
||||||
_Xty&& _XVal, _Yty&& _YVal) noexcept(noexcept(iter_value_t<remove_reference_t<_Xty>>(iter_move(_XVal)))) {
|
_Yty&& _YVal) noexcept(noexcept(iter_value_t<remove_reference_t<_Xty>>(_RANGES iter_move(_XVal)))) {
|
||||||
iter_value_t<remove_reference_t<_Xty>> _Tmp(iter_move(_XVal));
|
iter_value_t<remove_reference_t<_Xty>> _Tmp(_RANGES iter_move(_XVal));
|
||||||
*_XVal = iter_move(_YVal);
|
*_XVal = _RANGES iter_move(_YVal);
|
||||||
return _Tmp;
|
return _Tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1057,7 +1057,7 @@ namespace ranges {
|
||||||
return {_St::_Swap, noexcept(_RANGES swap(*_STD declval<_Ty1>(), *_STD declval<_Ty2>()))};
|
return {_St::_Swap, noexcept(_RANGES swap(*_STD declval<_Ty1>(), *_STD declval<_Ty2>()))};
|
||||||
} else if constexpr (_Symmetric_indirectly_movable_storable<_Ty1, _Ty2>) {
|
} else if constexpr (_Symmetric_indirectly_movable_storable<_Ty1, _Ty2>) {
|
||||||
constexpr auto _Nothrow = noexcept(
|
constexpr auto _Nothrow = noexcept(
|
||||||
*_STD declval<_Ty1>() = _Iter_exchange_move(_STD declval<_Ty1>(), _STD declval<_Ty2>()));
|
*_STD declval<_Ty1>() = _Iter_exchange_move(_STD declval<_Ty2>(), _STD declval<_Ty1>()));
|
||||||
return {_St::_Exchange, _Nothrow};
|
return {_St::_Exchange, _Nothrow};
|
||||||
} else {
|
} else {
|
||||||
return {_St::_None};
|
return {_St::_None};
|
||||||
|
@ -1078,7 +1078,7 @@ namespace ranges {
|
||||||
_RANGES swap(*static_cast<_Ty1&&>(_Val1), *static_cast<_Ty2&&>(_Val2));
|
_RANGES swap(*static_cast<_Ty1&&>(_Val1), *static_cast<_Ty2&&>(_Val2));
|
||||||
} else if constexpr (_Choice<_Ty1, _Ty2>._Strategy == _St::_Exchange) {
|
} else if constexpr (_Choice<_Ty1, _Ty2>._Strategy == _St::_Exchange) {
|
||||||
*static_cast<_Ty1&&>(_Val1) =
|
*static_cast<_Ty1&&>(_Val1) =
|
||||||
_Iter_exchange_move(static_cast<_Ty1&&>(_Val1), static_cast<_Ty2&&>(_Val2));
|
_Iter_exchange_move(static_cast<_Ty2&&>(_Val2), static_cast<_Ty1&&>(_Val1));
|
||||||
} else {
|
} else {
|
||||||
static_assert(_Always_false<_Ty1>, "should be unreachable");
|
static_assert(_Always_false<_Ty1>, "should be unreachable");
|
||||||
}
|
}
|
||||||
|
|
|
@ -1267,11 +1267,28 @@ namespace iterator_cust_swap_test {
|
||||||
// clang-format on
|
// clang-format on
|
||||||
|
|
||||||
constexpr bool test() {
|
constexpr bool test() {
|
||||||
int i0 = 42, i1 = 13;
|
{
|
||||||
S s0{i0}, s1{i1};
|
int i0 = 42;
|
||||||
ranges::iter_swap(s0, s1);
|
int i1 = 13;
|
||||||
assert(i0 == 13);
|
S s0{i0};
|
||||||
assert(i1 == 42);
|
S s1{i1};
|
||||||
|
ranges::iter_swap(s0, s1);
|
||||||
|
assert(i0 == 13);
|
||||||
|
assert(i1 == 42);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if !defined(__clang__) && !defined(__EDG__) // TRANSITION, VSO-938163
|
||||||
|
if (!std::is_constant_evaluated())
|
||||||
|
#endif // TRANSITION, VSO-938163
|
||||||
|
{
|
||||||
|
// Validate iter_swap bullet 3 to defend against regression of GH-1067 "ranges::iter_swap is broken"
|
||||||
|
int i = 42;
|
||||||
|
long l = 13;
|
||||||
|
ranges::iter_swap(&i, &l);
|
||||||
|
assert(i == 13);
|
||||||
|
assert(l == 42);
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
STATIC_ASSERT(test());
|
STATIC_ASSERT(test());
|
||||||
|
|
Загрузка…
Ссылка в новой задаче