Pass raw function pointer to Copy and move empty/debug checks inside Copy. - Change Copy's callback parameter from absl::FunctionRef<void(void*, const void*)> to a raw C function pointer void (*copy_fn)(void* set, void* dst, const void* src) and replace the copy constructor lambda with a static raw_hash_set::copy_slot_fn method. - Move AssertNotDebugCapacity() and the empty check (size == 0) from raw_hash_set(const raw_hash_set&, const allocator_type&) into Copy. PiperOrigin-RevId: 1002179566
diff --git a/absl/container/internal/raw_hash_set.cc b/absl/container/internal/raw_hash_set.cc index 5e1524e..6b36220 100644 --- a/absl/container/internal/raw_hash_set.cc +++ b/absl/container/internal/raw_hash_set.cc
@@ -2337,9 +2337,10 @@ void Copy(CommonFields& common, const PolicyFunctions& __restrict policy, const CommonFields& other, - absl::FunctionRef<void(void*, const void*)> copy_fn) { + void (*copy_fn)(void* set, void* dst, const void* src)) { + other.AssertNotDebugCapacity(); const size_t size = other.size(); - ABSL_SWISSTABLE_ASSERT(size > 0); + if (size == 0) return; const size_t soo_capacity = policy.soo_capacity(); const size_t slot_size = policy.slot_size; const bool soo_enabled = policy.soo_enabled; @@ -2357,7 +2358,8 @@ : SlotAddress(other.slot_array(other_capacity), FindFirstFullSlot(0, other_capacity, other.control()), slot_size); - copy_fn(soo_enabled ? common.soo_data() + copy_fn(&common, + soo_enabled ? common.soo_data() : SingleSlotAddress</*kSooEnabled=*/false>(common), other_slot); @@ -2389,7 +2391,8 @@ infoz.RecordInsertMiss(hash, target.probe_length); offset = target.offset; SetCtrl(common, offset, H2(hash), slot_size); - copy_fn(SlotAddress(target_slot_array, offset, slot_size), that_slot); + copy_fn(&common, SlotAddress(target_slot_array, offset, slot_size), + that_slot); common.maybe_increment_generation_on_insert(); }); common.increment_size(size);
diff --git a/absl/container/internal/raw_hash_set.h b/absl/container/internal/raw_hash_set.h index a851710..1a5bd50 100644 --- a/absl/container/internal/raw_hash_set.h +++ b/absl/container/internal/raw_hash_set.h
@@ -2148,7 +2148,7 @@ // Type erased version of copy constructor. void Copy(CommonFields& common, const PolicyFunctions& policy, const CommonFields& other, - absl::FunctionRef<void(void*, const void*)> copy_fn); + void (*copy_fn)(void* set, void* dst, const void* src)); // Returns the optimal size for memcpy when transferring SOO slot. // Otherwise, returns the optimal size for memcpy SOO slot transfer @@ -2899,16 +2899,7 @@ raw_hash_set(const raw_hash_set& that, const allocator_type& a) : raw_hash_set(0, that.hash_ref(), that.eq_ref(), a) { - that.AssertNotDebugCapacity(); - if (that.empty()) return; - Copy(common(), GetPolicyFunctions(), that.common(), - [this](void* dst, const void* src) { - // TODO(b/413598253): type erase for trivially copyable types via - // PolicyTraits. - construct(to_slot(dst), - PolicyTraits::element( - static_cast<slot_type*>(const_cast<void*>(src)))); - }); + Copy(common(), GetPolicyFunctions(), that.common(), ©_slot_fn); } ABSL_ATTRIBUTE_NOINLINE raw_hash_set(raw_hash_set&& that) noexcept( @@ -4159,6 +4150,14 @@ } } + static void copy_slot_fn(void* set, void* dst, const void* src) { + // TODO(b/413598253): type erase for trivially copyable types via + // PolicyTraits. + static_cast<raw_hash_set*>(set)->construct( + to_slot(dst), + PolicyTraits::element(static_cast<slot_type*>(const_cast<void*>(src)))); + } + static void destroy_slot_fn_impl(void* set, void* slot) { auto* h = static_cast<raw_hash_set*>(set); h->destroy(to_slot(slot));