issue #187 - swap allocators only if permitted by AllocTraits

This commit is contained in:
greg7mdp
2023-04-08 21:12:42 -04:00
parent 7883cb6cd1
commit 8540627c91
+10 -9
View File
@@ -135,6 +135,7 @@ void SwapAlloc(AllocType& lhs, AllocType& rhs,
using std::swap;
swap(lhs, rhs);
}
template <typename AllocType>
void SwapAlloc(AllocType& /*lhs*/, AllocType& /*rhs*/,
std::false_type /* propagate_on_container_swap */) {}
@@ -192,11 +193,16 @@ struct IsDecomposable<
// TODO(alkis): Switch to std::is_nothrow_swappable when gcc/clang supports it.
// --------------------------------------------------------------------------
template <class T>
constexpr bool IsNoThrowSwappable() {
constexpr bool IsNoThrowSwappable(std::true_type = {} /* is_swappable */) {
using std::swap;
return noexcept(swap(std::declval<T&>(), std::declval<T&>()));
}
template <class T>
constexpr bool IsNoThrowSwappable(std::false_type /* is_swappable */) {
return false;
}
// --------------------------------------------------------------------------
template <typename T>
int TrailingZeros(T x) {
@@ -1647,7 +1653,7 @@ public:
void swap(raw_hash_set& that) noexcept(
IsNoThrowSwappable<hasher>() && IsNoThrowSwappable<key_equal>() &&
(!AllocTraits::propagate_on_container_swap::value ||
IsNoThrowSwappable<allocator_type>())) {
IsNoThrowSwappable<allocator_type>(typename AllocTraits::propagate_on_container_swap{}))) {
using std::swap;
swap(ctrl_, that.ctrl_);
swap(slots_, that.slots_);
@@ -1657,12 +1663,7 @@ public:
swap(hash_ref(), that.hash_ref());
swap(eq_ref(), that.eq_ref());
swap(infoz_, that.infoz_);
if (AllocTraits::propagate_on_container_swap::value) {
swap(alloc_ref(), that.alloc_ref());
} else {
// If the allocators do not compare equal it is officially undefined
// behavior. We choose to do nothing.
}
SwapAlloc(alloc_ref(), that.alloc_ref(), typename AllocTraits::propagate_on_container_swap{});
}
#if !defined(PHMAP_NON_DETERMINISTIC)
@@ -3485,7 +3486,7 @@ public:
void swap(parallel_hash_set<N, RefSet, Mtx2_, Policy, Hash, Eq, Alloc>& that)
noexcept(IsNoThrowSwappable<EmbeddedSet>() &&
(!AllocTraits::propagate_on_container_swap::value ||
IsNoThrowSwappable<allocator_type>()))
IsNoThrowSwappable<allocator_type>(typename AllocTraits::propagate_on_container_swap{})))
{
using std::swap;
using Lockable2 = phmap::LockableImpl<Mtx2_>;