diff --git a/parallel_hashmap/phmap.h b/parallel_hashmap/phmap.h index abcd6ae..fe88b05 100644 --- a/parallel_hashmap/phmap.h +++ b/parallel_hashmap/phmap.h @@ -135,6 +135,7 @@ void SwapAlloc(AllocType& lhs, AllocType& rhs, using std::swap; swap(lhs, rhs); } + template 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 -constexpr bool IsNoThrowSwappable() { +constexpr bool IsNoThrowSwappable(std::true_type = {} /* is_swappable */) { using std::swap; return noexcept(swap(std::declval(), std::declval())); } +template +constexpr bool IsNoThrowSwappable(std::false_type /* is_swappable */) { + return false; +} + // -------------------------------------------------------------------------- template int TrailingZeros(T x) { @@ -1647,7 +1653,7 @@ public: void swap(raw_hash_set& that) noexcept( IsNoThrowSwappable() && IsNoThrowSwappable() && (!AllocTraits::propagate_on_container_swap::value || - IsNoThrowSwappable())) { + IsNoThrowSwappable(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& that) noexcept(IsNoThrowSwappable() && (!AllocTraits::propagate_on_container_swap::value || - IsNoThrowSwappable())) + IsNoThrowSwappable(typename AllocTraits::propagate_on_container_swap{}))) { using std::swap; using Lockable2 = phmap::LockableImpl;