diff --git a/src/google/protobuf/arena.h b/src/google/protobuf/arena.h index 0e5d6a9e00..83beb8f9b4 100644 --- a/src/google/protobuf/arena.h +++ b/src/google/protobuf/arena.h @@ -389,7 +389,8 @@ class PROTOBUF_EXPORT PROTOBUF_ALIGNAS(8) Arena final { // mutually exclusive fashion, we use implicit conversions to base classes // to force an explicit ranking for our preferences. The lowest ranked // version that compiles will be accepted. - struct Rank1 {}; + struct Rank2 {}; + struct Rank1 : Rank2 {}; struct Rank0 : Rank1 {}; static Arena* GetOwningArena(const T* p) { @@ -402,8 +403,15 @@ class PROTOBUF_EXPORT PROTOBUF_ALIGNAS(8) Arena final { return p->GetOwningArena(); } + // TODO: remove this function. template - static Arena* GetOwningArena(Rank1, const U*) { + static auto GetOwningArena(Rank1, const U* p) + -> EnableIfArenaGetArena())> { + return p->GetArena(); + } + + template + static Arena* GetOwningArena(Rank2, const U*) { return nullptr; } diff --git a/src/google/protobuf/message_lite.h b/src/google/protobuf/message_lite.h index 6d3b93432b..cbece7c799 100644 --- a/src/google/protobuf/message_lite.h +++ b/src/google/protobuf/message_lite.h @@ -221,6 +221,11 @@ class PROTOBUF_EXPORT MessageLite { // if arena is a nullptr. virtual MessageLite* New(Arena* arena) const = 0; + // Returns the arena, if any, that directly owns this message and its internal + // memory (Arena::Own is different in that the arena doesn't directly own the + // internal memory). This method is used in proto's implementation for + // swapping, moving and setting allocated, for deciding whether the ownership + // of this message or its internal memory could be changed. Arena* GetArena() const { return _internal_metadata_.arena(); } // Clear all fields of the message and set them to their default values. @@ -511,13 +516,6 @@ class PROTOBUF_EXPORT MessageLite { inline explicit MessageLite(Arena* arena) : _internal_metadata_(arena) {} - // Returns the arena, if any, that directly owns this message and its internal - // memory (Arena::Own is different in that the arena doesn't directly own the - // internal memory). This method is used in proto's implementation for - // swapping, moving and setting allocated, for deciding whether the ownership - // of this message or its internal memory could be changed. - Arena* GetOwningArena() const { return _internal_metadata_.arena(); } - // We use a secondary vtable for descriptor based methods. This way ClassData // does not growth with the number of descriptor methods. This avoids extra // costs in MessageLite. diff --git a/src/google/protobuf/repeated_field.h b/src/google/protobuf/repeated_field.h index bbce360899..0647790b78 100644 --- a/src/google/protobuf/repeated_field.h +++ b/src/google/protobuf/repeated_field.h @@ -293,7 +293,10 @@ class RepeatedField final // Gets the Arena on which this RepeatedField stores its elements. // Note: this can be inaccurate for split default fields so we make this // function non-const. - inline Arena* GetArena() { return GetOwningArena(); } + inline Arena* GetArena() { + return (total_size_ == 0) ? static_cast(arena_or_elements_) + : rep()->arena; + } // For internal use only. // @@ -327,12 +330,6 @@ class RepeatedField final RepeatedField(Arena* arena, const RepeatedField& rhs); - // Gets the Arena on which this RepeatedField stores its elements. - inline Arena* GetOwningArena() const { - return (total_size_ == 0) ? static_cast(arena_or_elements_) - : rep()->arena; - } - // Swaps entire contents with "other". Should be called only if the caller can // guarantee that both repeated fields are on the same arena or are on the diff --git a/src/google/protobuf/repeated_ptr_field.h b/src/google/protobuf/repeated_ptr_field.h index 72beb1c2f5..5894e777e2 100644 --- a/src/google/protobuf/repeated_ptr_field.h +++ b/src/google/protobuf/repeated_ptr_field.h @@ -651,8 +651,6 @@ class PROTOBUF_EXPORT RepeatedPtrFieldBase { // Gets the Arena on which this RepeatedPtrField stores its elements. inline Arena* GetArena() const { return arena_; } - inline Arena* GetOwningArena() const { return arena_; } - private: using InternalArenaConstructable_ = void; using DestructorSkippable_ = void; @@ -1317,9 +1315,6 @@ class RepeatedPtrField final : private internal::RepeatedPtrFieldBase { RepeatedPtrField(Arena* arena, const RepeatedPtrField& rhs); - // Internal version of GetArena(). - inline Arena* GetOwningArena() const; - // Implementations for ExtractSubrange(). The copying behavior must be // included only if the type supports the necessary operations (e.g., @@ -1676,11 +1671,6 @@ inline Arena* RepeatedPtrField::GetArena() const { } #endif // !PROTOBUF_FUTURE_REMOVE_CONST_REPEATEDFIELD_GETARENA_API -template -inline Arena* RepeatedPtrField::GetOwningArena() const { - return RepeatedPtrFieldBase::GetArena(); -} - template inline size_t RepeatedPtrField::SpaceUsedExcludingSelfLong() const { // `google::protobuf::Message` has a virtual method `SpaceUsedLong`, hence we can