-
Notifications
You must be signed in to change notification settings - Fork 1.6k
Closed
Labels
bugSomething isn't workingSomething isn't workingfixedSomething works now, yay!Something works now, yay!
Description
Describe the bug
Currently, self-swaps of pair are no-op:
Lines 441 to 460 in 9aca224
| _CONSTEXPR20 void swap(pair& _Right) noexcept( | |
| _Is_nothrow_swappable<_Ty1>::value && _Is_nothrow_swappable<_Ty2>::value) { | |
| using _STD swap; | |
| if (this != _STD addressof(_Right)) { | |
| swap(first, _Right.first); // intentional ADL | |
| swap(second, _Right.second); // intentional ADL | |
| } | |
| } | |
| #if _HAS_CXX23 | |
| template <int = 0> // see GH-3013 | |
| constexpr void swap(const pair& _Right) const | |
| noexcept(is_nothrow_swappable_v<const _Ty1> && is_nothrow_swappable_v<const _Ty2>) { | |
| using _STD swap; | |
| if (this != _STD addressof(_Right)) { | |
| swap(first, _Right.first); // intentional ADL | |
| swap(second, _Right.second); // intentional ADL | |
| } | |
| } | |
| #endif // _HAS_CXX23 |
However, the Cpp17Swappable requirements ([swappable.requirements]) doesn't seem to exclude self-swaps or side effects in them, and no special case is specified for self-swaps of pair.
Perhaps we should just unconditionally swap members.
Command-line test case
#include <utility>
struct swap_counter {
unsigned int* pcnt_ = nullptr;
friend constexpr void swap(swap_counter& lhs, swap_counter& rhs) noexcept
{
std::swap(lhs.pcnt_, rhs.pcnt_);
if (lhs.pcnt_ != nullptr)
++*lhs.pcnt_;
if (rhs.pcnt_ != nullptr)
++*lhs.pcnt_;
}
};
static_assert([]
{
unsigned int cnt{};
std::pair<swap_counter, int> pr{swap_counter{&cnt}, 0};
pr.swap(pr);
return cnt == 2u;
}());Expected behavior
The code snippet compiles.
Mq-b
Metadata
Metadata
Assignees
Labels
bugSomething isn't workingSomething isn't workingfixedSomething works now, yay!Something works now, yay!