diff --git a/csharp/src/Google.Protobuf/Reflection/FeatureSetDescriptor.g.cs b/csharp/src/Google.Protobuf/Reflection/FeatureSetDescriptor.g.cs deleted file mode 100644 index 208ce1fcb6..0000000000 --- a/csharp/src/Google.Protobuf/Reflection/FeatureSetDescriptor.g.cs +++ /dev/null @@ -1,17 +0,0 @@ -#region Copyright notice and license -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file or at -// https://developers.google.com/open-source/licenses/bsd -#endregion - -namespace Google.Protobuf.Reflection; - -internal sealed partial class FeatureSetDescriptor -{ - // Canonical serialized form of the edition defaults, generated by embed_edition_defaults. - private const string DefaultsBase64 = - "ChMYhAciACoMCAEQAhgCIAMoATACChMY5wciACoMCAIQARgBIAIoATABChMY6AciDAgBEAEYASACKAEwASoAIOYHKOgH"; -} diff --git a/src/google/protobuf/arena.h b/src/google/protobuf/arena.h index 50a13b3d83..6e9a0f0841 100644 --- a/src/google/protobuf/arena.h +++ b/src/google/protobuf/arena.h @@ -581,31 +581,17 @@ class PROTOBUF_EXPORT PROTOBUF_ALIGNAS(8) Arena final { // which needs to declare Map as friend of generated message. template static void CreateInArenaStorage(T* ptr, Arena* arena, Args&&... args) { - CreateInArenaStorageInternal(ptr, arena, is_arena_constructable(), - std::forward(args)...); - if (ABSL_PREDICT_TRUE(arena != nullptr)) { - RegisterDestructorInternal(ptr, arena, is_destructor_skippable()); + if constexpr (is_arena_constructable::value) { + InternalHelper::Construct(ptr, arena, std::forward(args)...); + } else { + new (ptr) T(std::forward(args)...); } - } - - template - static void CreateInArenaStorageInternal(T* ptr, Arena* arena, - std::true_type, Args&&... args) { - InternalHelper::Construct(ptr, arena, std::forward(args)...); - } - template - static void CreateInArenaStorageInternal(T* ptr, Arena* /* arena */, - std::false_type, Args&&... args) { - new (ptr) T(std::forward(args)...); - } - template - static void RegisterDestructorInternal(T* /* ptr */, Arena* /* arena */, - std::true_type) {} - template - static void RegisterDestructorInternal(T* ptr, Arena* arena, - std::false_type) { - arena->OwnDestructor(ptr); + if constexpr (!is_destructor_skippable::value) { + if (ABSL_PREDICT_TRUE(arena != nullptr)) { + arena->OwnDestructor(ptr); + } + } } // Implementation for GetArena(). Only message objects with diff --git a/src/google/protobuf/map.h b/src/google/protobuf/map.h index f2459dff17..1f02abd21e 100644 --- a/src/google/protobuf/map.h +++ b/src/google/protobuf/map.h @@ -246,30 +246,17 @@ struct TransparentSupport { // that is convertible to absl::string_view. template <> struct TransparentSupport { - // Use go/ranked-overloads for dispatching. - struct Rank0 {}; - struct Rank1 : Rank0 {}; - struct Rank2 : Rank1 {}; - template ::value>> - static absl::string_view ImplicitConvertImpl(T&& str, Rank2) { - absl::string_view ref = str; - return ref; - } - template ::value>> - static absl::string_view ImplicitConvertImpl(T&& str, Rank1) { - const std::string& ref = str; - return ref; - } - template - static absl::string_view ImplicitConvertImpl(T&& str, Rank0) { - return {str.data(), str.size()}; - } - template static absl::string_view ImplicitConvert(T&& str) { - return ImplicitConvertImpl(std::forward(str), Rank2{}); + if constexpr (std::is_convertible::value) { + absl::string_view res = str; + return res; + } else if constexpr (std::is_convertible::value) { + const std::string& ref = str; + return ref; + } else { + return {str.data(), str.size()}; + } } struct hash : public absl::Hash { @@ -1576,16 +1563,33 @@ class Map : private internal::KeyMapBase> { template std::pair try_emplace(K&& k, Args&&... args) ABSL_ATTRIBUTE_LIFETIME_BOUND { - // Inserts a new element into the container if there is no element with the - // key in the container. - // The new element is: - // (1) Constructed in-place with the given args, if mapped_type is not - // arena constructible. - // (2) Constructed in-place with the arena and then assigned with a - // mapped_type temporary constructed with the given args, otherwise. - return ArenaAwareTryEmplace(Arena::is_arena_constructable(), - std::forward(k), + // Case 1: `mapped_type` is arena constructible. A temporary object is + // created and then (if `Args` are not empty) assigned to a mapped value + // that was created with the arena. + if constexpr (Arena::is_arena_constructable::value) { + if constexpr (sizeof...(Args) == 0) { + // case 1.1: "default" constructed (e.g. from arena only). + return TryEmplaceInternal(std::forward(k)); + } else { + // case 1.2: "default" constructed + copy/move assignment + auto p = TryEmplaceInternal(std::forward(k)); + if (p.second) { + if constexpr (std::is_same::type...), + void(mapped_type)>::value) { + // Avoid the temporary when the input is the right type. + p.first->second = (std::forward(args), ...); + } else { + p.first->second = mapped_type(std::forward(args)...); + } + } + return p; + } + } else { + // Case 2: `mapped_type` is not arena constructible. Using in-place + // construction. + return TryEmplaceInternal(std::forward(k), std::forward(args)...); + } } std::pair insert(init_type&& value) ABSL_ATTRIBUTE_LIFETIME_BOUND { @@ -1599,7 +1603,14 @@ class Map : private internal::KeyMapBase> { template std::pair emplace(Args&&... args) ABSL_ATTRIBUTE_LIFETIME_BOUND { - return EmplaceInternal(Rank0{}, std::forward(args)...); + // We try to construct `init_type` from `Args` with a fall back to + // `value_type`. The latter is less desired as it unconditionally makes a + // copy of `value_type::first`. + if constexpr (std::is_constructible::value) { + return insert(init_type(std::forward(args)...)); + } else { + return insert(value_type(std::forward(args)...)); + } } template void insert(InputIt first, InputIt last) { @@ -1687,9 +1698,6 @@ class Map : private internal::KeyMapBase> { } private: - struct Rank1 {}; - struct Rank0 : Rank1 {}; - // Linked-list nodes, as one would expect for a chaining hash table. struct Node : Base::KeyNode { using key_type = Key; @@ -1724,20 +1732,6 @@ class Map : private internal::KeyMapBase> { return this->SpaceUsedInTable(sizeof(Node)); } - // We try to construct `init_type` from `Args` with a fall back to - // `value_type`. The latter is less desired as it unconditionally makes a copy - // of `value_type::first`. - template - auto EmplaceInternal(Rank0, Args&&... args) -> - typename std::enable_if::value, - std::pair>::type { - return insert(init_type(std::forward(args)...)); - } - template - std::pair EmplaceInternal(Rank1, Args&&... args) { - return insert(value_type(std::forward(args)...)); - } - template std::pair TryEmplaceInternal(K&& k, Args&&... args) { auto p = this->FindHelper(TS::ToView(k)); @@ -1777,47 +1771,6 @@ class Map : private internal::KeyMapBase> { true); } - // A helper function to perform an assignment of `mapped_type`. - // If the first argument is true, then it is a regular assignment. - // Otherwise, we first create a temporary and then perform an assignment. - template - static void AssignMapped(std::true_type, mapped_type& mapped, V&& v) { - mapped = std::forward(v); - } - template - static void AssignMapped(std::false_type, mapped_type& mapped, - Args&&... args) { - mapped = mapped_type(std::forward(args)...); - } - - // Case 1: `mapped_type` is arena constructible. A temporary object is - // created and then (if `Args` are not empty) assigned to a mapped value - // that was created with the arena. - template - std::pair ArenaAwareTryEmplace(std::true_type, K&& k) { - // case 1.1: "default" constructed (e.g. from arena only). - return TryEmplaceInternal(std::forward(k)); - } - template - std::pair ArenaAwareTryEmplace(std::true_type, K&& k, - Args&&... args) { - // case 1.2: "default" constructed + copy/move assignment - auto p = TryEmplaceInternal(std::forward(k)); - if (p.second) { - AssignMapped(std::is_same::type...), - void(mapped_type)>(), - p.first->second, std::forward(args)...); - } - return p; - } - // Case 2: `mapped_type` is not arena constructible. Using in-place - // construction. - template - std::pair ArenaAwareTryEmplace(std::false_type, - Args&&... args) { - return TryEmplaceInternal(std::forward(args)...); - } - using Base::arena; friend class Arena;