diff --git a/include/boost/unordered/detail/foa.hpp b/include/boost/unordered/detail/foa.hpp index 9b3fec58..41a1f153 100644 --- a/include/boost/unordered/detail/foa.hpp +++ b/include/boost/unordered/detail/foa.hpp @@ -1306,19 +1306,32 @@ public: table& operator=(table&& x) noexcept( - alloc_traits::is_always_equal::value&& - std::is_nothrow_move_assignable::value&& - std::is_nothrow_move_assignable::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(al(),x.al()); swap(size_,x.size_);