Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-31 10:12:26

0001 // Protocol Buffers - Google's data interchange format
0002 // Copyright 2008 Google Inc.  All rights reserved.
0003 //
0004 // Use of this source code is governed by a BSD-style
0005 // license that can be found in the LICENSE file or at
0006 // https://developers.google.com/open-source/licenses/bsd
0007 
0008 // Author: kenton@google.com (Kenton Varda)
0009 //  Based on original Protocol Buffers design by
0010 //  Sanjay Ghemawat, Jeff Dean, and others.
0011 //
0012 // RepeatedField and RepeatedPtrField are used by generated protocol message
0013 // classes to manipulate repeated fields.  These classes are very similar to
0014 // STL's vector, but include a number of optimizations found to be useful
0015 // specifically in the case of Protocol Buffers.  RepeatedPtrField is
0016 // particularly different from STL vector as it manages ownership of the
0017 // pointers that it contains.
0018 //
0019 // This header covers RepeatedPtrField.
0020 
0021 #ifndef GOOGLE_PROTOBUF_REPEATED_PTR_FIELD_H__
0022 #define GOOGLE_PROTOBUF_REPEATED_PTR_FIELD_H__
0023 
0024 #include <algorithm>
0025 #include <cstddef>
0026 #include <cstdint>
0027 #include <iterator>
0028 #include <limits>
0029 #include <string>
0030 #include <tuple>
0031 #include <type_traits>
0032 #include <utility>
0033 
0034 #include "absl/base/attributes.h"
0035 #include "absl/base/prefetch.h"
0036 #include "absl/log/absl_check.h"
0037 #include "absl/meta/type_traits.h"
0038 #include "google/protobuf/arena.h"
0039 #include "google/protobuf/internal_visibility.h"
0040 #include "google/protobuf/message_lite.h"
0041 #include "google/protobuf/port.h"
0042 
0043 
0044 // Must be included last.
0045 #include "google/protobuf/port_def.inc"
0046 
0047 #ifdef SWIG
0048 #error "You cannot SWIG proto headers"
0049 #endif
0050 
0051 namespace google {
0052 namespace protobuf {
0053 
0054 class Message;
0055 class Reflection;
0056 
0057 template <typename T>
0058 struct WeakRepeatedPtrField;
0059 
0060 namespace internal {
0061 
0062 class MergePartialFromCodedStreamHelper;
0063 class SwapFieldHelper;
0064 
0065 
0066 }  // namespace internal
0067 
0068 namespace internal {
0069 template <typename It>
0070 class RepeatedPtrIterator;
0071 template <typename It, typename VoidPtr>
0072 class RepeatedPtrOverPtrsIterator;
0073 }  // namespace internal
0074 
0075 namespace internal {
0076 
0077 // Swaps two non-overlapping blocks of memory of size `N`
0078 template <size_t N>
0079 inline void memswap(char* PROTOBUF_RESTRICT a, char* PROTOBUF_RESTRICT b) {
0080   // `PROTOBUF_RESTRICT` tells compiler that blocks do not overlapping which
0081   // allows it to generate optimized code for swap_ranges.
0082   std::swap_ranges(a, a + N, b);
0083 }
0084 
0085 template <typename T>
0086 struct IsMovable
0087     : std::integral_constant<bool, std::is_move_constructible<T>::value &&
0088                                        std::is_move_assignable<T>::value> {};
0089 
0090 // A trait that tells offset of `T::arena_`.
0091 //
0092 // Do not use this struct - it exists for internal use only.
0093 template <typename T>
0094 struct ArenaOffsetHelper {
0095   constexpr static size_t value = offsetof(T, arena_);
0096 };
0097 
0098 // This is the common base class for RepeatedPtrFields.  It deals only in void*
0099 // pointers.  Users should not use this interface directly.
0100 //
0101 // The methods of this interface correspond to the methods of RepeatedPtrField,
0102 // but may have a template argument called TypeHandler.  Its signature is:
0103 //   class TypeHandler {
0104 //    public:
0105 //     typedef MyType Type;
0106 //     static Type* New();
0107 //     static Type* NewFromPrototype(const Type* prototype,
0108 //                                       Arena* arena);
0109 //     static void Delete(Type*);
0110 //     static void Clear(Type*);
0111 //     static void Merge(const Type& from, Type* to);
0112 //
0113 //     // Only needs to be implemented if SpaceUsedExcludingSelf() is called.
0114 //     static int SpaceUsedLong(const Type&);
0115 //   };
0116 class PROTOBUF_EXPORT RepeatedPtrFieldBase {
0117   template <typename Handler>
0118   using Value = typename Handler::Type;
0119 
0120   static constexpr int kSSOCapacity = 1;
0121 
0122   using ElementFactory = void* (*)(Arena*);
0123 
0124  protected:
0125   // We use the same Handler for all Message types to deduplicate generated
0126   // code.
0127   template <typename Handler>
0128   using CommonHandler = typename std::conditional<
0129       std::is_base_of<MessageLite, Value<Handler>>::value,
0130       internal::GenericTypeHandler<MessageLite>, Handler>::type;
0131 
0132   constexpr RepeatedPtrFieldBase()
0133       : tagged_rep_or_elem_(nullptr),
0134         current_size_(0),
0135         capacity_proxy_(0),
0136         arena_(nullptr) {}
0137   explicit RepeatedPtrFieldBase(Arena* arena)
0138       : tagged_rep_or_elem_(nullptr),
0139         current_size_(0),
0140         capacity_proxy_(0),
0141         arena_(arena) {}
0142 
0143   RepeatedPtrFieldBase(const RepeatedPtrFieldBase&) = delete;
0144   RepeatedPtrFieldBase& operator=(const RepeatedPtrFieldBase&) = delete;
0145 
0146   ~RepeatedPtrFieldBase() {
0147 #ifndef NDEBUG
0148     // Try to trigger segfault / asan failure in non-opt builds. If arena_
0149     // lifetime has ended before the destructor.
0150     if (arena_) (void)arena_->SpaceAllocated();
0151 #endif
0152   }
0153 
0154   bool empty() const { return current_size_ == 0; }
0155   int size() const { return current_size_; }
0156   // Returns the size of the buffer with pointers to elements.
0157   //
0158   // Note:
0159   //
0160   //   * prefer `SizeAtCapacity()` to `size() == Capacity()`;
0161   //   * prefer `AllocatedSizeAtCapacity()` to `allocated_size() == Capacity()`.
0162   int Capacity() const { return capacity_proxy_ + kSSOCapacity; }
0163 
0164   template <typename TypeHandler>
0165   const Value<TypeHandler>& at(int index) const {
0166     ABSL_CHECK_GE(index, 0);
0167     ABSL_CHECK_LT(index, current_size_);
0168     return *cast<TypeHandler>(element_at(index));
0169   }
0170 
0171   template <typename TypeHandler>
0172   Value<TypeHandler>& at(int index) {
0173     ABSL_CHECK_GE(index, 0);
0174     ABSL_CHECK_LT(index, current_size_);
0175     return *cast<TypeHandler>(element_at(index));
0176   }
0177 
0178   template <typename TypeHandler>
0179   Value<TypeHandler>* Mutable(int index) {
0180     ABSL_DCHECK_GE(index, 0);
0181     ABSL_DCHECK_LT(index, current_size_);
0182     return cast<TypeHandler>(element_at(index));
0183   }
0184 
0185   template <typename Handler>
0186   Value<Handler>* Add() {
0187     if (std::is_same<Value<Handler>, std::string>{}) {
0188       return cast<Handler>(AddString());
0189     }
0190     return cast<Handler>(AddMessageLite(Handler::GetNewFunc()));
0191   }
0192 
0193   template <
0194       typename TypeHandler,
0195       typename std::enable_if<TypeHandler::Movable::value>::type* = nullptr>
0196   inline void Add(Value<TypeHandler>&& value) {
0197     if (current_size_ < allocated_size()) {
0198       *cast<TypeHandler>(element_at(ExchangeCurrentSize(current_size_ + 1))) =
0199           std::move(value);
0200       return;
0201     }
0202     MaybeExtend();
0203     if (!using_sso()) ++rep()->allocated_size;
0204     auto* result = TypeHandler::New(arena_, std::move(value));
0205     element_at(ExchangeCurrentSize(current_size_ + 1)) = result;
0206   }
0207 
0208   // Must be called from destructor.
0209   //
0210   // Pre-condition: NeedsDestroy() returns true.
0211   template <typename TypeHandler>
0212   void Destroy() {
0213     ABSL_DCHECK(NeedsDestroy());
0214 
0215     // TODO: arena check is redundant once all `RepeatedPtrField`s
0216     // with non-null arena are owned by the arena.
0217     if (PROTOBUF_PREDICT_FALSE(arena_ != nullptr)) return;
0218 
0219     using H = CommonHandler<TypeHandler>;
0220     int n = allocated_size();
0221     void** elems = elements();
0222     for (int i = 0; i < n; i++) {
0223       Delete<H>(elems[i], nullptr);
0224     }
0225     if (!using_sso()) {
0226       internal::SizedDelete(rep(),
0227                             Capacity() * sizeof(elems[0]) + kRepHeaderSize);
0228     }
0229   }
0230 
0231   inline bool NeedsDestroy() const {
0232     // Either there is an allocated element in SSO buffer or there is an
0233     // allocated Rep.
0234     return tagged_rep_or_elem_ != nullptr;
0235   }
0236   void DestroyProtos();
0237 
0238  public:
0239   // The next few methods are public so that they can be called from generated
0240   // code when implicit weak fields are used, but they should never be called by
0241   // application code.
0242 
0243   template <typename TypeHandler>
0244   const Value<TypeHandler>& Get(int index) const {
0245     ABSL_DCHECK_GE(index, 0);
0246     ABSL_DCHECK_LT(index, current_size_);
0247     return *cast<TypeHandler>(element_at(index));
0248   }
0249 
0250   // Creates and adds an element using the given prototype, without introducing
0251   // a link-time dependency on the concrete message type.
0252   //
0253   // Pre-condition: prototype must not be nullptr.
0254   MessageLite* AddMessage(const MessageLite* prototype);
0255 
0256   template <typename TypeHandler>
0257   void Clear() {
0258     const int n = current_size_;
0259     ABSL_DCHECK_GE(n, 0);
0260     if (n > 0) {
0261       using H = CommonHandler<TypeHandler>;
0262       ClearNonEmpty<H>();
0263     }
0264   }
0265 
0266   // Appends all message values from `from` to this instance.
0267   template <typename T>
0268   void MergeFrom(const RepeatedPtrFieldBase& from) {
0269     static_assert(std::is_base_of<MessageLite, T>::value, "");
0270 #ifdef __cpp_if_constexpr
0271     if constexpr (!std::is_base_of<Message, T>::value) {
0272       // For LITE objects we use the generic MergeFrom to save on binary size.
0273       return MergeFrom<MessageLite>(from);
0274     }
0275 #endif
0276     MergeFromConcreteMessage(from, Arena::CopyConstruct<T>);
0277   }
0278 
0279   inline void InternalSwap(RepeatedPtrFieldBase* PROTOBUF_RESTRICT rhs) {
0280     ABSL_DCHECK(this != rhs);
0281 
0282     // Swap all fields except arena pointer at once.
0283     internal::memswap<ArenaOffsetHelper<RepeatedPtrFieldBase>::value>(
0284         reinterpret_cast<char*>(this), reinterpret_cast<char*>(rhs));
0285   }
0286 
0287   // Returns true if there are no preallocated elements in the array.
0288   bool PrepareForParse() { return allocated_size() == current_size_; }
0289 
0290   // Similar to `AddAllocated` but faster.
0291   //
0292   // Pre-condition: PrepareForParse() is true.
0293   void AddAllocatedForParse(void* value) {
0294     ABSL_DCHECK(PrepareForParse());
0295     if (PROTOBUF_PREDICT_FALSE(SizeAtCapacity())) {
0296       *InternalExtend(1) = value;
0297       ++rep()->allocated_size;
0298     } else {
0299       if (using_sso()) {
0300         tagged_rep_or_elem_ = value;
0301       } else {
0302         rep()->elements[current_size_] = value;
0303         ++rep()->allocated_size;
0304       }
0305     }
0306     ExchangeCurrentSize(current_size_ + 1);
0307   }
0308 
0309  protected:
0310   template <typename TypeHandler>
0311   void RemoveLast() {
0312     ABSL_DCHECK_GT(current_size_, 0);
0313     ExchangeCurrentSize(current_size_ - 1);
0314     using H = CommonHandler<TypeHandler>;
0315     H::Clear(cast<H>(element_at(current_size_)));
0316   }
0317 
0318   template <typename TypeHandler>
0319   void CopyFrom(const RepeatedPtrFieldBase& other) {
0320     if (&other == this) return;
0321     RepeatedPtrFieldBase::Clear<TypeHandler>();
0322     if (other.empty()) return;
0323     RepeatedPtrFieldBase::MergeFrom<typename TypeHandler::Type>(other);
0324   }
0325 
0326   void CloseGap(int start, int num);
0327 
0328   void Reserve(int capacity);
0329 
0330   template <typename TypeHandler>
0331   static inline Value<TypeHandler>* copy(const Value<TypeHandler>* value) {
0332     using H = CommonHandler<TypeHandler>;
0333     auto* new_value = H::NewFromPrototype(value, nullptr);
0334     H::Merge(*value, new_value);
0335     return cast<TypeHandler>(new_value);
0336   }
0337 
0338   // Used for constructing iterators.
0339   void* const* raw_data() const { return elements(); }
0340   void** raw_mutable_data() { return elements(); }
0341 
0342   template <typename TypeHandler>
0343   Value<TypeHandler>** mutable_data() {
0344     // TODO:  Breaks C++ aliasing rules.  We should probably remove this
0345     //   method entirely.
0346     return reinterpret_cast<Value<TypeHandler>**>(raw_mutable_data());
0347   }
0348 
0349   template <typename TypeHandler>
0350   const Value<TypeHandler>* const* data() const {
0351     // TODO:  Breaks C++ aliasing rules.  We should probably remove this
0352     //   method entirely.
0353     return reinterpret_cast<const Value<TypeHandler>* const*>(raw_data());
0354   }
0355 
0356   template <typename TypeHandler>
0357   PROTOBUF_NDEBUG_INLINE void Swap(RepeatedPtrFieldBase* other) {
0358 #ifdef PROTOBUF_FORCE_COPY_IN_SWAP
0359     if (GetArena() != nullptr && GetArena() == other->GetArena())
0360 #else   // PROTOBUF_FORCE_COPY_IN_SWAP
0361     if (GetArena() == other->GetArena())
0362 #endif  // !PROTOBUF_FORCE_COPY_IN_SWAP
0363     {
0364       InternalSwap(other);
0365     } else {
0366       SwapFallback<TypeHandler>(other);
0367     }
0368   }
0369 
0370   void SwapElements(int index1, int index2) {
0371     using std::swap;  // enable ADL with fallback
0372     swap(element_at(index1), element_at(index2));
0373   }
0374 
0375   template <typename TypeHandler>
0376   PROTOBUF_NOINLINE size_t SpaceUsedExcludingSelfLong() const {
0377     size_t allocated_bytes =
0378         using_sso()
0379             ? 0
0380             : static_cast<size_t>(Capacity()) * sizeof(void*) + kRepHeaderSize;
0381     const int n = allocated_size();
0382     void* const* elems = elements();
0383     for (int i = 0; i < n; ++i) {
0384       allocated_bytes +=
0385           TypeHandler::SpaceUsedLong(*cast<TypeHandler>(elems[i]));
0386     }
0387     return allocated_bytes;
0388   }
0389 
0390   // Advanced memory management --------------------------------------
0391 
0392   // Like Add(), but if there are no cleared objects to use, returns nullptr.
0393   template <typename TypeHandler>
0394   Value<TypeHandler>* AddFromCleared() {
0395     if (current_size_ < allocated_size()) {
0396       return cast<TypeHandler>(
0397           element_at(ExchangeCurrentSize(current_size_ + 1)));
0398     } else {
0399       return nullptr;
0400     }
0401   }
0402 
0403   template <typename TypeHandler>
0404   void AddAllocated(Value<TypeHandler>* value) {
0405     ABSL_DCHECK_NE(value, nullptr);
0406     Arena* element_arena = TypeHandler::GetArena(value);
0407     Arena* arena = GetArena();
0408     if (arena != element_arena || AllocatedSizeAtCapacity()) {
0409       AddAllocatedSlowWithCopy<TypeHandler>(value, element_arena, arena);
0410       return;
0411     }
0412     // Fast path: underlying arena representation (tagged pointer) is equal to
0413     // our arena pointer, and we can add to array without resizing it (at
0414     // least one slot that is not allocated).
0415     void** elems = elements();
0416     if (current_size_ < allocated_size()) {
0417       // Make space at [current] by moving first allocated element to end of
0418       // allocated list.
0419       elems[allocated_size()] = elems[current_size_];
0420     }
0421     elems[ExchangeCurrentSize(current_size_ + 1)] = value;
0422     if (!using_sso()) ++rep()->allocated_size;
0423   }
0424 
0425   template <typename TypeHandler>
0426   void UnsafeArenaAddAllocated(Value<TypeHandler>* value) {
0427     ABSL_DCHECK_NE(value, nullptr);
0428     // Make room for the new pointer.
0429     if (SizeAtCapacity()) {
0430       // The array is completely full with no cleared objects, so grow it.
0431       InternalExtend(1);
0432       ++rep()->allocated_size;
0433     } else if (AllocatedSizeAtCapacity()) {
0434       // There is no more space in the pointer array because it contains some
0435       // cleared objects awaiting reuse.  We don't want to grow the array in
0436       // this case because otherwise a loop calling AddAllocated() followed by
0437       // Clear() would leak memory.
0438       using H = CommonHandler<TypeHandler>;
0439       Delete<H>(element_at(current_size_), arena_);
0440     } else if (current_size_ < allocated_size()) {
0441       // We have some cleared objects.  We don't care about their order, so we
0442       // can just move the first one to the end to make space.
0443       element_at(allocated_size()) = element_at(current_size_);
0444       ++rep()->allocated_size;
0445     } else {
0446       // There are no cleared objects.
0447       if (!using_sso()) ++rep()->allocated_size;
0448     }
0449 
0450     element_at(ExchangeCurrentSize(current_size_ + 1)) = value;
0451   }
0452 
0453   template <typename TypeHandler>
0454   PROTOBUF_NODISCARD Value<TypeHandler>* ReleaseLast() {
0455     Value<TypeHandler>* result = UnsafeArenaReleaseLast<TypeHandler>();
0456     // Now perform a copy if we're on an arena.
0457     Arena* arena = GetArena();
0458 
0459 #ifdef PROTOBUF_FORCE_COPY_IN_RELEASE
0460     auto* new_result = copy<TypeHandler>(result);
0461     if (arena == nullptr) delete result;
0462 #else   // PROTOBUF_FORCE_COPY_IN_RELEASE
0463     auto* new_result = (arena == nullptr) ? result : copy<TypeHandler>(result);
0464 #endif  // !PROTOBUF_FORCE_COPY_IN_RELEASE
0465     return new_result;
0466   }
0467 
0468   // Releases and returns the last element, but does not do out-of-arena copy.
0469   // Instead, just returns the raw pointer to the contained element in the
0470   // arena.
0471   template <typename TypeHandler>
0472   Value<TypeHandler>* UnsafeArenaReleaseLast() {
0473     ABSL_DCHECK_GT(current_size_, 0);
0474     ExchangeCurrentSize(current_size_ - 1);
0475     auto* result = cast<TypeHandler>(element_at(current_size_));
0476     if (using_sso()) {
0477       tagged_rep_or_elem_ = nullptr;
0478     } else {
0479       --rep()->allocated_size;
0480       if (current_size_ < allocated_size()) {
0481         // There are cleared elements on the end; replace the removed element
0482         // with the last allocated element.
0483         element_at(current_size_) = element_at(allocated_size());
0484       }
0485     }
0486     return result;
0487   }
0488 
0489   int ClearedCount() const { return allocated_size() - current_size_; }
0490 
0491   // Slowpath handles all cases, copying if necessary.
0492   template <typename TypeHandler>
0493   PROTOBUF_NOINLINE void AddAllocatedSlowWithCopy(
0494       // Pass value_arena and my_arena to avoid duplicate virtual call (value)
0495       // or load (mine).
0496       Value<TypeHandler>* value, Arena* value_arena, Arena* my_arena) {
0497     using H = CommonHandler<TypeHandler>;
0498     // Ensure that either the value is in the same arena, or if not, we do the
0499     // appropriate thing: Own() it (if it's on heap and we're in an arena) or
0500     // copy it to our arena/heap (otherwise).
0501     if (my_arena != nullptr && value_arena == nullptr) {
0502       my_arena->Own(value);
0503     } else if (my_arena != value_arena) {
0504       ABSL_DCHECK(value_arena != nullptr);
0505       auto* new_value = TypeHandler::NewFromPrototype(value, my_arena);
0506       H::Merge(*value, new_value);
0507       value = new_value;
0508     }
0509 
0510     UnsafeArenaAddAllocated<H>(value);
0511   }
0512 
0513   template <typename TypeHandler>
0514   PROTOBUF_NOINLINE void SwapFallback(RepeatedPtrFieldBase* other) {
0515 #ifdef PROTOBUF_FORCE_COPY_IN_SWAP
0516     ABSL_DCHECK(GetArena() == nullptr || other->GetArena() != GetArena());
0517 #else   // PROTOBUF_FORCE_COPY_IN_SWAP
0518     ABSL_DCHECK(other->GetArena() != GetArena());
0519 #endif  // !PROTOBUF_FORCE_COPY_IN_SWAP
0520 
0521     // Copy semantics in this case. We try to improve efficiency by placing the
0522     // temporary on |other|'s arena so that messages are copied twice rather
0523     // than three times.
0524     RepeatedPtrFieldBase temp(other->GetArena());
0525     if (!this->empty()) {
0526       temp.MergeFrom<typename TypeHandler::Type>(*this);
0527     }
0528     this->CopyFrom<TypeHandler>(*other);
0529     other->InternalSwap(&temp);
0530     if (temp.NeedsDestroy()) {
0531       temp.Destroy<TypeHandler>();
0532     }
0533   }
0534 
0535   // Gets the Arena on which this RepeatedPtrField stores its elements.
0536   inline Arena* GetArena() const { return arena_; }
0537 
0538  private:
0539   using InternalArenaConstructable_ = void;
0540   using DestructorSkippable_ = void;
0541 
0542   template <typename T>
0543   friend class Arena::InternalHelper;
0544 
0545   // ExtensionSet stores repeated message extensions as
0546   // RepeatedPtrField<MessageLite>, but non-lite ExtensionSets need to implement
0547   // SpaceUsedLong(), and thus need to call SpaceUsedExcludingSelfLong()
0548   // reinterpreting MessageLite as Message.  ExtensionSet also needs to make use
0549   // of AddFromCleared(), which is not part of the public interface.
0550   friend class ExtensionSet;
0551 
0552   // The MapFieldBase implementation needs to call protected methods directly,
0553   // reinterpreting pointers as being to Message instead of a specific Message
0554   // subclass.
0555   friend class MapFieldBase;
0556   friend struct MapFieldTestPeer;
0557 
0558   // The table-driven MergePartialFromCodedStream implementation needs to
0559   // operate on RepeatedPtrField<MessageLite>.
0560   friend class MergePartialFromCodedStreamHelper;
0561 
0562   friend class AccessorHelper;
0563 
0564   template <typename T>
0565   friend struct google::protobuf::WeakRepeatedPtrField;
0566 
0567   friend class internal::TcParser;  // TODO: Remove this friend.
0568 
0569   // Expose offset of `arena_` without exposing the member itself.
0570   // Used to optimize code size of `InternalSwap` method.
0571   template <typename T>
0572   friend struct ArenaOffsetHelper;
0573 
0574   // The reflection implementation needs to call protected methods directly,
0575   // reinterpreting pointers as being to Message instead of a specific Message
0576   // subclass.
0577   friend class google::protobuf::Reflection;
0578   friend class internal::SwapFieldHelper;
0579 
0580   // Concrete Arena enabled copy function used to copy messages instances.
0581   // This follows the `Arena::CopyConstruct` signature so that the compiler
0582   // can have the inlined call into the out of line copy function(s) simply pass
0583   // the address of `Arena::CopyConstruct` 'as is'.
0584   using CopyFn = void* (*)(Arena*, const void*);
0585 
0586   struct Rep {
0587     int allocated_size;
0588     // Here we declare a huge array as a way of approximating C's "flexible
0589     // array member" feature without relying on undefined behavior.
0590     void* elements[(std::numeric_limits<int>::max() - 2 * sizeof(int)) /
0591                    sizeof(void*)];
0592   };
0593 
0594   static constexpr size_t kRepHeaderSize = offsetof(Rep, elements);
0595 
0596   // Replaces current_size_ with new_size and returns the previous value of
0597   // current_size_. This function is intended to be the only place where
0598   // current_size_ is modified.
0599   inline int ExchangeCurrentSize(int new_size) {
0600     return std::exchange(current_size_, new_size);
0601   }
0602   inline bool SizeAtCapacity() const {
0603     // Harden invariant size() <= allocated_size() <= Capacity().
0604     ABSL_DCHECK_LE(size(), allocated_size());
0605     ABSL_DCHECK_LE(allocated_size(), Capacity());
0606     // This is equivalent to `current_size_ == Capacity()`.
0607     // Assuming `Capacity()` function is inlined, compiler is likely to optimize
0608     // away "+ kSSOCapacity" and reduce it to "current_size_ > capacity_proxy_"
0609     // which is an instruction less than "current_size_ == capacity_proxy_ + 1".
0610     return current_size_ >= Capacity();
0611   }
0612   inline bool AllocatedSizeAtCapacity() const {
0613     // Harden invariant size() <= allocated_size() <= Capacity().
0614     ABSL_DCHECK_LE(size(), allocated_size());
0615     ABSL_DCHECK_LE(allocated_size(), Capacity());
0616     // This combines optimization mentioned in `SizeAtCapacity()` and simplifies
0617     // `allocated_size()` in sso case.
0618     return using_sso() ? (tagged_rep_or_elem_ != nullptr)
0619                        : rep()->allocated_size >= Capacity();
0620   }
0621 
0622   void* const* elements() const {
0623     return using_sso() ? &tagged_rep_or_elem_ : +rep()->elements;
0624   }
0625   void** elements() {
0626     return using_sso() ? &tagged_rep_or_elem_ : +rep()->elements;
0627   }
0628 
0629   void*& element_at(int index) {
0630     if (using_sso()) {
0631       ABSL_DCHECK_EQ(index, 0);
0632       return tagged_rep_or_elem_;
0633     }
0634     return rep()->elements[index];
0635   }
0636   const void* element_at(int index) const {
0637     return const_cast<RepeatedPtrFieldBase*>(this)->element_at(index);
0638   }
0639 
0640   int allocated_size() const {
0641     return using_sso() ? (tagged_rep_or_elem_ != nullptr ? 1 : 0)
0642                        : rep()->allocated_size;
0643   }
0644   Rep* rep() {
0645     ABSL_DCHECK(!using_sso());
0646     return reinterpret_cast<Rep*>(
0647         reinterpret_cast<uintptr_t>(tagged_rep_or_elem_) - 1);
0648   }
0649   const Rep* rep() const {
0650     return const_cast<RepeatedPtrFieldBase*>(this)->rep();
0651   }
0652 
0653   bool using_sso() const {
0654     return (reinterpret_cast<uintptr_t>(tagged_rep_or_elem_) & 1) == 0;
0655   }
0656 
0657   template <typename TypeHandler>
0658   static inline Value<TypeHandler>* cast(void* element) {
0659     return reinterpret_cast<Value<TypeHandler>*>(element);
0660   }
0661   template <typename TypeHandler>
0662   static inline const Value<TypeHandler>* cast(const void* element) {
0663     return reinterpret_cast<const Value<TypeHandler>*>(element);
0664   }
0665   template <typename TypeHandler>
0666   static inline void Delete(void* obj, Arena* arena) {
0667     TypeHandler::Delete(cast<TypeHandler>(obj), arena);
0668   }
0669 
0670   // Out-of-line helper routine for Clear() once the inlined check has
0671   // determined the container is non-empty
0672   template <typename TypeHandler>
0673   PROTOBUF_NOINLINE void ClearNonEmpty() {
0674     const int n = current_size_;
0675     void* const* elems = elements();
0676     int i = 0;
0677     ABSL_DCHECK_GT(n, 0);
0678     // do/while loop to avoid initial test because we know n > 0
0679     do {
0680       TypeHandler::Clear(cast<TypeHandler>(elems[i++]));
0681     } while (i < n);
0682     ExchangeCurrentSize(0);
0683   }
0684 
0685   // Merges messages from `from` into available, cleared messages sitting in the
0686   // range `[size(), allocated_size())`. Returns the number of message merged
0687   // which is `ClearedCount(), from.size())`.
0688   // Note that this function does explicitly NOT update `current_size_`.
0689   // This function is out of line as it should be the slow path: this scenario
0690   // only happens when a caller constructs and fills a repeated field, then
0691   // shrinks it, and then merges additional messages into it.
0692   int MergeIntoClearedMessages(const RepeatedPtrFieldBase& from);
0693 
0694   // Appends all messages from `from` to this instance, using the
0695   // provided `copy_fn` copy function to copy existing messages.
0696   void MergeFromConcreteMessage(const RepeatedPtrFieldBase& from,
0697                                 CopyFn copy_fn);
0698 
0699   // Extends capacity by at least |extend_amount|.
0700   //
0701   // Pre-condition: |extend_amount| must be > 0.
0702   void** InternalExtend(int extend_amount);
0703 
0704   // Ensures that capacity is big enough to store one more allocated element.
0705   inline void MaybeExtend() {
0706     if (AllocatedSizeAtCapacity()) {
0707       ABSL_DCHECK_EQ(allocated_size(), Capacity());
0708       InternalExtend(1);
0709     } else {
0710       ABSL_DCHECK_NE(allocated_size(), Capacity());
0711     }
0712   }
0713 
0714   // Ensures that capacity is at least `n` elements.
0715   // Returns a pointer to the element directly beyond the last element.
0716   inline void** InternalReserve(int n) {
0717     if (n <= Capacity()) {
0718       void** elements = using_sso() ? &tagged_rep_or_elem_ : rep()->elements;
0719       return elements + current_size_;
0720     }
0721     return InternalExtend(n - Capacity());
0722   }
0723 
0724   // Internal helpers for Add that keep definition out-of-line.
0725   void* AddMessageLite(ElementFactory factory);
0726   void* AddString();
0727 
0728   // Common implementation used by various Add* methods. `factory` is an object
0729   // used to construct a new element unless there are spare cleared elements
0730   // ready for reuse. Returns pointer to the new element.
0731   //
0732   // Note: avoid inlining this function in methods such as `Add()` as this would
0733   // drastically increase binary size due to template instantiation and implicit
0734   // inlining.
0735   template <typename Factory>
0736   void* AddInternal(Factory factory);
0737 
0738   // A few notes on internal representation:
0739   //
0740   // We use an indirected approach, with struct Rep, to keep
0741   // sizeof(RepeatedPtrFieldBase) equivalent to what it was before arena support
0742   // was added; namely, 3 8-byte machine words on x86-64. An instance of Rep is
0743   // allocated only when the repeated field is non-empty, and it is a
0744   // dynamically-sized struct (the header is directly followed by elements[]).
0745   // We place arena_ and current_size_ directly in the object to avoid cache
0746   // misses due to the indirection, because these fields are checked frequently.
0747   // Placing all fields directly in the RepeatedPtrFieldBase instance would cost
0748   // significant performance for memory-sensitive workloads.
0749   void* tagged_rep_or_elem_;
0750   int current_size_;
0751   int capacity_proxy_;  // we store `capacity - kSSOCapacity` as an optimization
0752   Arena* arena_;
0753 };
0754 
0755 // Appends all message values from `from` to this instance using the abstract
0756 // message interface. This overload is used in places like reflection and
0757 // other locations where the underlying type is unavailable
0758 template <>
0759 void RepeatedPtrFieldBase::MergeFrom<MessageLite>(
0760     const RepeatedPtrFieldBase& from);
0761 
0762 template <>
0763 inline void RepeatedPtrFieldBase::MergeFrom<Message>(
0764     const RepeatedPtrFieldBase& from) {
0765   return MergeFrom<MessageLite>(from);
0766 }
0767 
0768 // Appends all `std::string` values from `from` to this instance.
0769 template <>
0770 void RepeatedPtrFieldBase::MergeFrom<std::string>(
0771     const RepeatedPtrFieldBase& from);
0772 
0773 
0774 template <typename F>
0775 void* RepeatedPtrFieldBase::AddInternal(F factory) {
0776   Arena* const arena = GetArena();
0777   if (tagged_rep_or_elem_ == nullptr) {
0778     ExchangeCurrentSize(1);
0779     tagged_rep_or_elem_ = factory(arena);
0780     return tagged_rep_or_elem_;
0781   }
0782   absl::PrefetchToLocalCache(tagged_rep_or_elem_);
0783   if (using_sso()) {
0784     if (current_size_ == 0) {
0785       ExchangeCurrentSize(1);
0786       return tagged_rep_or_elem_;
0787     }
0788     void*& result = *InternalExtend(1);
0789     result = factory(arena);
0790     Rep* r = rep();
0791     r->allocated_size = 2;
0792     ExchangeCurrentSize(2);
0793     return result;
0794   }
0795   Rep* r = rep();
0796   if (PROTOBUF_PREDICT_FALSE(SizeAtCapacity())) {
0797     InternalExtend(1);
0798     r = rep();
0799   } else {
0800     if (current_size_ != r->allocated_size) {
0801       return r->elements[ExchangeCurrentSize(current_size_ + 1)];
0802     }
0803   }
0804   ++r->allocated_size;
0805   void*& result = r->elements[ExchangeCurrentSize(current_size_ + 1)];
0806   result = factory(arena);
0807   return result;
0808 }
0809 
0810 PROTOBUF_EXPORT void InternalOutOfLineDeleteMessageLite(MessageLite* message);
0811 
0812 template <typename GenericType>
0813 class GenericTypeHandler {
0814  public:
0815   typedef GenericType Type;
0816   using Movable = IsMovable<GenericType>;
0817 
0818   static constexpr auto GetNewFunc() { return Arena::DefaultConstruct<Type>; }
0819 
0820   static inline GenericType* New(Arena* arena) {
0821     return static_cast<GenericType*>(Arena::DefaultConstruct<Type>(arena));
0822   }
0823   static inline GenericType* New(Arena* arena, GenericType&& value) {
0824     return Arena::Create<GenericType>(arena, std::move(value));
0825   }
0826   static inline GenericType* NewFromPrototype(const GenericType* /*prototype*/,
0827                                               Arena* arena = nullptr) {
0828     return New(arena);
0829   }
0830   static inline void Delete(GenericType* value, Arena* arena) {
0831     if (arena != nullptr) return;
0832 #ifdef __cpp_if_constexpr
0833     if constexpr (std::is_base_of<MessageLite, GenericType>::value) {
0834       // Using virtual destructor to reduce generated code size that would have
0835       // happened otherwise due to inlined `~GenericType`.
0836       InternalOutOfLineDeleteMessageLite(value);
0837     } else {
0838       delete value;
0839     }
0840 #else
0841     delete value;
0842 #endif
0843   }
0844   static inline Arena* GetArena(GenericType* value) {
0845     return Arena::InternalGetArena(value);
0846   }
0847 
0848   static inline void Clear(GenericType* value) { value->Clear(); }
0849   static void Merge(const GenericType& from, GenericType* to);
0850   static inline size_t SpaceUsedLong(const GenericType& value) {
0851     return value.SpaceUsedLong();
0852   }
0853 };
0854 
0855 // NewFromPrototypeHelper() is not defined inline here, as we will need to do a
0856 // virtual function dispatch anyways to go from Message* to call New/Merge. (The
0857 // additional helper is needed as a workaround for MSVC.)
0858 PROTOBUF_EXPORT MessageLite* NewFromPrototypeHelper(
0859     const MessageLite* prototype, Arena* arena);
0860 
0861 template <>
0862 inline MessageLite* GenericTypeHandler<MessageLite>::NewFromPrototype(
0863     const MessageLite* prototype, Arena* arena) {
0864   return NewFromPrototypeHelper(prototype, arena);
0865 }
0866 template <>
0867 inline Arena* GenericTypeHandler<MessageLite>::GetArena(MessageLite* value) {
0868   return value->GetArena();
0869 }
0870 
0871 template <typename GenericType>
0872 PROTOBUF_NOINLINE inline void GenericTypeHandler<GenericType>::Merge(
0873     const GenericType& from, GenericType* to) {
0874   to->MergeFrom(from);
0875 }
0876 template <>
0877 PROTOBUF_EXPORT void GenericTypeHandler<MessageLite>::Merge(
0878     const MessageLite& from, MessageLite* to);
0879 
0880 // Message specialization bodies defined in message.cc. This split is necessary
0881 // to allow proto2-lite (which includes this header) to be independent of
0882 // Message.
0883 template <>
0884 PROTOBUF_EXPORT Message* GenericTypeHandler<Message>::NewFromPrototype(
0885     const Message* prototype, Arena* arena);
0886 template <>
0887 PROTOBUF_EXPORT Arena* GenericTypeHandler<Message>::GetArena(Message* value);
0888 
0889 PROTOBUF_EXPORT void* NewStringElement(Arena* arena);
0890 
0891 template <>
0892 class GenericTypeHandler<std::string> {
0893  public:
0894   typedef std::string Type;
0895   using Movable = IsMovable<Type>;
0896 
0897   static constexpr auto GetNewFunc() { return NewStringElement; }
0898 
0899   static PROTOBUF_NOINLINE std::string* New(Arena* arena) {
0900     return Arena::Create<std::string>(arena);
0901   }
0902   static PROTOBUF_NOINLINE std::string* New(Arena* arena, std::string&& value) {
0903     return Arena::Create<std::string>(arena, std::move(value));
0904   }
0905   static inline std::string* NewFromPrototype(const std::string*,
0906                                               Arena* arena) {
0907     return New(arena);
0908   }
0909   static inline Arena* GetArena(std::string*) { return nullptr; }
0910   static inline void Delete(std::string* value, Arena* arena) {
0911     if (arena == nullptr) {
0912       delete value;
0913     }
0914   }
0915   static inline void Clear(std::string* value) { value->clear(); }
0916   static inline void Merge(const std::string& from, std::string* to) {
0917     *to = from;
0918   }
0919   static size_t SpaceUsedLong(const std::string& value) {
0920     return sizeof(value) + StringSpaceUsedExcludingSelfLong(value);
0921   }
0922 };
0923 
0924 }  // namespace internal
0925 
0926 // RepeatedPtrField is like RepeatedField, but used for repeated strings or
0927 // Messages.
0928 template <typename Element>
0929 class RepeatedPtrField final : private internal::RepeatedPtrFieldBase {
0930   static_assert(!std::is_const<Element>::value,
0931                 "We do not support const value types.");
0932   static_assert(!std::is_volatile<Element>::value,
0933                 "We do not support volatile value types.");
0934   static_assert(!std::is_pointer<Element>::value,
0935                 "We do not support pointer value types.");
0936   static_assert(!std::is_reference<Element>::value,
0937                 "We do not support reference value types.");
0938   static constexpr PROTOBUF_ALWAYS_INLINE void StaticValidityCheck() {
0939     static_assert(
0940         absl::disjunction<
0941             internal::is_supported_string_type<Element>,
0942             internal::is_supported_message_type<Element>>::value,
0943         "We only support string and Message types in RepeatedPtrField.");
0944   }
0945 
0946  public:
0947   using value_type = Element;
0948   using size_type = int;
0949   using difference_type = ptrdiff_t;
0950   using reference = Element&;
0951   using const_reference = const Element&;
0952   using pointer = Element*;
0953   using const_pointer = const Element*;
0954   using iterator = internal::RepeatedPtrIterator<Element>;
0955   using const_iterator = internal::RepeatedPtrIterator<const Element>;
0956   using reverse_iterator = std::reverse_iterator<iterator>;
0957   using const_reverse_iterator = std::reverse_iterator<const_iterator>;
0958   // Custom STL-like iterator that iterates over and returns the underlying
0959   // pointers to Element rather than Element itself.
0960   using pointer_iterator =
0961       internal::RepeatedPtrOverPtrsIterator<Element*, void*>;
0962   using const_pointer_iterator =
0963       internal::RepeatedPtrOverPtrsIterator<const Element* const,
0964                                             const void* const>;
0965 
0966   constexpr RepeatedPtrField();
0967 
0968   // Arena enabled constructors: for internal use only.
0969   RepeatedPtrField(internal::InternalVisibility, Arena* arena)
0970       : RepeatedPtrField(arena) {}
0971   RepeatedPtrField(internal::InternalVisibility, Arena* arena,
0972                    const RepeatedPtrField& rhs)
0973       : RepeatedPtrField(arena, rhs) {}
0974 
0975   // TODO: make constructor private
0976   explicit RepeatedPtrField(Arena* arena);
0977 
0978   template <typename Iter,
0979             typename = typename std::enable_if<std::is_constructible<
0980                 Element, decltype(*std::declval<Iter>())>::value>::type>
0981   RepeatedPtrField(Iter begin, Iter end);
0982 
0983   RepeatedPtrField(const RepeatedPtrField& rhs)
0984       : RepeatedPtrField(nullptr, rhs) {}
0985   RepeatedPtrField& operator=(const RepeatedPtrField& other)
0986       ABSL_ATTRIBUTE_LIFETIME_BOUND;
0987 
0988   RepeatedPtrField(RepeatedPtrField&& rhs) noexcept
0989       : RepeatedPtrField(nullptr, std::move(rhs)) {}
0990   RepeatedPtrField& operator=(RepeatedPtrField&& other) noexcept
0991       ABSL_ATTRIBUTE_LIFETIME_BOUND;
0992 
0993   ~RepeatedPtrField();
0994 
0995   bool empty() const;
0996   int size() const;
0997 
0998   const_reference Get(int index) const ABSL_ATTRIBUTE_LIFETIME_BOUND;
0999   pointer Mutable(int index) ABSL_ATTRIBUTE_LIFETIME_BOUND;
1000 
1001   // Unlike std::vector, adding an element to a RepeatedPtrField doesn't always
1002   // make a new element; it might re-use an element left over from when the
1003   // field was Clear()'d or resize()'d smaller.  For this reason, Add() is the
1004   // fastest API for adding a new element.
1005   pointer Add() ABSL_ATTRIBUTE_LIFETIME_BOUND;
1006 
1007   // `Add(std::move(value));` is equivalent to `*Add() = std::move(value);`
1008   // It will either move-construct to the end of this field, or swap value
1009   // with the new-or-recycled element at the end of this field.  Note that
1010   // this operation is very slow if this RepeatedPtrField is not on the
1011   // same Arena, if any, as `value`.
1012   void Add(Element&& value);
1013 
1014   // Copying to the end of this RepeatedPtrField is slowest of all; it can't
1015   // reliably copy-construct to the last element of this RepeatedPtrField, for
1016   // example (unlike std::vector).
1017   // We currently block this API.  The right way to add to the end is to call
1018   // Add() and modify the element it points to.
1019   // If you must add an existing value, call `*Add() = value;`
1020   void Add(const Element& value) = delete;
1021 
1022   // Append elements in the range [begin, end) after reserving
1023   // the appropriate number of elements.
1024   template <typename Iter>
1025   void Add(Iter begin, Iter end);
1026 
1027   const_reference operator[](int index) const ABSL_ATTRIBUTE_LIFETIME_BOUND {
1028     return Get(index);
1029   }
1030   reference operator[](int index) ABSL_ATTRIBUTE_LIFETIME_BOUND {
1031     return *Mutable(index);
1032   }
1033 
1034   const_reference at(int index) const ABSL_ATTRIBUTE_LIFETIME_BOUND;
1035   reference at(int index) ABSL_ATTRIBUTE_LIFETIME_BOUND;
1036 
1037   // Removes the last element in the array.
1038   // Ownership of the element is retained by the array.
1039   void RemoveLast();
1040 
1041   // Deletes elements with indices in the range [start .. start+num-1].
1042   // Caution: moves all elements with indices [start+num .. ].
1043   // Calling this routine inside a loop can cause quadratic behavior.
1044   void DeleteSubrange(int start, int num);
1045 
1046   ABSL_ATTRIBUTE_REINITIALIZES void Clear();
1047   void MergeFrom(const RepeatedPtrField& other);
1048   ABSL_ATTRIBUTE_REINITIALIZES void CopyFrom(const RepeatedPtrField& other);
1049 
1050   // Replaces the contents with RepeatedPtrField(begin, end).
1051   template <typename Iter>
1052   ABSL_ATTRIBUTE_REINITIALIZES void Assign(Iter begin, Iter end);
1053 
1054   // Reserves space to expand the field to at least the given size.  This only
1055   // resizes the pointer array; it doesn't allocate any objects.  If the
1056   // array is grown, it will always be at least doubled in size.
1057   void Reserve(int new_size);
1058 
1059   int Capacity() const;
1060 
1061   // Gets the underlying array.  This pointer is possibly invalidated by
1062   // any add or remove operation.
1063   Element**
1064   mutable_data() ABSL_ATTRIBUTE_LIFETIME_BOUND;
1065   const Element* const* data() const ABSL_ATTRIBUTE_LIFETIME_BOUND;
1066 
1067   // Swaps entire contents with "other". If they are on separate arenas, then
1068   // copies data.
1069   void Swap(RepeatedPtrField* other);
1070 
1071   // Swaps entire contents with "other". Caller should guarantee that either
1072   // both fields are on the same arena or both are on the heap. Swapping between
1073   // different arenas with this function is disallowed and is caught via
1074   // ABSL_DCHECK.
1075   void UnsafeArenaSwap(RepeatedPtrField* other);
1076 
1077   // Swaps two elements.
1078   void SwapElements(int index1, int index2);
1079 
1080   iterator begin() ABSL_ATTRIBUTE_LIFETIME_BOUND;
1081   const_iterator begin() const ABSL_ATTRIBUTE_LIFETIME_BOUND;
1082   const_iterator cbegin() const ABSL_ATTRIBUTE_LIFETIME_BOUND;
1083   iterator end() ABSL_ATTRIBUTE_LIFETIME_BOUND;
1084   const_iterator end() const ABSL_ATTRIBUTE_LIFETIME_BOUND;
1085   const_iterator cend() const ABSL_ATTRIBUTE_LIFETIME_BOUND;
1086 
1087   reverse_iterator rbegin() ABSL_ATTRIBUTE_LIFETIME_BOUND {
1088     return reverse_iterator(end());
1089   }
1090   const_reverse_iterator rbegin() const ABSL_ATTRIBUTE_LIFETIME_BOUND {
1091     return const_reverse_iterator(end());
1092   }
1093   reverse_iterator rend() ABSL_ATTRIBUTE_LIFETIME_BOUND {
1094     return reverse_iterator(begin());
1095   }
1096   const_reverse_iterator rend() const ABSL_ATTRIBUTE_LIFETIME_BOUND {
1097     return const_reverse_iterator(begin());
1098   }
1099 
1100   pointer_iterator pointer_begin() ABSL_ATTRIBUTE_LIFETIME_BOUND;
1101   const_pointer_iterator pointer_begin() const ABSL_ATTRIBUTE_LIFETIME_BOUND;
1102   pointer_iterator pointer_end() ABSL_ATTRIBUTE_LIFETIME_BOUND;
1103   const_pointer_iterator pointer_end() const ABSL_ATTRIBUTE_LIFETIME_BOUND;
1104 
1105   // Returns (an estimate of) the number of bytes used by the repeated field,
1106   // excluding sizeof(*this).
1107   size_t SpaceUsedExcludingSelfLong() const;
1108 
1109   int SpaceUsedExcludingSelf() const {
1110     return internal::ToIntSize(SpaceUsedExcludingSelfLong());
1111   }
1112 
1113   // Advanced memory management --------------------------------------
1114   // When hardcore memory management becomes necessary -- as it sometimes
1115   // does here at Google -- the following methods may be useful.
1116 
1117   // Adds an already-allocated object, passing ownership to the
1118   // RepeatedPtrField.
1119   //
1120   // Note that some special behavior occurs with respect to arenas:
1121   //
1122   //   (i) if this field holds submessages, the new submessage will be copied if
1123   //   the original is in an arena and this RepeatedPtrField is either in a
1124   //   different arena, or on the heap.
1125   //   (ii) if this field holds strings, the passed-in string *must* be
1126   //   heap-allocated, not arena-allocated. There is no way to dynamically check
1127   //   this at runtime, so User Beware.
1128   // Requires:  value != nullptr
1129   void AddAllocated(Element* value);
1130 
1131   // Removes and returns the last element, passing ownership to the caller.
1132   // Requires:  size() > 0
1133   //
1134   // If this RepeatedPtrField is on an arena, an object copy is required to pass
1135   // ownership back to the user (for compatible semantics). Use
1136   // UnsafeArenaReleaseLast() if this behavior is undesired.
1137   PROTOBUF_NODISCARD Element* ReleaseLast();
1138 
1139   // Adds an already-allocated object, skipping arena-ownership checks. The user
1140   // must guarantee that the given object is in the same arena as this
1141   // RepeatedPtrField.
1142   // It is also useful in legacy code that uses temporary ownership to avoid
1143   // copies. Example:
1144   //   RepeatedPtrField<T> temp_field;
1145   //   temp_field.UnsafeArenaAddAllocated(new T);
1146   //   ... // Do something with temp_field
1147   //   temp_field.UnsafeArenaExtractSubrange(0, temp_field.size(), nullptr);
1148   // If you put temp_field on the arena this fails, because the ownership
1149   // transfers to the arena at the "AddAllocated" call and is not released
1150   // anymore, causing a double delete. UnsafeArenaAddAllocated prevents this.
1151   // Requires:  value != nullptr
1152   void UnsafeArenaAddAllocated(Element* value);
1153 
1154   // Removes and returns the last element.  Unlike ReleaseLast, the returned
1155   // pointer is always to the original object.  This may be in an arena, in
1156   // which case it would have the arena's lifetime.
1157   // Requires: current_size_ > 0
1158   pointer UnsafeArenaReleaseLast();
1159 
1160   // Extracts elements with indices in the range "[start .. start+num-1]".
1161   // The caller assumes ownership of the extracted elements and is responsible
1162   // for deleting them when they are no longer needed.
1163   // If "elements" is non-nullptr, then pointers to the extracted elements
1164   // are stored in "elements[0 .. num-1]" for the convenience of the caller.
1165   // If "elements" is nullptr, then the caller must use some other mechanism
1166   // to perform any further operations (like deletion) on these elements.
1167   // Caution: implementation also moves elements with indices [start+num ..].
1168   // Calling this routine inside a loop can cause quadratic behavior.
1169   //
1170   // Memory copying behavior is identical to ReleaseLast(), described above: if
1171   // this RepeatedPtrField is on an arena, an object copy is performed for each
1172   // returned element, so that all returned element pointers are to
1173   // heap-allocated copies. If this copy is not desired, the user should call
1174   // UnsafeArenaExtractSubrange().
1175   void ExtractSubrange(int start, int num, Element** elements);
1176 
1177   // Identical to ExtractSubrange() described above, except that no object
1178   // copies are ever performed. Instead, the raw object pointers are returned.
1179   // Thus, if on an arena, the returned objects must not be freed, because they
1180   // will not be heap-allocated objects.
1181   void UnsafeArenaExtractSubrange(int start, int num, Element** elements);
1182 
1183   // When elements are removed by calls to RemoveLast() or Clear(), they
1184   // are not actually freed.  Instead, they are cleared and kept so that
1185   // they can be reused later.  This can save lots of CPU time when
1186   // repeatedly reusing a protocol message for similar purposes.
1187   //
1188   // Hardcore programs may choose to manipulate these cleared objects
1189   // to better optimize memory management using the following routines.
1190 
1191   // Gets the number of cleared objects that are currently being kept
1192   // around for reuse.
1193   ABSL_DEPRECATED("This will be removed in a future release")
1194   int ClearedCount() const;
1195 
1196   // Removes the element referenced by position.
1197   //
1198   // Returns an iterator to the element immediately following the removed
1199   // element.
1200   //
1201   // Invalidates all iterators at or after the removed element, including end().
1202   iterator erase(const_iterator position) ABSL_ATTRIBUTE_LIFETIME_BOUND;
1203 
1204   // Removes the elements in the range [first, last).
1205   //
1206   // Returns an iterator to the element immediately following the removed range.
1207   //
1208   // Invalidates all iterators at or after the removed range, including end().
1209   iterator erase(const_iterator first,
1210                  const_iterator last) ABSL_ATTRIBUTE_LIFETIME_BOUND;
1211 
1212   // Gets the arena on which this RepeatedPtrField stores its elements.
1213   inline Arena* GetArena();
1214 
1215   // For internal use only.
1216   //
1217   // This is public due to it being called by generated code.
1218   void InternalSwap(RepeatedPtrField* PROTOBUF_RESTRICT other) {
1219     internal::RepeatedPtrFieldBase::InternalSwap(other);
1220   }
1221 
1222 
1223  private:
1224   using InternalArenaConstructable_ = void;
1225   using DestructorSkippable_ = void;
1226 
1227   friend class Arena;
1228 
1229   friend class internal::TcParser;
1230 
1231   template <typename T>
1232   friend struct WeakRepeatedPtrField;
1233 
1234   // Note:  RepeatedPtrField SHOULD NOT be subclassed by users.
1235   using TypeHandler = internal::GenericTypeHandler<Element>;
1236 
1237   RepeatedPtrField(Arena* arena, const RepeatedPtrField& rhs);
1238   RepeatedPtrField(Arena* arena, RepeatedPtrField&& rhs);
1239 
1240 
1241   void AddAllocatedForParse(Element* p) {
1242     return RepeatedPtrFieldBase::AddAllocatedForParse(p);
1243   }
1244 };
1245 
1246 // -------------------------------------------------------------------
1247 
1248 template <typename Element>
1249 constexpr RepeatedPtrField<Element>::RepeatedPtrField()
1250     : RepeatedPtrFieldBase() {
1251   StaticValidityCheck();
1252 }
1253 
1254 template <typename Element>
1255 inline RepeatedPtrField<Element>::RepeatedPtrField(Arena* arena)
1256     : RepeatedPtrFieldBase(arena) {
1257   // We can't have StaticValidityCheck here because that requires Element to be
1258   // a complete type, and in split repeated fields cases, we call
1259   // CreateMessage<RepeatedPtrField<T>> for incomplete Ts.
1260 }
1261 
1262 template <typename Element>
1263 inline RepeatedPtrField<Element>::RepeatedPtrField(Arena* arena,
1264                                                    const RepeatedPtrField& rhs)
1265     : RepeatedPtrFieldBase(arena) {
1266   StaticValidityCheck();
1267   MergeFrom(rhs);
1268 }
1269 
1270 template <typename Element>
1271 template <typename Iter, typename>
1272 inline RepeatedPtrField<Element>::RepeatedPtrField(Iter begin, Iter end) {
1273   StaticValidityCheck();
1274   Add(begin, end);
1275 }
1276 
1277 template <typename Element>
1278 RepeatedPtrField<Element>::~RepeatedPtrField() {
1279   StaticValidityCheck();
1280   if (!NeedsDestroy()) return;
1281 #ifdef __cpp_if_constexpr
1282   if constexpr (std::is_base_of<MessageLite, Element>::value) {
1283 #else
1284   if (std::is_base_of<MessageLite, Element>::value) {
1285 #endif
1286     DestroyProtos();
1287   } else {
1288     Destroy<TypeHandler>();
1289   }
1290 }
1291 
1292 template <typename Element>
1293 inline RepeatedPtrField<Element>& RepeatedPtrField<Element>::operator=(
1294     const RepeatedPtrField& other) ABSL_ATTRIBUTE_LIFETIME_BOUND {
1295   if (this != &other) CopyFrom(other);
1296   return *this;
1297 }
1298 
1299 template <typename Element>
1300 inline RepeatedPtrField<Element>::RepeatedPtrField(Arena* arena,
1301                                                    RepeatedPtrField&& rhs)
1302     : RepeatedPtrField(arena) {
1303 #ifdef PROTOBUF_FORCE_COPY_IN_MOVE
1304   CopyFrom(rhs);
1305 #else   // PROTOBUF_FORCE_COPY_IN_MOVE
1306   // We don't just call Swap(&rhs) here because it would perform 3 copies if rhs
1307   // is on a different arena.
1308   if (arena != rhs.GetArena()) {
1309     CopyFrom(rhs);
1310   } else {
1311     InternalSwap(&rhs);
1312   }
1313 #endif  // !PROTOBUF_FORCE_COPY_IN_MOVE
1314 }
1315 
1316 template <typename Element>
1317 inline RepeatedPtrField<Element>& RepeatedPtrField<Element>::operator=(
1318     RepeatedPtrField&& other) noexcept ABSL_ATTRIBUTE_LIFETIME_BOUND {
1319   // We don't just call Swap(&other) here because it would perform 3 copies if
1320   // the two fields are on different arenas.
1321   if (this != &other) {
1322     if (GetArena() != other.GetArena()
1323 #ifdef PROTOBUF_FORCE_COPY_IN_MOVE
1324         || GetArena() == nullptr
1325 #endif  // !PROTOBUF_FORCE_COPY_IN_MOVE
1326     ) {
1327       CopyFrom(other);
1328     } else {
1329       InternalSwap(&other);
1330     }
1331   }
1332   return *this;
1333 }
1334 
1335 template <typename Element>
1336 inline bool RepeatedPtrField<Element>::empty() const {
1337   return RepeatedPtrFieldBase::empty();
1338 }
1339 
1340 template <typename Element>
1341 inline int RepeatedPtrField<Element>::size() const {
1342   return RepeatedPtrFieldBase::size();
1343 }
1344 
1345 template <typename Element>
1346 inline const Element& RepeatedPtrField<Element>::Get(int index) const
1347     ABSL_ATTRIBUTE_LIFETIME_BOUND {
1348   return RepeatedPtrFieldBase::Get<TypeHandler>(index);
1349 }
1350 
1351 template <typename Element>
1352 inline const Element& RepeatedPtrField<Element>::at(int index) const
1353     ABSL_ATTRIBUTE_LIFETIME_BOUND {
1354   return RepeatedPtrFieldBase::at<TypeHandler>(index);
1355 }
1356 
1357 template <typename Element>
1358 inline Element& RepeatedPtrField<Element>::at(int index)
1359     ABSL_ATTRIBUTE_LIFETIME_BOUND {
1360   return RepeatedPtrFieldBase::at<TypeHandler>(index);
1361 }
1362 
1363 
1364 template <typename Element>
1365 inline Element* RepeatedPtrField<Element>::Mutable(int index)
1366     ABSL_ATTRIBUTE_LIFETIME_BOUND {
1367   return RepeatedPtrFieldBase::Mutable<TypeHandler>(index);
1368 }
1369 
1370 template <typename Element>
1371 inline Element* RepeatedPtrField<Element>::Add() ABSL_ATTRIBUTE_LIFETIME_BOUND {
1372   return RepeatedPtrFieldBase::Add<TypeHandler>();
1373 }
1374 
1375 template <typename Element>
1376 inline void RepeatedPtrField<Element>::Add(Element&& value) {
1377   RepeatedPtrFieldBase::Add<TypeHandler>(std::move(value));
1378 }
1379 
1380 template <typename Element>
1381 template <typename Iter>
1382 inline void RepeatedPtrField<Element>::Add(Iter begin, Iter end) {
1383   if (std::is_base_of<
1384           std::forward_iterator_tag,
1385           typename std::iterator_traits<Iter>::iterator_category>::value) {
1386     int reserve = static_cast<int>(std::distance(begin, end));
1387     Reserve(size() + reserve);
1388   }
1389   for (; begin != end; ++begin) {
1390     *Add() = *begin;
1391   }
1392 }
1393 
1394 template <typename Element>
1395 inline void RepeatedPtrField<Element>::RemoveLast() {
1396   RepeatedPtrFieldBase::RemoveLast<TypeHandler>();
1397 }
1398 
1399 template <typename Element>
1400 inline void RepeatedPtrField<Element>::DeleteSubrange(int start, int num) {
1401   ABSL_DCHECK_GE(start, 0);
1402   ABSL_DCHECK_GE(num, 0);
1403   ABSL_DCHECK_LE(start + num, size());
1404   void** subrange = raw_mutable_data() + start;
1405   Arena* arena = GetArena();
1406   for (int i = 0; i < num; ++i) {
1407     using H = CommonHandler<TypeHandler>;
1408     H::Delete(static_cast<Element*>(subrange[i]), arena);
1409   }
1410   UnsafeArenaExtractSubrange(start, num, nullptr);
1411 }
1412 
1413 template <typename Element>
1414 inline void RepeatedPtrField<Element>::ExtractSubrange(int start, int num,
1415                                                        Element** elements) {
1416   ABSL_DCHECK_GE(start, 0);
1417   ABSL_DCHECK_GE(num, 0);
1418   ABSL_DCHECK_LE(start + num, size());
1419 
1420   if (num == 0) return;
1421 
1422   ABSL_DCHECK_NE(elements, nullptr)
1423       << "Releasing elements without transferring ownership is an unsafe "
1424          "operation.  Use UnsafeArenaExtractSubrange.";
1425   if (elements != nullptr) {
1426     Arena* arena = GetArena();
1427     auto* extracted = data() + start;
1428 #ifdef PROTOBUF_FORCE_COPY_IN_RELEASE
1429     // Always copy.
1430     for (int i = 0; i < num; ++i) {
1431       elements[i] = copy<TypeHandler>(extracted[i]);
1432     }
1433     if (arena == nullptr) {
1434       for (int i = 0; i < num; ++i) {
1435         delete extracted[i];
1436       }
1437     }
1438 #else   // PROTOBUF_FORCE_COPY_IN_RELEASE
1439     // If we're on an arena, we perform a copy for each element so that the
1440     // returned elements are heap-allocated. Otherwise, just forward it.
1441     if (arena != nullptr) {
1442       for (int i = 0; i < num; ++i) {
1443         elements[i] = copy<TypeHandler>(extracted[i]);
1444       }
1445     } else {
1446       memcpy(elements, extracted, num * sizeof(Element*));
1447     }
1448 #endif  // !PROTOBUF_FORCE_COPY_IN_RELEASE
1449   }
1450   CloseGap(start, num);
1451 }
1452 
1453 template <typename Element>
1454 inline void RepeatedPtrField<Element>::UnsafeArenaExtractSubrange(
1455     int start, int num, Element** elements) {
1456   ABSL_DCHECK_GE(start, 0);
1457   ABSL_DCHECK_GE(num, 0);
1458   ABSL_DCHECK_LE(start + num, size());
1459 
1460   if (num > 0) {
1461     // Save the values of the removed elements if requested.
1462     if (elements != nullptr) {
1463       memcpy(elements, data() + start, num * sizeof(Element*));
1464     }
1465     CloseGap(start, num);
1466   }
1467 }
1468 
1469 template <typename Element>
1470 inline void RepeatedPtrField<Element>::Clear() {
1471   RepeatedPtrFieldBase::Clear<TypeHandler>();
1472 }
1473 
1474 template <typename Element>
1475 inline void RepeatedPtrField<Element>::MergeFrom(
1476     const RepeatedPtrField& other) {
1477   if (other.empty()) return;
1478   RepeatedPtrFieldBase::MergeFrom<Element>(other);
1479 }
1480 
1481 template <typename Element>
1482 inline void RepeatedPtrField<Element>::CopyFrom(const RepeatedPtrField& other) {
1483   RepeatedPtrFieldBase::CopyFrom<TypeHandler>(other);
1484 }
1485 
1486 template <typename Element>
1487 template <typename Iter>
1488 inline void RepeatedPtrField<Element>::Assign(Iter begin, Iter end) {
1489   Clear();
1490   Add(begin, end);
1491 }
1492 
1493 template <typename Element>
1494 inline typename RepeatedPtrField<Element>::iterator
1495 RepeatedPtrField<Element>::erase(const_iterator position)
1496     ABSL_ATTRIBUTE_LIFETIME_BOUND {
1497   return erase(position, position + 1);
1498 }
1499 
1500 template <typename Element>
1501 inline typename RepeatedPtrField<Element>::iterator
1502 RepeatedPtrField<Element>::erase(const_iterator first, const_iterator last)
1503     ABSL_ATTRIBUTE_LIFETIME_BOUND {
1504   size_type pos_offset = static_cast<size_type>(std::distance(cbegin(), first));
1505   size_type last_offset = static_cast<size_type>(std::distance(cbegin(), last));
1506   DeleteSubrange(pos_offset, last_offset - pos_offset);
1507   return begin() + pos_offset;
1508 }
1509 
1510 template <typename Element>
1511 inline Element** RepeatedPtrField<Element>::mutable_data()
1512     ABSL_ATTRIBUTE_LIFETIME_BOUND {
1513   return RepeatedPtrFieldBase::mutable_data<TypeHandler>();
1514 }
1515 
1516 template <typename Element>
1517 inline const Element* const* RepeatedPtrField<Element>::data() const
1518     ABSL_ATTRIBUTE_LIFETIME_BOUND {
1519   return RepeatedPtrFieldBase::data<TypeHandler>();
1520 }
1521 
1522 template <typename Element>
1523 inline void RepeatedPtrField<Element>::Swap(RepeatedPtrField* other) {
1524   if (this == other) return;
1525   RepeatedPtrFieldBase::Swap<TypeHandler>(other);
1526 }
1527 
1528 template <typename Element>
1529 inline void RepeatedPtrField<Element>::UnsafeArenaSwap(
1530     RepeatedPtrField* other) {
1531   if (this == other) return;
1532   ABSL_DCHECK_EQ(GetArena(), other->GetArena());
1533   RepeatedPtrFieldBase::InternalSwap(other);
1534 }
1535 
1536 template <typename Element>
1537 inline void RepeatedPtrField<Element>::SwapElements(int index1, int index2) {
1538   RepeatedPtrFieldBase::SwapElements(index1, index2);
1539 }
1540 
1541 template <typename Element>
1542 inline Arena* RepeatedPtrField<Element>::GetArena() {
1543   return RepeatedPtrFieldBase::GetArena();
1544 }
1545 
1546 template <typename Element>
1547 inline size_t RepeatedPtrField<Element>::SpaceUsedExcludingSelfLong() const {
1548   // `google::protobuf::Message` has a virtual method `SpaceUsedLong`, hence we can
1549   // instantiate just one function for all protobuf messages.
1550   // Note: std::is_base_of requires that `Element` is a concrete class.
1551   using H = typename std::conditional<std::is_base_of<Message, Element>::value,
1552                                       internal::GenericTypeHandler<Message>,
1553                                       TypeHandler>::type;
1554   return RepeatedPtrFieldBase::SpaceUsedExcludingSelfLong<H>();
1555 }
1556 
1557 template <typename Element>
1558 inline void RepeatedPtrField<Element>::AddAllocated(Element* value) {
1559   RepeatedPtrFieldBase::AddAllocated<TypeHandler>(value);
1560 }
1561 
1562 template <typename Element>
1563 inline void RepeatedPtrField<Element>::UnsafeArenaAddAllocated(Element* value) {
1564   RepeatedPtrFieldBase::UnsafeArenaAddAllocated<TypeHandler>(value);
1565 }
1566 
1567 template <typename Element>
1568 inline Element* RepeatedPtrField<Element>::ReleaseLast() {
1569   return RepeatedPtrFieldBase::ReleaseLast<TypeHandler>();
1570 }
1571 
1572 template <typename Element>
1573 inline Element* RepeatedPtrField<Element>::UnsafeArenaReleaseLast() {
1574   return RepeatedPtrFieldBase::UnsafeArenaReleaseLast<TypeHandler>();
1575 }
1576 
1577 template <typename Element>
1578 inline int RepeatedPtrField<Element>::ClearedCount() const {
1579   return RepeatedPtrFieldBase::ClearedCount();
1580 }
1581 
1582 template <typename Element>
1583 inline void RepeatedPtrField<Element>::Reserve(int new_size) {
1584   return RepeatedPtrFieldBase::Reserve(new_size);
1585 }
1586 
1587 template <typename Element>
1588 inline int RepeatedPtrField<Element>::Capacity() const {
1589   return RepeatedPtrFieldBase::Capacity();
1590 }
1591 
1592 // -------------------------------------------------------------------
1593 
1594 namespace internal {
1595 
1596 // STL-like iterator implementation for RepeatedPtrField.  You should not
1597 // refer to this class directly; use RepeatedPtrField<T>::iterator instead.
1598 //
1599 // The iterator for RepeatedPtrField<T>, RepeatedPtrIterator<T>, is
1600 // very similar to iterator_ptr<T**> in util/gtl/iterator_adaptors.h,
1601 // but adds random-access operators and is modified to wrap a void** base
1602 // iterator (since RepeatedPtrField stores its array as a void* array and
1603 // casting void** to T** would violate C++ aliasing rules).
1604 //
1605 // This code based on net/proto/proto-array-internal.h by Jeffrey Yasskin
1606 // (jyasskin@google.com).
1607 template <typename Element>
1608 class RepeatedPtrIterator {
1609  public:
1610   using iterator = RepeatedPtrIterator<Element>;
1611   using iterator_category = std::random_access_iterator_tag;
1612   using value_type = typename std::remove_const<Element>::type;
1613   using difference_type = std::ptrdiff_t;
1614   using pointer = Element*;
1615   using reference = Element&;
1616 
1617   RepeatedPtrIterator() : it_(nullptr) {}
1618   explicit RepeatedPtrIterator(void* const* it) : it_(it) {}
1619 
1620   // Allows "upcasting" from RepeatedPtrIterator<T**> to
1621   // RepeatedPtrIterator<const T*const*>.
1622   template <typename OtherElement,
1623             typename std::enable_if<std::is_convertible<
1624                 OtherElement*, pointer>::value>::type* = nullptr>
1625   RepeatedPtrIterator(const RepeatedPtrIterator<OtherElement>& other)
1626       : it_(other.it_) {}
1627 
1628   // dereferenceable
1629   reference operator*() const { return *reinterpret_cast<Element*>(*it_); }
1630   pointer operator->() const { return &(operator*()); }
1631 
1632   // {inc,dec}rementable
1633   iterator& operator++() {
1634     ++it_;
1635     return *this;
1636   }
1637   iterator operator++(int) { return iterator(it_++); }
1638   iterator& operator--() {
1639     --it_;
1640     return *this;
1641   }
1642   iterator operator--(int) { return iterator(it_--); }
1643 
1644   // equality_comparable
1645   friend bool operator==(const iterator& x, const iterator& y) {
1646     return x.it_ == y.it_;
1647   }
1648   friend bool operator!=(const iterator& x, const iterator& y) {
1649     return x.it_ != y.it_;
1650   }
1651 
1652   // less_than_comparable
1653   friend bool operator<(const iterator& x, const iterator& y) {
1654     return x.it_ < y.it_;
1655   }
1656   friend bool operator<=(const iterator& x, const iterator& y) {
1657     return x.it_ <= y.it_;
1658   }
1659   friend bool operator>(const iterator& x, const iterator& y) {
1660     return x.it_ > y.it_;
1661   }
1662   friend bool operator>=(const iterator& x, const iterator& y) {
1663     return x.it_ >= y.it_;
1664   }
1665 
1666   // addable, subtractable
1667   iterator& operator+=(difference_type d) {
1668     it_ += d;
1669     return *this;
1670   }
1671   friend iterator operator+(iterator it, const difference_type d) {
1672     it += d;
1673     return it;
1674   }
1675   friend iterator operator+(const difference_type d, iterator it) {
1676     it += d;
1677     return it;
1678   }
1679   iterator& operator-=(difference_type d) {
1680     it_ -= d;
1681     return *this;
1682   }
1683   friend iterator operator-(iterator it, difference_type d) {
1684     it -= d;
1685     return it;
1686   }
1687 
1688   // indexable
1689   reference operator[](difference_type d) const { return *(*this + d); }
1690 
1691   // random access iterator
1692   friend difference_type operator-(iterator it1, iterator it2) {
1693     return it1.it_ - it2.it_;
1694   }
1695 
1696  private:
1697   template <typename OtherElement>
1698   friend class RepeatedPtrIterator;
1699 
1700   // The internal iterator.
1701   void* const* it_;
1702 };
1703 
1704 template <typename Traits, typename = void>
1705 struct IteratorConceptSupport {
1706   using tag = typename Traits::iterator_category;
1707 };
1708 
1709 template <typename Traits>
1710 struct IteratorConceptSupport<Traits,
1711                               absl::void_t<typename Traits::iterator_concept>> {
1712   using tag = typename Traits::iterator_concept;
1713 };
1714 
1715 // Provides an iterator that operates on pointers to the underlying objects
1716 // rather than the objects themselves as RepeatedPtrIterator does.
1717 // Consider using this when working with stl algorithms that change
1718 // the array.
1719 // The VoidPtr template parameter holds the type-agnostic pointer value
1720 // referenced by the iterator.  It should either be "void *" for a mutable
1721 // iterator, or "const void* const" for a constant iterator.
1722 template <typename Element, typename VoidPtr>
1723 class RepeatedPtrOverPtrsIterator {
1724  private:
1725   using traits =
1726       std::iterator_traits<typename std::remove_const<Element>::type*>;
1727 
1728  public:
1729   using value_type = typename traits::value_type;
1730   using difference_type = typename traits::difference_type;
1731   using pointer = Element*;
1732   using reference = Element&;
1733   using iterator_category = typename traits::iterator_category;
1734   using iterator_concept = typename IteratorConceptSupport<traits>::tag;
1735 
1736   using iterator = RepeatedPtrOverPtrsIterator<Element, VoidPtr>;
1737 
1738   RepeatedPtrOverPtrsIterator() : it_(nullptr) {}
1739   explicit RepeatedPtrOverPtrsIterator(VoidPtr* it) : it_(it) {}
1740 
1741   // Allows "upcasting" from RepeatedPtrOverPtrsIterator<T**> to
1742   // RepeatedPtrOverPtrsIterator<const T*const*>.
1743   template <
1744       typename OtherElement, typename OtherVoidPtr,
1745       typename std::enable_if<
1746           std::is_convertible<OtherElement*, pointer>::value &&
1747           std::is_convertible<OtherVoidPtr*, VoidPtr>::value>::type* = nullptr>
1748   RepeatedPtrOverPtrsIterator(
1749       const RepeatedPtrOverPtrsIterator<OtherElement, OtherVoidPtr>& other)
1750       : it_(other.it_) {}
1751 
1752   // dereferenceable
1753   reference operator*() const { return *reinterpret_cast<Element*>(it_); }
1754   pointer operator->() const { return reinterpret_cast<Element*>(it_); }
1755 
1756   // {inc,dec}rementable
1757   iterator& operator++() {
1758     ++it_;
1759     return *this;
1760   }
1761   iterator operator++(int) { return iterator(it_++); }
1762   iterator& operator--() {
1763     --it_;
1764     return *this;
1765   }
1766   iterator operator--(int) { return iterator(it_--); }
1767 
1768   // equality_comparable
1769   friend bool operator==(const iterator& x, const iterator& y) {
1770     return x.it_ == y.it_;
1771   }
1772   friend bool operator!=(const iterator& x, const iterator& y) {
1773     return x.it_ != y.it_;
1774   }
1775 
1776   // less_than_comparable
1777   friend bool operator<(const iterator& x, const iterator& y) {
1778     return x.it_ < y.it_;
1779   }
1780   friend bool operator<=(const iterator& x, const iterator& y) {
1781     return x.it_ <= y.it_;
1782   }
1783   friend bool operator>(const iterator& x, const iterator& y) {
1784     return x.it_ > y.it_;
1785   }
1786   friend bool operator>=(const iterator& x, const iterator& y) {
1787     return x.it_ >= y.it_;
1788   }
1789 
1790   // addable, subtractable
1791   iterator& operator+=(difference_type d) {
1792     it_ += d;
1793     return *this;
1794   }
1795   friend iterator operator+(iterator it, difference_type d) {
1796     it += d;
1797     return it;
1798   }
1799   friend iterator operator+(difference_type d, iterator it) {
1800     it += d;
1801     return it;
1802   }
1803   iterator& operator-=(difference_type d) {
1804     it_ -= d;
1805     return *this;
1806   }
1807   friend iterator operator-(iterator it, difference_type d) {
1808     it -= d;
1809     return it;
1810   }
1811 
1812   // indexable
1813   reference operator[](difference_type d) const { return *(*this + d); }
1814 
1815   // random access iterator
1816   friend difference_type operator-(iterator it1, iterator it2) {
1817     return it1.it_ - it2.it_;
1818   }
1819 
1820  private:
1821   template <typename OtherElement, typename OtherVoidPtr>
1822   friend class RepeatedPtrOverPtrsIterator;
1823 
1824   // The internal iterator.
1825   VoidPtr* it_;
1826 };
1827 
1828 }  // namespace internal
1829 
1830 template <typename Element>
1831 inline typename RepeatedPtrField<Element>::iterator
1832 RepeatedPtrField<Element>::begin() ABSL_ATTRIBUTE_LIFETIME_BOUND {
1833   return iterator(raw_data());
1834 }
1835 template <typename Element>
1836 inline typename RepeatedPtrField<Element>::const_iterator
1837 RepeatedPtrField<Element>::begin() const ABSL_ATTRIBUTE_LIFETIME_BOUND {
1838   return iterator(raw_data());
1839 }
1840 template <typename Element>
1841 inline typename RepeatedPtrField<Element>::const_iterator
1842 RepeatedPtrField<Element>::cbegin() const ABSL_ATTRIBUTE_LIFETIME_BOUND {
1843   return begin();
1844 }
1845 template <typename Element>
1846 inline typename RepeatedPtrField<Element>::iterator
1847 RepeatedPtrField<Element>::end() ABSL_ATTRIBUTE_LIFETIME_BOUND {
1848   return iterator(raw_data() + size());
1849 }
1850 template <typename Element>
1851 inline typename RepeatedPtrField<Element>::const_iterator
1852 RepeatedPtrField<Element>::end() const ABSL_ATTRIBUTE_LIFETIME_BOUND {
1853   return iterator(raw_data() + size());
1854 }
1855 template <typename Element>
1856 inline typename RepeatedPtrField<Element>::const_iterator
1857 RepeatedPtrField<Element>::cend() const ABSL_ATTRIBUTE_LIFETIME_BOUND {
1858   return end();
1859 }
1860 
1861 template <typename Element>
1862 inline typename RepeatedPtrField<Element>::pointer_iterator
1863 RepeatedPtrField<Element>::pointer_begin() ABSL_ATTRIBUTE_LIFETIME_BOUND {
1864   return pointer_iterator(raw_mutable_data());
1865 }
1866 template <typename Element>
1867 inline typename RepeatedPtrField<Element>::const_pointer_iterator
1868 RepeatedPtrField<Element>::pointer_begin() const ABSL_ATTRIBUTE_LIFETIME_BOUND {
1869   return const_pointer_iterator(const_cast<const void* const*>(raw_data()));
1870 }
1871 template <typename Element>
1872 inline typename RepeatedPtrField<Element>::pointer_iterator
1873 RepeatedPtrField<Element>::pointer_end() ABSL_ATTRIBUTE_LIFETIME_BOUND {
1874   return pointer_iterator(raw_mutable_data() + size());
1875 }
1876 template <typename Element>
1877 inline typename RepeatedPtrField<Element>::const_pointer_iterator
1878 RepeatedPtrField<Element>::pointer_end() const ABSL_ATTRIBUTE_LIFETIME_BOUND {
1879   return const_pointer_iterator(
1880       const_cast<const void* const*>(raw_data() + size()));
1881 }
1882 
1883 // Iterators and helper functions that follow the spirit of the STL
1884 // std::back_insert_iterator and std::back_inserter but are tailor-made
1885 // for RepeatedField and RepeatedPtrField. Typical usage would be:
1886 //
1887 //   std::copy(some_sequence.begin(), some_sequence.end(),
1888 //             RepeatedFieldBackInserter(proto.mutable_sequence()));
1889 //
1890 // Ported by johannes from util/gtl/proto-array-iterators.h
1891 
1892 namespace internal {
1893 
1894 // A back inserter for RepeatedPtrField objects.
1895 template <typename T>
1896 class RepeatedPtrFieldBackInsertIterator {
1897  public:
1898   using iterator_category = std::output_iterator_tag;
1899   using value_type = T;
1900   using pointer = void;
1901   using reference = void;
1902   using difference_type = std::ptrdiff_t;
1903 
1904   RepeatedPtrFieldBackInsertIterator(RepeatedPtrField<T>* const mutable_field)
1905       : field_(mutable_field) {}
1906   RepeatedPtrFieldBackInsertIterator<T>& operator=(const T& value) {
1907     *field_->Add() = value;
1908     return *this;
1909   }
1910   RepeatedPtrFieldBackInsertIterator<T>& operator=(
1911       const T* const ptr_to_value) {
1912     *field_->Add() = *ptr_to_value;
1913     return *this;
1914   }
1915   RepeatedPtrFieldBackInsertIterator<T>& operator=(T&& value) {
1916     *field_->Add() = std::move(value);
1917     return *this;
1918   }
1919   RepeatedPtrFieldBackInsertIterator<T>& operator*() { return *this; }
1920   RepeatedPtrFieldBackInsertIterator<T>& operator++() { return *this; }
1921   RepeatedPtrFieldBackInsertIterator<T>& operator++(int /* unused */) {
1922     return *this;
1923   }
1924 
1925  private:
1926   RepeatedPtrField<T>* field_;
1927 };
1928 
1929 // A back inserter for RepeatedPtrFields that inserts by transferring ownership
1930 // of a pointer.
1931 template <typename T>
1932 class AllocatedRepeatedPtrFieldBackInsertIterator {
1933  public:
1934   using iterator_category = std::output_iterator_tag;
1935   using value_type = T;
1936   using pointer = void;
1937   using reference = void;
1938   using difference_type = std::ptrdiff_t;
1939 
1940   explicit AllocatedRepeatedPtrFieldBackInsertIterator(
1941       RepeatedPtrField<T>* const mutable_field)
1942       : field_(mutable_field) {}
1943   AllocatedRepeatedPtrFieldBackInsertIterator<T>& operator=(
1944       T* const ptr_to_value) {
1945     field_->AddAllocated(ptr_to_value);
1946     return *this;
1947   }
1948   AllocatedRepeatedPtrFieldBackInsertIterator<T>& operator*() { return *this; }
1949   AllocatedRepeatedPtrFieldBackInsertIterator<T>& operator++() { return *this; }
1950   AllocatedRepeatedPtrFieldBackInsertIterator<T>& operator++(int /* unused */) {
1951     return *this;
1952   }
1953 
1954  private:
1955   RepeatedPtrField<T>* field_;
1956 };
1957 
1958 // Almost identical to AllocatedRepeatedPtrFieldBackInsertIterator. This one
1959 // uses the UnsafeArenaAddAllocated instead.
1960 template <typename T>
1961 class UnsafeArenaAllocatedRepeatedPtrFieldBackInsertIterator {
1962  public:
1963   using iterator_category = std::output_iterator_tag;
1964   using value_type = T;
1965   using pointer = void;
1966   using reference = void;
1967   using difference_type = std::ptrdiff_t;
1968 
1969   explicit UnsafeArenaAllocatedRepeatedPtrFieldBackInsertIterator(
1970       RepeatedPtrField<T>* const mutable_field)
1971       : field_(mutable_field) {}
1972   UnsafeArenaAllocatedRepeatedPtrFieldBackInsertIterator<T>& operator=(
1973       T const* const ptr_to_value) {
1974     field_->UnsafeArenaAddAllocated(const_cast<T*>(ptr_to_value));
1975     return *this;
1976   }
1977   UnsafeArenaAllocatedRepeatedPtrFieldBackInsertIterator<T>& operator*() {
1978     return *this;
1979   }
1980   UnsafeArenaAllocatedRepeatedPtrFieldBackInsertIterator<T>& operator++() {
1981     return *this;
1982   }
1983   UnsafeArenaAllocatedRepeatedPtrFieldBackInsertIterator<T>& operator++(
1984       int /* unused */) {
1985     return *this;
1986   }
1987 
1988  private:
1989   RepeatedPtrField<T>* field_;
1990 };
1991 
1992 }  // namespace internal
1993 
1994 // Provides a back insert iterator for RepeatedPtrField instances,
1995 // similar to std::back_inserter().
1996 template <typename T>
1997 internal::RepeatedPtrFieldBackInsertIterator<T> RepeatedPtrFieldBackInserter(
1998     RepeatedPtrField<T>* const mutable_field) {
1999   return internal::RepeatedPtrFieldBackInsertIterator<T>(mutable_field);
2000 }
2001 
2002 // Special back insert iterator for RepeatedPtrField instances, just in
2003 // case someone wants to write generic template code that can access both
2004 // RepeatedFields and RepeatedPtrFields using a common name.
2005 template <typename T>
2006 internal::RepeatedPtrFieldBackInsertIterator<T> RepeatedFieldBackInserter(
2007     RepeatedPtrField<T>* const mutable_field) {
2008   return internal::RepeatedPtrFieldBackInsertIterator<T>(mutable_field);
2009 }
2010 
2011 // Provides a back insert iterator for RepeatedPtrField instances
2012 // similar to std::back_inserter() which transfers the ownership while
2013 // copying elements.
2014 template <typename T>
2015 internal::AllocatedRepeatedPtrFieldBackInsertIterator<T>
2016 AllocatedRepeatedPtrFieldBackInserter(
2017     RepeatedPtrField<T>* const mutable_field) {
2018   return internal::AllocatedRepeatedPtrFieldBackInsertIterator<T>(
2019       mutable_field);
2020 }
2021 
2022 // Similar to AllocatedRepeatedPtrFieldBackInserter, using
2023 // UnsafeArenaAddAllocated instead of AddAllocated.
2024 // This is slightly faster if that matters. It is also useful in legacy code
2025 // that uses temporary ownership to avoid copies. Example:
2026 //   RepeatedPtrField<T> temp_field;
2027 //   temp_field.UnsafeArenaAddAllocated(new T);
2028 //   ... // Do something with temp_field
2029 //   temp_field.UnsafeArenaExtractSubrange(0, temp_field.size(), nullptr);
2030 // Putting temp_field on the arena fails because the ownership transfers to the
2031 // arena at the "AddAllocated" call and is not released anymore causing a
2032 // double delete. This function uses UnsafeArenaAddAllocated to prevent this.
2033 template <typename T>
2034 internal::UnsafeArenaAllocatedRepeatedPtrFieldBackInsertIterator<T>
2035 UnsafeArenaAllocatedRepeatedPtrFieldBackInserter(
2036     RepeatedPtrField<T>* const mutable_field) {
2037   return internal::UnsafeArenaAllocatedRepeatedPtrFieldBackInsertIterator<T>(
2038       mutable_field);
2039 }
2040 
2041 
2042 namespace internal {
2043 // Size optimization for `memswap<N>` - supplied below N is used by every
2044 // `RepeatedPtrField<T>`.
2045 extern template PROTOBUF_EXPORT_TEMPLATE_DECLARE void
2046 memswap<ArenaOffsetHelper<RepeatedPtrFieldBase>::value>(
2047     char* PROTOBUF_RESTRICT, char* PROTOBUF_RESTRICT);
2048 }  // namespace internal
2049 
2050 }  // namespace protobuf
2051 }  // namespace google
2052 
2053 #include "google/protobuf/port_undef.inc"
2054 
2055 #endif  // GOOGLE_PROTOBUF_REPEATED_PTR_FIELD_H__