Update FOA move assignment operator to uphold the strong guarantee for Hash, KeyEqual

This commit is contained in:
Christian Mazakas
2022-12-01 15:51:22 -08:00
parent 2043f98593
commit c8910e8007

View File

@ -1306,19 +1306,32 @@ public:
table& operator=(table&& x)
noexcept(
alloc_traits::is_always_equal::value&&
std::is_nothrow_move_assignable<Hash>::value&&
std::is_nothrow_move_assignable<Pred>::value)
alloc_traits::propagate_on_container_move_assignment::value||
alloc_traits::is_always_equal::value)
{
BOOST_UNORDERED_STATIC_ASSERT_HASH_PRED(Hash, Pred)
static constexpr auto pocma=
alloc_traits::propagate_on_container_move_assignment::value;
if(this!=std::addressof(x)){
/* Given ambiguity in implementation strategies briefly discussed here:
* https://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#2227
*
* we opt into requiring nothrow swappability and eschew the move
* operations associated with Hash, Pred.
*
* To this end, we ensure that the user never has to consider the
* moved-from state of their Hash, Pred objects
*/
using std::swap;
clear();
h()=std::move(x.h());
pred()=std::move(x.pred());
swap(h(),x.h());
swap(pred(),x.pred());
if(pocma||al()==x.al()){
using std::swap;
reserve(0);
move_assign_if<pocma>(al(),x.al());
swap(size_,x.size_);