From c44dd5acd7848a175d1fb939cdb81a4cf8d4c912 Mon Sep 17 00:00:00 2001 From: Abseil Team Date: Tue, 30 Jan 2024 12:52:43 -0800 Subject: Early return from destroy_slots for trivially destructible types in flat_hash_{*}. PiperOrigin-RevId: 602813933 Change-Id: I744fe438281755a141b2fd47e54ab9c6c0fad5a3 --- absl/container/internal/common_policy_traits.h | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) (limited to 'absl/container/internal/common_policy_traits.h') diff --git a/absl/container/internal/common_policy_traits.h b/absl/container/internal/common_policy_traits.h index 57eac678..77df4790 100644 --- a/absl/container/internal/common_policy_traits.h +++ b/absl/container/internal/common_policy_traits.h @@ -45,9 +45,10 @@ struct common_policy_traits { // PRECONDITION: `slot` is INITIALIZED // POSTCONDITION: `slot` is UNINITIALIZED + // Returns std::true_type in case destroy is trivial. template - static void destroy(Alloc* alloc, slot_type* slot) { - Policy::destroy(alloc, slot); + static auto destroy(Alloc* alloc, slot_type* slot) { + return Policy::destroy(alloc, slot); } // Transfers the `old_slot` to `new_slot`. Any memory allocated by the @@ -86,6 +87,13 @@ struct common_policy_traits { std::true_type>::value; } + // Returns true if destroy is trivial and can be omitted. + template + static constexpr bool destroy_is_trivial() { + return std::is_same(nullptr, nullptr)), + std::true_type>::value; + } + private: // To rank the overloads below for overload resolution. Rank0 is preferred. struct Rank2 {}; -- cgit v1.2.3 From 99f0b6d16f0e9ab6027379c31ce6c99dc1db5e9c Mon Sep 17 00:00:00 2001 From: Matt Kulukundis Date: Wed, 7 Feb 2024 16:02:47 -0800 Subject: Switch rank structs to be consistent with written guidance in go/ranked-overloads PiperOrigin-RevId: 605125821 Change-Id: I2ee260eaf283acafd80abfd2b7419a0e9f597a78 --- absl/container/internal/common_policy_traits.h | 19 ++++++++++--------- absl/strings/cord.h | 2 +- absl/strings/internal/cord_internal.h | 11 ++++++----- 3 files changed, 17 insertions(+), 15 deletions(-) (limited to 'absl/container/internal/common_policy_traits.h') diff --git a/absl/container/internal/common_policy_traits.h b/absl/container/internal/common_policy_traits.h index 77df4790..c521f612 100644 --- a/absl/container/internal/common_policy_traits.h +++ b/absl/container/internal/common_policy_traits.h @@ -64,7 +64,7 @@ struct common_policy_traits { // UNINITIALIZED template static void transfer(Alloc* alloc, slot_type* new_slot, slot_type* old_slot) { - transfer_impl(alloc, new_slot, old_slot, Rank0{}); + transfer_impl(alloc, new_slot, old_slot, Rank2{}); } // PRECONDITION: `slot` is INITIALIZED @@ -83,7 +83,7 @@ struct common_policy_traits { static constexpr bool transfer_uses_memcpy() { return std::is_same>( - nullptr, nullptr, nullptr, Rank0{})), + nullptr, nullptr, nullptr, Rank2{})), std::true_type>::value; } @@ -95,18 +95,19 @@ struct common_policy_traits { } private: - // To rank the overloads below for overload resolution. Rank0 is preferred. - struct Rank2 {}; - struct Rank1 : Rank2 {}; - struct Rank0 : Rank1 {}; + // Use go/ranked-overloads for dispatching. + struct Rank0 {}; + struct Rank1 : Rank0 {}; + struct Rank2 : Rank1 {}; // Use auto -> decltype as an enabler. // P::transfer returns std::true_type if transfer uses memcpy (e.g. in // node_slot_policy). template static auto transfer_impl(Alloc* alloc, slot_type* new_slot, - slot_type* old_slot, Rank0) - -> decltype(P::transfer(alloc, new_slot, old_slot)) { + slot_type* old_slot, + Rank2) -> decltype(P::transfer(alloc, new_slot, + old_slot)) { return P::transfer(alloc, new_slot, old_slot); } #if defined(__cpp_lib_launder) && __cpp_lib_launder >= 201606 @@ -129,7 +130,7 @@ struct common_policy_traits { template static void transfer_impl(Alloc* alloc, slot_type* new_slot, - slot_type* old_slot, Rank2) { + slot_type* old_slot, Rank0) { construct(alloc, new_slot, std::move(element(old_slot))); destroy(alloc, old_slot); } diff --git a/absl/strings/cord.h b/absl/strings/cord.h index d2ba9673..2583aa8a 100644 --- a/absl/strings/cord.h +++ b/absl/strings/cord.h @@ -1120,7 +1120,7 @@ Cord MakeCordFromExternal(absl::string_view data, Releaser&& releaser) { } else { using ReleaserType = absl::decay_t; cord_internal::InvokeReleaser( - cord_internal::Rank0{}, ReleaserType(std::forward(releaser)), + cord_internal::Rank1{}, ReleaserType(std::forward(releaser)), data); } return cord; diff --git a/absl/strings/internal/cord_internal.h b/absl/strings/internal/cord_internal.h index 549f9175..a52deea1 100644 --- a/absl/strings/internal/cord_internal.h +++ b/absl/strings/internal/cord_internal.h @@ -352,18 +352,19 @@ struct CordRepExternal : public CordRep { static void Delete(CordRep* rep); }; -struct Rank1 {}; -struct Rank0 : Rank1 {}; +// Use go/ranked-overloads for dispatching. +struct Rank0 {}; +struct Rank1 : Rank0 {}; template > -void InvokeReleaser(Rank0, Releaser&& releaser, absl::string_view data) { +void InvokeReleaser(Rank1, Releaser&& releaser, absl::string_view data) { ::absl::base_internal::invoke(std::forward(releaser), data); } template > -void InvokeReleaser(Rank1, Releaser&& releaser, absl::string_view) { +void InvokeReleaser(Rank0, Releaser&& releaser, absl::string_view) { ::absl::base_internal::invoke(std::forward(releaser)); } @@ -381,7 +382,7 @@ struct CordRepExternalImpl } ~CordRepExternalImpl() { - InvokeReleaser(Rank0{}, std::move(this->template get<0>()), + InvokeReleaser(Rank1{}, std::move(this->template get<0>()), absl::string_view(base, length)); } -- cgit v1.2.3