Back to home page

EIC code displayed by LXR

 
 

    


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

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 RepeatedField.
0020 
0021 #ifndef GOOGLE_PROTOBUF_REPEATED_FIELD_H__
0022 #define GOOGLE_PROTOBUF_REPEATED_FIELD_H__
0023 
0024 #include <algorithm>
0025 #include <cstddef>
0026 #include <iterator>
0027 #include <limits>
0028 #include <memory>
0029 #include <string>
0030 #include <type_traits>
0031 #include <utility>
0032 
0033 #include "absl/base/attributes.h"
0034 #include "absl/base/dynamic_annotations.h"
0035 #include "absl/base/optimization.h"
0036 #include "absl/log/absl_check.h"
0037 #include "absl/log/absl_log.h"
0038 #include "absl/meta/type_traits.h"
0039 #include "absl/strings/cord.h"
0040 #include "google/protobuf/arena.h"
0041 #include "google/protobuf/generated_enum_util.h"
0042 #include "google/protobuf/internal_visibility.h"
0043 #include "google/protobuf/message_lite.h"
0044 #include "google/protobuf/port.h"
0045 #include "google/protobuf/repeated_ptr_field.h"
0046 
0047 
0048 // Must be included last.
0049 #include "google/protobuf/port_def.inc"
0050 
0051 #ifdef SWIG
0052 #error "You cannot SWIG proto headers"
0053 #endif
0054 
0055 namespace google {
0056 namespace protobuf {
0057 
0058 class Message;
0059 
0060 namespace internal {
0061 
0062 template <typename T, int kRepHeaderSize>
0063 constexpr int RepeatedFieldLowerClampLimit() {
0064   // The header is padded to be at least `sizeof(T)` when it would be smaller
0065   // otherwise.
0066   static_assert(sizeof(T) <= kRepHeaderSize, "");
0067   // We want to pad the minimum size to be a power of two bytes, including the
0068   // header.
0069   // The first allocation is kRepHeaderSize bytes worth of elements for a total
0070   // of 2*kRepHeaderSize bytes.
0071   // For an 8-byte header, we allocate 8 bool, 2 ints, or 1 int64.
0072   return kRepHeaderSize / sizeof(T);
0073 }
0074 
0075 // kRepeatedFieldUpperClampLimit is the lowest signed integer value that
0076 // overflows when multiplied by 2 (which is undefined behavior). Sizes above
0077 // this will clamp to the maximum int value instead of following exponential
0078 // growth when growing a repeated field.
0079 constexpr int kRepeatedFieldUpperClampLimit =
0080     (std::numeric_limits<int>::max() / 2) + 1;
0081 
0082 template <typename Element>
0083 class RepeatedIterator;
0084 
0085 // Sentinel base class.
0086 struct RepeatedFieldBase {};
0087 
0088 // We can't skip the destructor for, e.g., arena allocated RepeatedField<Cord>.
0089 template <typename Element,
0090           bool Trivial = Arena::is_destructor_skippable<Element>::value>
0091 struct RepeatedFieldDestructorSkippableBase : RepeatedFieldBase {};
0092 
0093 template <typename Element>
0094 struct RepeatedFieldDestructorSkippableBase<Element, true> : RepeatedFieldBase {
0095   using DestructorSkippable_ = void;
0096 };
0097 
0098 }  // namespace internal
0099 
0100 // RepeatedField is used to represent repeated fields of a primitive type (in
0101 // other words, everything except strings and nested Messages).  Most users will
0102 // not ever use a RepeatedField directly; they will use the get-by-index,
0103 // set-by-index, and add accessors that are generated for all repeated fields.
0104 // Actually, in addition to primitive types, we use RepeatedField for repeated
0105 // Cords, because the Cord class is in fact just a reference-counted pointer.
0106 // We have to specialize several methods in the Cord case to get the memory
0107 // management right; e.g. swapping when appropriate, etc.
0108 template <typename Element>
0109 class RepeatedField final
0110     : private internal::RepeatedFieldDestructorSkippableBase<Element> {
0111   static_assert(
0112       alignof(Arena) >= alignof(Element),
0113       "We only support types that have an alignment smaller than Arena");
0114   static_assert(!std::is_const<Element>::value,
0115                 "We do not support const value types.");
0116   static_assert(!std::is_volatile<Element>::value,
0117                 "We do not support volatile value types.");
0118   static_assert(!std::is_pointer<Element>::value,
0119                 "We do not support pointer value types.");
0120   static_assert(!std::is_reference<Element>::value,
0121                 "We do not support reference value types.");
0122   static constexpr PROTOBUF_ALWAYS_INLINE void StaticValidityCheck() {
0123     static_assert(
0124         absl::disjunction<internal::is_supported_integral_type<Element>,
0125                           internal::is_supported_floating_point_type<Element>,
0126                           std::is_same<absl::Cord, Element>,
0127                           is_proto_enum<Element>>::value,
0128         "We only support non-string scalars in RepeatedField.");
0129   }
0130 
0131  public:
0132   using value_type = Element;
0133   using size_type = int;
0134   using difference_type = ptrdiff_t;
0135   using reference = Element&;
0136   using const_reference = const Element&;
0137   using pointer = Element*;
0138   using const_pointer = const Element*;
0139   using iterator = internal::RepeatedIterator<Element>;
0140   using const_iterator = internal::RepeatedIterator<const Element>;
0141   using reverse_iterator = std::reverse_iterator<iterator>;
0142   using const_reverse_iterator = std::reverse_iterator<const_iterator>;
0143 
0144   constexpr RepeatedField();
0145   RepeatedField(const RepeatedField& rhs) : RepeatedField(nullptr, rhs) {}
0146 
0147   // TODO: make this constructor private
0148   explicit RepeatedField(Arena* arena);
0149 
0150   template <typename Iter,
0151             typename = typename std::enable_if<std::is_constructible<
0152                 Element, decltype(*std::declval<Iter>())>::value>::type>
0153   RepeatedField(Iter begin, Iter end);
0154 
0155   // Arena enabled constructors: for internal use only.
0156   RepeatedField(internal::InternalVisibility, Arena* arena)
0157       : RepeatedField(arena) {}
0158   RepeatedField(internal::InternalVisibility, Arena* arena,
0159                 const RepeatedField& rhs)
0160       : RepeatedField(arena, rhs) {}
0161 
0162   RepeatedField& operator=(const RepeatedField& other)
0163       ABSL_ATTRIBUTE_LIFETIME_BOUND;
0164 
0165   RepeatedField(RepeatedField&& rhs) noexcept
0166       : RepeatedField(nullptr, std::move(rhs)) {}
0167   RepeatedField& operator=(RepeatedField&& other) noexcept
0168       ABSL_ATTRIBUTE_LIFETIME_BOUND;
0169 
0170   ~RepeatedField();
0171 
0172   bool empty() const;
0173   int size() const;
0174 
0175   const_reference Get(int index) const ABSL_ATTRIBUTE_LIFETIME_BOUND;
0176   pointer Mutable(int index) ABSL_ATTRIBUTE_LIFETIME_BOUND;
0177 
0178   const_reference operator[](int index) const ABSL_ATTRIBUTE_LIFETIME_BOUND {
0179     return Get(index);
0180   }
0181   reference operator[](int index) ABSL_ATTRIBUTE_LIFETIME_BOUND {
0182     return *Mutable(index);
0183   }
0184 
0185   const_reference at(int index) const ABSL_ATTRIBUTE_LIFETIME_BOUND;
0186   reference at(int index) ABSL_ATTRIBUTE_LIFETIME_BOUND;
0187 
0188   void Set(int index, const Element& value);
0189   void Add(Element value);
0190 
0191   // Appends a new element and returns a pointer to it.
0192   // The new element is uninitialized if |Element| is a POD type.
0193   pointer Add() ABSL_ATTRIBUTE_LIFETIME_BOUND;
0194   // Appends elements in the range [begin, end) after reserving
0195   // the appropriate number of elements.
0196   template <typename Iter>
0197   void Add(Iter begin, Iter end);
0198 
0199   // Removes the last element in the array.
0200   void RemoveLast();
0201 
0202   // Extracts elements with indices in "[start .. start+num-1]".
0203   // Copies them into "elements[0 .. num-1]" if "elements" is not nullptr.
0204   // Caution: also moves elements with indices [start+num ..].
0205   // Calling this routine inside a loop can cause quadratic behavior.
0206   void ExtractSubrange(int start, int num, Element* elements);
0207 
0208   ABSL_ATTRIBUTE_REINITIALIZES void Clear();
0209   void MergeFrom(const RepeatedField& other);
0210   ABSL_ATTRIBUTE_REINITIALIZES void CopyFrom(const RepeatedField& other);
0211 
0212   // Replaces the contents with RepeatedField(begin, end).
0213   template <typename Iter>
0214   ABSL_ATTRIBUTE_REINITIALIZES void Assign(Iter begin, Iter end);
0215 
0216   // Reserves space to expand the field to at least the given size.  If the
0217   // array is grown, it will always be at least doubled in size.
0218   void Reserve(int new_size);
0219 
0220   // Resizes the RepeatedField to a new, smaller size.  This is O(1).
0221   // Except for RepeatedField<Cord>, for which it is O(size-new_size).
0222   void Truncate(int new_size);
0223 
0224   void AddAlreadyReserved(Element value);
0225   int Capacity() const;
0226 
0227   // Adds `n` elements to this instance asserting there is enough capacity.
0228   // The added elements are uninitialized if `Element` is trivial.
0229   pointer AddAlreadyReserved() ABSL_ATTRIBUTE_LIFETIME_BOUND;
0230   pointer AddNAlreadyReserved(int n) ABSL_ATTRIBUTE_LIFETIME_BOUND;
0231 
0232   // Like STL resize.  Uses value to fill appended elements.
0233   // Like Truncate() if new_size <= size(), otherwise this is
0234   // O(new_size - size()).
0235   void Resize(size_type new_size, const Element& value);
0236 
0237   // Gets the underlying array.  This pointer is possibly invalidated by
0238   // any add or remove operation.
0239   pointer mutable_data() ABSL_ATTRIBUTE_LIFETIME_BOUND;
0240   const_pointer data() const ABSL_ATTRIBUTE_LIFETIME_BOUND;
0241 
0242   // Swaps entire contents with "other". If they are separate arenas, then
0243   // copies data between each other.
0244   void Swap(RepeatedField* other);
0245 
0246   // Swaps two elements.
0247   void SwapElements(int index1, int index2);
0248 
0249   iterator begin() ABSL_ATTRIBUTE_LIFETIME_BOUND;
0250   const_iterator begin() const ABSL_ATTRIBUTE_LIFETIME_BOUND;
0251   const_iterator cbegin() const ABSL_ATTRIBUTE_LIFETIME_BOUND;
0252   iterator end() ABSL_ATTRIBUTE_LIFETIME_BOUND;
0253   const_iterator end() const ABSL_ATTRIBUTE_LIFETIME_BOUND;
0254   const_iterator cend() const ABSL_ATTRIBUTE_LIFETIME_BOUND;
0255 
0256   // Reverse iterator support
0257   reverse_iterator rbegin() ABSL_ATTRIBUTE_LIFETIME_BOUND {
0258     return reverse_iterator(end());
0259   }
0260   const_reverse_iterator rbegin() const ABSL_ATTRIBUTE_LIFETIME_BOUND {
0261     return const_reverse_iterator(end());
0262   }
0263   reverse_iterator rend() ABSL_ATTRIBUTE_LIFETIME_BOUND {
0264     return reverse_iterator(begin());
0265   }
0266   const_reverse_iterator rend() const ABSL_ATTRIBUTE_LIFETIME_BOUND {
0267     return const_reverse_iterator(begin());
0268   }
0269 
0270   // Returns the number of bytes used by the repeated field, excluding
0271   // sizeof(*this)
0272   size_t SpaceUsedExcludingSelfLong() const;
0273 
0274   int SpaceUsedExcludingSelf() const {
0275     return internal::ToIntSize(SpaceUsedExcludingSelfLong());
0276   }
0277 
0278   // Removes the element referenced by position.
0279   //
0280   // Returns an iterator to the element immediately following the removed
0281   // element.
0282   //
0283   // Invalidates all iterators at or after the removed element, including end().
0284   iterator erase(const_iterator position) ABSL_ATTRIBUTE_LIFETIME_BOUND;
0285 
0286   // Removes the elements in the range [first, last).
0287   //
0288   // Returns an iterator to the element immediately following the removed range.
0289   //
0290   // Invalidates all iterators at or after the removed range, including end().
0291   iterator erase(const_iterator first,
0292                  const_iterator last) ABSL_ATTRIBUTE_LIFETIME_BOUND;
0293 
0294   // Gets the Arena on which this RepeatedField stores its elements.
0295   // Note: this can be inaccurate for split default fields so we make this
0296   // function non-const.
0297   inline Arena* GetArena() {
0298     return Capacity() == 0 ? static_cast<Arena*>(arena_or_elements_)
0299                            : rep()->arena;
0300   }
0301 
0302   // For internal use only.
0303   //
0304   // This is public due to it being called by generated code.
0305   inline void InternalSwap(RepeatedField* other);
0306 
0307  private:
0308   using InternalArenaConstructable_ = void;
0309 
0310   template <typename T>
0311   friend class Arena::InternalHelper;
0312 
0313   friend class Arena;
0314 
0315   // Pad the rep to being max(Arena*, Element) with a minimum align
0316   // of 8 as sanitizers are picky on the alignment of containers to
0317   // start at 8 byte offsets even when compiling for 32 bit platforms.
0318   struct Rep {
0319     union {
0320       alignas(8) Arena* arena;
0321       Element unused;
0322     };
0323     Element* elements() { return reinterpret_cast<Element*>(this + 1); }
0324 
0325     // Avoid 'implicitly deleted dtor' warnings on certain compilers.
0326     ~Rep() = delete;
0327   };
0328 
0329   static constexpr int kInitialSize = 0;
0330   static PROTOBUF_CONSTEXPR const size_t kRepHeaderSize = sizeof(Rep);
0331 
0332   RepeatedField(Arena* arena, const RepeatedField& rhs);
0333   RepeatedField(Arena* arena, RepeatedField&& rhs);
0334 
0335 
0336   void set_size(int s) { size_ = s; }
0337   void set_capacity(int c) { capacity_ = c; }
0338 
0339   // Swaps entire contents with "other". Should be called only if the caller can
0340   // guarantee that both repeated fields are on the same arena or are on the
0341   // heap. Swapping between different arenas is disallowed and caught by a
0342   // ABSL_DCHECK (see API docs for details).
0343   void UnsafeArenaSwap(RepeatedField* other);
0344 
0345   // Copy constructs `n` instances in place into the array `dst`.
0346   // This function is identical to `std::uninitialized_copy_n(src, n, dst)`
0347   // except that we explicit declare the memory to not be aliased, which will
0348   // result in `memcpy` code generation instead of `memmove` for trivial types.
0349   static inline void UninitializedCopyN(const Element* PROTOBUF_RESTRICT src,
0350                                         int n, Element* PROTOBUF_RESTRICT dst) {
0351     std::uninitialized_copy_n(src, n, dst);
0352   }
0353 
0354   // Copy constructs `[begin, end)` instances in place into the array `dst`.
0355   // See above `UninitializedCopyN()` function comments for more information.
0356   template <typename Iter>
0357   static inline void UninitializedCopy(Iter begin, Iter end,
0358                                        Element* PROTOBUF_RESTRICT dst) {
0359     std::uninitialized_copy(begin, end, dst);
0360   }
0361 
0362   // Destroys all elements in [begin, end).
0363   // This function does nothing if `Element` is trivial.
0364   static void Destroy(const Element* begin, const Element* end) {
0365     if (!std::is_trivial<Element>::value) {
0366       std::for_each(begin, end, [&](const Element& e) { e.~Element(); });
0367     }
0368   }
0369 
0370   template <typename Iter>
0371   void AddForwardIterator(Iter begin, Iter end);
0372 
0373   template <typename Iter>
0374   void AddInputIterator(Iter begin, Iter end);
0375 
0376   // Reserves space to expand the field to at least the given size.
0377   // If the array is grown, it will always be at least doubled in size.
0378   // If `annotate_size` is true (the default), then this function will annotate
0379   // the old container from `current_size` to `capacity_` (unpoison memory)
0380   // directly before it is being released, and annotate the new container from
0381   // `capacity_` to `current_size` (poison unused memory).
0382   void Grow(int current_size, int new_size);
0383   void GrowNoAnnotate(int current_size, int new_size);
0384 
0385   // Annotates a change in size of this instance. This function should be called
0386   // with (total_size, current_size) after new memory has been allocated and
0387   // filled from previous memory), and called with (current_size, total_size)
0388   // right before (previously annotated) memory is released.
0389   void AnnotateSize(int old_size, int new_size) const {
0390     if (old_size != new_size) {
0391       ABSL_ANNOTATE_CONTIGUOUS_CONTAINER(
0392           unsafe_elements(), unsafe_elements() + Capacity(),
0393           unsafe_elements() + old_size, unsafe_elements() + new_size);
0394       if (new_size < old_size) {
0395         ABSL_ANNOTATE_MEMORY_IS_UNINITIALIZED(
0396             unsafe_elements() + new_size,
0397             (old_size - new_size) * sizeof(Element));
0398       }
0399     }
0400   }
0401 
0402   // Replaces size_ with new_size and returns the previous value of
0403   // size_. This function is intended to be the only place where
0404   // size_ is modified, with the exception of `AddInputIterator()`
0405   // where the size of added items is not known in advance.
0406   inline int ExchangeCurrentSize(int new_size) {
0407     const int prev_size = size();
0408     AnnotateSize(prev_size, new_size);
0409     set_size(new_size);
0410     return prev_size;
0411   }
0412 
0413   // Returns a pointer to elements array.
0414   // pre-condition: the array must have been allocated.
0415   Element* elements() const {
0416     ABSL_DCHECK_GT(Capacity(), 0);
0417     // Because of above pre-condition this cast is safe.
0418     return unsafe_elements();
0419   }
0420 
0421   // Returns a pointer to elements array if it exists; otherwise either null or
0422   // an invalid pointer is returned. This only happens for empty repeated
0423   // fields, where you can't dereference this pointer anyway (it's empty).
0424   Element* unsafe_elements() const {
0425     return static_cast<Element*>(arena_or_elements_);
0426   }
0427 
0428   // Returns a pointer to the Rep struct.
0429   // pre-condition: the Rep must have been allocated, ie elements() is safe.
0430   Rep* rep() const {
0431     return reinterpret_cast<Rep*>(reinterpret_cast<char*>(elements()) -
0432                                   kRepHeaderSize);
0433   }
0434 
0435   // Internal helper to delete all elements and deallocate the storage.
0436   template <bool in_destructor = false>
0437   void InternalDeallocate() {
0438     const size_t bytes = Capacity() * sizeof(Element) + kRepHeaderSize;
0439     if (rep()->arena == nullptr) {
0440       internal::SizedDelete(rep(), bytes);
0441     } else if (!in_destructor) {
0442       // If we are in the destructor, we might be being destroyed as part of
0443       // the arena teardown. We can't try and return blocks to the arena then.
0444       rep()->arena->ReturnArrayMemory(rep(), bytes);
0445     }
0446   }
0447 
0448   // A note on the representation here (see also comment below for
0449   // RepeatedPtrFieldBase's struct Rep):
0450   //
0451   // We maintain the same sizeof(RepeatedField) as before we added arena support
0452   // so that we do not degrade performance by bloating memory usage. Directly
0453   // adding an arena_ element to RepeatedField is quite costly. By using
0454   // indirection in this way, we keep the same size when the RepeatedField is
0455   // empty (common case), and add only an 8-byte header to the elements array
0456   // when non-empty. We make sure to place the size fields directly in the
0457   // RepeatedField class to avoid costly cache misses due to the indirection.
0458   int size_;
0459   int capacity_;
0460   // If capacity_ == 0 this points to an Arena otherwise it points to the
0461   // elements member of a Rep struct. Using this invariant allows the storage of
0462   // the arena pointer without an extra allocation in the constructor.
0463   void* arena_or_elements_;
0464 };
0465 
0466 // implementation ====================================================
0467 
0468 template <typename Element>
0469 constexpr RepeatedField<Element>::RepeatedField()
0470     : size_(0), capacity_(0), arena_or_elements_(nullptr) {
0471   StaticValidityCheck();
0472 }
0473 
0474 template <typename Element>
0475 inline RepeatedField<Element>::RepeatedField(Arena* arena)
0476     : size_(0), capacity_(0), arena_or_elements_(arena) {
0477   StaticValidityCheck();
0478 }
0479 
0480 template <typename Element>
0481 inline RepeatedField<Element>::RepeatedField(Arena* arena,
0482                                              const RepeatedField& rhs)
0483     : size_(0), capacity_(0), arena_or_elements_(arena) {
0484   StaticValidityCheck();
0485   if (auto size = rhs.size()) {
0486     Grow(0, size);
0487     ExchangeCurrentSize(size);
0488     UninitializedCopyN(rhs.elements(), size, unsafe_elements());
0489   }
0490 }
0491 
0492 template <typename Element>
0493 template <typename Iter, typename>
0494 RepeatedField<Element>::RepeatedField(Iter begin, Iter end)
0495     : size_(0), capacity_(0), arena_or_elements_(nullptr) {
0496   StaticValidityCheck();
0497   Add(begin, end);
0498 }
0499 
0500 template <typename Element>
0501 RepeatedField<Element>::~RepeatedField() {
0502   StaticValidityCheck();
0503 #ifndef NDEBUG
0504   // Try to trigger segfault / asan failure in non-opt builds if arena_
0505   // lifetime has ended before the destructor.
0506   auto arena = GetArena();
0507   if (arena) (void)arena->SpaceAllocated();
0508 #endif
0509   if (Capacity() > 0) {
0510     Destroy(unsafe_elements(), unsafe_elements() + size());
0511     InternalDeallocate<true>();
0512   }
0513 }
0514 
0515 template <typename Element>
0516 inline RepeatedField<Element>& RepeatedField<Element>::operator=(
0517     const RepeatedField& other) ABSL_ATTRIBUTE_LIFETIME_BOUND {
0518   if (this != &other) CopyFrom(other);
0519   return *this;
0520 }
0521 
0522 template <typename Element>
0523 inline RepeatedField<Element>::RepeatedField(Arena* arena, RepeatedField&& rhs)
0524     : RepeatedField(arena) {
0525 #ifdef PROTOBUF_FORCE_COPY_IN_MOVE
0526   CopyFrom(rhs);
0527 #else   // PROTOBUF_FORCE_COPY_IN_MOVE
0528   // We don't just call Swap(&rhs) here because it would perform 3 copies if rhs
0529   // is on a different arena.
0530   if (arena != rhs.GetArena()) {
0531     CopyFrom(rhs);
0532   } else {
0533     InternalSwap(&rhs);
0534   }
0535 #endif  // !PROTOBUF_FORCE_COPY_IN_MOVE
0536 }
0537 
0538 template <typename Element>
0539 inline RepeatedField<Element>& RepeatedField<Element>::operator=(
0540     RepeatedField&& other) noexcept ABSL_ATTRIBUTE_LIFETIME_BOUND {
0541   // We don't just call Swap(&other) here because it would perform 3 copies if
0542   // the two fields are on different arenas.
0543   if (this != &other) {
0544     if (GetArena() != other.GetArena()
0545 #ifdef PROTOBUF_FORCE_COPY_IN_MOVE
0546         || GetArena() == nullptr
0547 #endif  // !PROTOBUF_FORCE_COPY_IN_MOVE
0548     ) {
0549       CopyFrom(other);
0550     } else {
0551       InternalSwap(&other);
0552     }
0553   }
0554   return *this;
0555 }
0556 
0557 template <typename Element>
0558 inline bool RepeatedField<Element>::empty() const {
0559   return size() == 0;
0560 }
0561 
0562 template <typename Element>
0563 inline int RepeatedField<Element>::size() const {
0564   return size_;
0565 }
0566 
0567 template <typename Element>
0568 inline int RepeatedField<Element>::Capacity() const {
0569   return capacity_;
0570 }
0571 
0572 template <typename Element>
0573 inline void RepeatedField<Element>::AddAlreadyReserved(Element value) {
0574   ABSL_DCHECK_LT(size(), Capacity());
0575   void* p = elements() + ExchangeCurrentSize(size() + 1);
0576   ::new (p) Element(std::move(value));
0577 }
0578 
0579 template <typename Element>
0580 inline Element* RepeatedField<Element>::AddAlreadyReserved()
0581     ABSL_ATTRIBUTE_LIFETIME_BOUND {
0582   ABSL_DCHECK_LT(size(), Capacity());
0583   // new (p) <TrivialType> compiles into nothing: this is intentional as this
0584   // function is documented to return uninitialized data for trivial types.
0585   void* p = elements() + ExchangeCurrentSize(size() + 1);
0586   return ::new (p) Element;
0587 }
0588 
0589 template <typename Element>
0590 inline Element* RepeatedField<Element>::AddNAlreadyReserved(int n)
0591     ABSL_ATTRIBUTE_LIFETIME_BOUND {
0592   ABSL_DCHECK_GE(Capacity() - size(), n) << Capacity() << ", " << size();
0593   Element* p = unsafe_elements() + ExchangeCurrentSize(size() + n);
0594   for (Element *begin = p, *end = p + n; begin != end; ++begin) {
0595     new (static_cast<void*>(begin)) Element;
0596   }
0597   return p;
0598 }
0599 
0600 template <typename Element>
0601 inline void RepeatedField<Element>::Resize(int new_size, const Element& value) {
0602   ABSL_DCHECK_GE(new_size, 0);
0603   if (new_size > size()) {
0604     if (new_size > Capacity()) Grow(size(), new_size);
0605     Element* first = elements() + ExchangeCurrentSize(new_size);
0606     std::uninitialized_fill(first, elements() + size(), value);
0607   } else if (new_size < size()) {
0608     Destroy(unsafe_elements() + new_size, unsafe_elements() + size());
0609     ExchangeCurrentSize(new_size);
0610   }
0611 }
0612 
0613 template <typename Element>
0614 inline const Element& RepeatedField<Element>::Get(int index) const
0615     ABSL_ATTRIBUTE_LIFETIME_BOUND {
0616   ABSL_DCHECK_GE(index, 0);
0617   ABSL_DCHECK_LT(index, size());
0618   return elements()[index];
0619 }
0620 
0621 template <typename Element>
0622 inline const Element& RepeatedField<Element>::at(int index) const
0623     ABSL_ATTRIBUTE_LIFETIME_BOUND {
0624   ABSL_CHECK_GE(index, 0);
0625   ABSL_CHECK_LT(index, size());
0626   return elements()[index];
0627 }
0628 
0629 template <typename Element>
0630 inline Element& RepeatedField<Element>::at(int index)
0631     ABSL_ATTRIBUTE_LIFETIME_BOUND {
0632   ABSL_CHECK_GE(index, 0);
0633   ABSL_CHECK_LT(index, size());
0634   return elements()[index];
0635 }
0636 
0637 template <typename Element>
0638 inline Element* RepeatedField<Element>::Mutable(int index)
0639     ABSL_ATTRIBUTE_LIFETIME_BOUND {
0640   ABSL_DCHECK_GE(index, 0);
0641   ABSL_DCHECK_LT(index, size());
0642   return &elements()[index];
0643 }
0644 
0645 template <typename Element>
0646 inline void RepeatedField<Element>::Set(int index, const Element& value) {
0647   ABSL_DCHECK_GE(index, 0);
0648   ABSL_DCHECK_LT(index, size());
0649   elements()[index] = value;
0650 }
0651 
0652 template <typename Element>
0653 inline void RepeatedField<Element>::Add(Element value) {
0654   int capacity = Capacity();
0655   Element* elem = unsafe_elements();
0656   if (ABSL_PREDICT_FALSE(size() == capacity)) {
0657     Grow(size(), size() + 1);
0658     capacity = Capacity();
0659     elem = unsafe_elements();
0660   }
0661   int new_size = size() + 1;
0662   void* p = elem + ExchangeCurrentSize(new_size);
0663   ::new (p) Element(std::move(value));
0664 
0665   // The below helps the compiler optimize dense loops.
0666   ABSL_ASSUME(new_size == size_);
0667   ABSL_ASSUME(elem == arena_or_elements_);
0668   ABSL_ASSUME(capacity == capacity_);
0669 }
0670 
0671 template <typename Element>
0672 inline Element* RepeatedField<Element>::Add() ABSL_ATTRIBUTE_LIFETIME_BOUND {
0673   if (ABSL_PREDICT_FALSE(size() == Capacity())) {
0674     Grow(size(), size() + 1);
0675   }
0676   void* p = unsafe_elements() + ExchangeCurrentSize(size() + 1);
0677   return ::new (p) Element;
0678 }
0679 
0680 template <typename Element>
0681 template <typename Iter>
0682 inline void RepeatedField<Element>::AddForwardIterator(Iter begin, Iter end) {
0683   int capacity = Capacity();
0684   Element* elem = unsafe_elements();
0685   int new_size = size() + static_cast<int>(std::distance(begin, end));
0686   if (ABSL_PREDICT_FALSE(new_size > capacity)) {
0687     Grow(size(), new_size);
0688     elem = unsafe_elements();
0689     capacity = Capacity();
0690   }
0691   UninitializedCopy(begin, end, elem + ExchangeCurrentSize(new_size));
0692 
0693   // The below helps the compiler optimize dense loops.
0694   ABSL_ASSUME(new_size == size_);
0695   ABSL_ASSUME(elem == arena_or_elements_);
0696   ABSL_ASSUME(capacity == capacity_);
0697 }
0698 
0699 template <typename Element>
0700 template <typename Iter>
0701 inline void RepeatedField<Element>::AddInputIterator(Iter begin, Iter end) {
0702   Element* first = unsafe_elements() + size();
0703   Element* last = unsafe_elements() + Capacity();
0704   AnnotateSize(size(), Capacity());
0705 
0706   while (begin != end) {
0707     if (ABSL_PREDICT_FALSE(first == last)) {
0708       int current_size = first - unsafe_elements();
0709       GrowNoAnnotate(current_size, current_size + 1);
0710       first = unsafe_elements() + current_size;
0711       last = unsafe_elements() + Capacity();
0712     }
0713     ::new (static_cast<void*>(first)) Element(*begin);
0714     ++begin;
0715     ++first;
0716   }
0717 
0718   set_size(first - unsafe_elements());
0719   AnnotateSize(Capacity(), size());
0720 }
0721 
0722 template <typename Element>
0723 template <typename Iter>
0724 inline void RepeatedField<Element>::Add(Iter begin, Iter end) {
0725   if (std::is_base_of<
0726           std::forward_iterator_tag,
0727           typename std::iterator_traits<Iter>::iterator_category>::value) {
0728     AddForwardIterator(begin, end);
0729   } else {
0730     AddInputIterator(begin, end);
0731   }
0732 }
0733 
0734 template <typename Element>
0735 inline void RepeatedField<Element>::RemoveLast() {
0736   ABSL_DCHECK_GT(size(), 0);
0737   elements()[size() - 1].~Element();
0738   ExchangeCurrentSize(size() - 1);
0739 }
0740 
0741 template <typename Element>
0742 void RepeatedField<Element>::ExtractSubrange(int start, int num,
0743                                              Element* elements) {
0744   ABSL_DCHECK_GE(start, 0);
0745   ABSL_DCHECK_GE(num, 0);
0746   ABSL_DCHECK_LE(start + num, size());
0747 
0748   // Save the values of the removed elements if requested.
0749   if (elements != nullptr) {
0750     for (int i = 0; i < num; ++i) elements[i] = Get(i + start);
0751   }
0752 
0753   // Slide remaining elements down to fill the gap.
0754   if (num > 0) {
0755     for (int i = start + num; i < size(); ++i) Set(i - num, Get(i));
0756     Truncate(size() - num);
0757   }
0758 }
0759 
0760 template <typename Element>
0761 inline void RepeatedField<Element>::Clear() {
0762   Destroy(unsafe_elements(), unsafe_elements() + size());
0763   ExchangeCurrentSize(0);
0764 }
0765 
0766 template <typename Element>
0767 inline void RepeatedField<Element>::MergeFrom(const RepeatedField& other) {
0768   ABSL_DCHECK_NE(&other, this);
0769   if (auto size = other.size()) {
0770     Reserve(this->size() + size);
0771     Element* dst = elements() + ExchangeCurrentSize(this->size() + size);
0772     UninitializedCopyN(other.elements(), size, dst);
0773   }
0774 }
0775 
0776 template <typename Element>
0777 inline void RepeatedField<Element>::CopyFrom(const RepeatedField& other) {
0778   if (&other == this) return;
0779   Clear();
0780   MergeFrom(other);
0781 }
0782 
0783 template <typename Element>
0784 template <typename Iter>
0785 inline void RepeatedField<Element>::Assign(Iter begin, Iter end) {
0786   Clear();
0787   Add(begin, end);
0788 }
0789 
0790 template <typename Element>
0791 inline typename RepeatedField<Element>::iterator RepeatedField<Element>::erase(
0792     const_iterator position) ABSL_ATTRIBUTE_LIFETIME_BOUND {
0793   return erase(position, position + 1);
0794 }
0795 
0796 template <typename Element>
0797 inline typename RepeatedField<Element>::iterator RepeatedField<Element>::erase(
0798     const_iterator first, const_iterator last) ABSL_ATTRIBUTE_LIFETIME_BOUND {
0799   size_type first_offset = first - cbegin();
0800   if (first != last) {
0801     Truncate(std::copy(last, cend(), begin() + first_offset) - cbegin());
0802   }
0803   return begin() + first_offset;
0804 }
0805 
0806 template <typename Element>
0807 inline Element* RepeatedField<Element>::mutable_data()
0808     ABSL_ATTRIBUTE_LIFETIME_BOUND {
0809   return unsafe_elements();
0810 }
0811 
0812 template <typename Element>
0813 inline const Element* RepeatedField<Element>::data() const
0814     ABSL_ATTRIBUTE_LIFETIME_BOUND {
0815   return unsafe_elements();
0816 }
0817 
0818 template <typename Element>
0819 inline void RepeatedField<Element>::InternalSwap(
0820     RepeatedField* PROTOBUF_RESTRICT other) {
0821   ABSL_DCHECK(this != other);
0822 
0823   // Swap all fields at once.
0824   static_assert(std::is_standard_layout<RepeatedField<Element>>::value,
0825                 "offsetof() requires standard layout before c++17");
0826   static constexpr size_t kOffset = offsetof(RepeatedField, size_);
0827   internal::memswap<offsetof(RepeatedField, arena_or_elements_) +
0828                     sizeof(this->arena_or_elements_) - kOffset>(
0829       reinterpret_cast<char*>(this) + kOffset,
0830       reinterpret_cast<char*>(other) + kOffset);
0831 }
0832 
0833 template <typename Element>
0834 void RepeatedField<Element>::Swap(RepeatedField* other) {
0835   if (this == other) return;
0836 #ifdef PROTOBUF_FORCE_COPY_IN_SWAP
0837   if (GetArena() != nullptr && GetArena() == other->GetArena()) {
0838 #else   // PROTOBUF_FORCE_COPY_IN_SWAP
0839   if (GetArena() == other->GetArena()) {
0840 #endif  // !PROTOBUF_FORCE_COPY_IN_SWAP
0841     InternalSwap(other);
0842   } else {
0843     RepeatedField<Element> temp(other->GetArena());
0844     temp.MergeFrom(*this);
0845     CopyFrom(*other);
0846     other->UnsafeArenaSwap(&temp);
0847   }
0848 }
0849 
0850 template <typename Element>
0851 void RepeatedField<Element>::UnsafeArenaSwap(RepeatedField* other) {
0852   if (this == other) return;
0853   ABSL_DCHECK_EQ(GetArena(), other->GetArena());
0854   InternalSwap(other);
0855 }
0856 
0857 template <typename Element>
0858 void RepeatedField<Element>::SwapElements(int index1, int index2) {
0859   using std::swap;  // enable ADL with fallback
0860   swap(elements()[index1], elements()[index2]);
0861 }
0862 
0863 template <typename Element>
0864 inline typename RepeatedField<Element>::iterator RepeatedField<Element>::begin()
0865     ABSL_ATTRIBUTE_LIFETIME_BOUND {
0866   return iterator(unsafe_elements());
0867 }
0868 template <typename Element>
0869 inline typename RepeatedField<Element>::const_iterator
0870 RepeatedField<Element>::begin() const ABSL_ATTRIBUTE_LIFETIME_BOUND {
0871   return const_iterator(unsafe_elements());
0872 }
0873 template <typename Element>
0874 inline typename RepeatedField<Element>::const_iterator
0875 RepeatedField<Element>::cbegin() const ABSL_ATTRIBUTE_LIFETIME_BOUND {
0876   return const_iterator(unsafe_elements());
0877 }
0878 template <typename Element>
0879 inline typename RepeatedField<Element>::iterator RepeatedField<Element>::end()
0880     ABSL_ATTRIBUTE_LIFETIME_BOUND {
0881   return iterator(unsafe_elements() + size());
0882 }
0883 template <typename Element>
0884 inline typename RepeatedField<Element>::const_iterator
0885 RepeatedField<Element>::end() const ABSL_ATTRIBUTE_LIFETIME_BOUND {
0886   return const_iterator(unsafe_elements() + size());
0887 }
0888 template <typename Element>
0889 inline typename RepeatedField<Element>::const_iterator
0890 RepeatedField<Element>::cend() const ABSL_ATTRIBUTE_LIFETIME_BOUND {
0891   return const_iterator(unsafe_elements() + size());
0892 }
0893 
0894 template <typename Element>
0895 inline size_t RepeatedField<Element>::SpaceUsedExcludingSelfLong() const {
0896   return Capacity() > 0 ? (Capacity() * sizeof(Element) + kRepHeaderSize) : 0;
0897 }
0898 
0899 namespace internal {
0900 // Returns the new size for a reserved field based on its 'total_size' and the
0901 // requested 'new_size'. The result is clamped to the closed interval:
0902 //   [internal::kMinRepeatedFieldAllocationSize,
0903 //    std::numeric_limits<int>::max()]
0904 // Requires:
0905 //     new_size > total_size &&
0906 //     (total_size == 0 ||
0907 //      total_size >= kRepeatedFieldLowerClampLimit)
0908 template <typename T, int kRepHeaderSize>
0909 inline int CalculateReserveSize(int total_size, int new_size) {
0910   constexpr int lower_limit = RepeatedFieldLowerClampLimit<T, kRepHeaderSize>();
0911   if (new_size < lower_limit) {
0912     // Clamp to smallest allowed size.
0913     return lower_limit;
0914   }
0915   constexpr int kMaxSizeBeforeClamp =
0916       (std::numeric_limits<int>::max() - kRepHeaderSize) / 2;
0917   if (PROTOBUF_PREDICT_FALSE(total_size > kMaxSizeBeforeClamp)) {
0918     return std::numeric_limits<int>::max();
0919   }
0920   // We want to double the number of bytes, not the number of elements, to try
0921   // to stay within power-of-two allocations.
0922   // The allocation has kRepHeaderSize + sizeof(T) * capacity.
0923   int doubled_size = 2 * total_size + kRepHeaderSize / sizeof(T);
0924   return std::max(doubled_size, new_size);
0925 }
0926 }  // namespace internal
0927 
0928 template <typename Element>
0929 void RepeatedField<Element>::Reserve(int new_size) {
0930   if (ABSL_PREDICT_FALSE(new_size > Capacity())) {
0931     Grow(size(), new_size);
0932   }
0933 }
0934 
0935 // Avoid inlining of Reserve(): new, copy, and delete[] lead to a significant
0936 // amount of code bloat.
0937 template <typename Element>
0938 PROTOBUF_NOINLINE void RepeatedField<Element>::GrowNoAnnotate(int current_size,
0939                                                               int new_size) {
0940   ABSL_DCHECK_GT(new_size, Capacity());
0941   Rep* new_rep;
0942   Arena* arena = GetArena();
0943 
0944   new_size = internal::CalculateReserveSize<Element, kRepHeaderSize>(Capacity(),
0945                                                                      new_size);
0946 
0947   ABSL_DCHECK_LE(
0948       static_cast<size_t>(new_size),
0949       (std::numeric_limits<size_t>::max() - kRepHeaderSize) / sizeof(Element))
0950       << "Requested size is too large to fit into size_t.";
0951   size_t bytes =
0952       kRepHeaderSize + sizeof(Element) * static_cast<size_t>(new_size);
0953   if (arena == nullptr) {
0954     ABSL_DCHECK_LE((bytes - kRepHeaderSize) / sizeof(Element),
0955                    static_cast<size_t>(std::numeric_limits<int>::max()))
0956         << "Requested size is too large to fit element count into int.";
0957     internal::SizedPtr res = internal::AllocateAtLeast(bytes);
0958     size_t num_available =
0959         std::min((res.n - kRepHeaderSize) / sizeof(Element),
0960                  static_cast<size_t>(std::numeric_limits<int>::max()));
0961     new_size = static_cast<int>(num_available);
0962     new_rep = static_cast<Rep*>(res.p);
0963   } else {
0964     new_rep = reinterpret_cast<Rep*>(Arena::CreateArray<char>(arena, bytes));
0965   }
0966   new_rep->arena = arena;
0967 
0968   if (Capacity() > 0) {
0969     if (current_size > 0) {
0970       Element* pnew = new_rep->elements();
0971       Element* pold = elements();
0972       // TODO: add absl::is_trivially_relocatable<Element>
0973       if (std::is_trivial<Element>::value) {
0974         memcpy(static_cast<void*>(pnew), pold, current_size * sizeof(Element));
0975       } else {
0976         for (Element* end = pnew + current_size; pnew != end; ++pnew, ++pold) {
0977           ::new (static_cast<void*>(pnew)) Element(std::move(*pold));
0978           pold->~Element();
0979         }
0980       }
0981     }
0982     InternalDeallocate();
0983   }
0984 
0985   set_capacity(new_size);
0986   arena_or_elements_ = new_rep->elements();
0987 }
0988 
0989 // Ideally we would be able to use:
0990 //   template <bool annotate_size = true>
0991 //   void Grow();
0992 // However, as explained in b/266411038#comment9, this causes issues
0993 // in shared libraries for Youtube (and possibly elsewhere).
0994 template <typename Element>
0995 PROTOBUF_NOINLINE void RepeatedField<Element>::Grow(int current_size,
0996                                                     int new_size) {
0997   AnnotateSize(current_size, Capacity());
0998   GrowNoAnnotate(current_size, new_size);
0999   AnnotateSize(Capacity(), current_size);
1000 }
1001 
1002 template <typename Element>
1003 inline void RepeatedField<Element>::Truncate(int new_size) {
1004   ABSL_DCHECK_LE(new_size, size());
1005   if (new_size < size()) {
1006     Destroy(unsafe_elements() + new_size, unsafe_elements() + size());
1007     ExchangeCurrentSize(new_size);
1008   }
1009 }
1010 
1011 template <>
1012 PROTOBUF_EXPORT size_t
1013 RepeatedField<absl::Cord>::SpaceUsedExcludingSelfLong() const;
1014 
1015 
1016 // -------------------------------------------------------------------
1017 
1018 // Iterators and helper functions that follow the spirit of the STL
1019 // std::back_insert_iterator and std::back_inserter but are tailor-made
1020 // for RepeatedField and RepeatedPtrField. Typical usage would be:
1021 //
1022 //   std::copy(some_sequence.begin(), some_sequence.end(),
1023 //             RepeatedFieldBackInserter(proto.mutable_sequence()));
1024 //
1025 // Ported by johannes from util/gtl/proto-array-iterators.h
1026 
1027 namespace internal {
1028 
1029 // STL-like iterator implementation for RepeatedField.  You should not
1030 // refer to this class directly; use RepeatedField<T>::iterator instead.
1031 //
1032 // Note: All of the iterator operators *must* be inlined to avoid performance
1033 // regressions.  This is caused by the extern template declarations below (which
1034 // are required because of the RepeatedField extern template declarations).  If
1035 // any of these functions aren't explicitly inlined (e.g. defined in the class),
1036 // the compiler isn't allowed to inline them.
1037 template <typename Element>
1038 class RepeatedIterator {
1039  private:
1040   using traits =
1041       std::iterator_traits<typename std::remove_const<Element>::type*>;
1042 
1043  public:
1044   // Note: value_type is never cv-qualified.
1045   using value_type = typename traits::value_type;
1046   using difference_type = typename traits::difference_type;
1047   using pointer = Element*;
1048   using reference = Element&;
1049   using iterator_category = typename traits::iterator_category;
1050   using iterator_concept = typename IteratorConceptSupport<traits>::tag;
1051 
1052   constexpr RepeatedIterator() noexcept : it_(nullptr) {}
1053 
1054   // Allows "upcasting" from RepeatedIterator<T**> to
1055   // RepeatedIterator<const T*const*>.
1056   template <typename OtherElement,
1057             typename std::enable_if<std::is_convertible<
1058                 OtherElement*, pointer>::value>::type* = nullptr>
1059   constexpr RepeatedIterator(
1060       const RepeatedIterator<OtherElement>& other) noexcept
1061       : it_(other.it_) {}
1062 
1063   // dereferenceable
1064   constexpr reference operator*() const noexcept { return *it_; }
1065   constexpr pointer operator->() const noexcept { return it_; }
1066 
1067  private:
1068   // Helper alias to hide the internal type.
1069   using iterator = RepeatedIterator<Element>;
1070 
1071  public:
1072   // {inc,dec}rementable
1073   iterator& operator++() noexcept {
1074     ++it_;
1075     return *this;
1076   }
1077   iterator operator++(int) noexcept { return iterator(it_++); }
1078   iterator& operator--() noexcept {
1079     --it_;
1080     return *this;
1081   }
1082   iterator operator--(int) noexcept { return iterator(it_--); }
1083 
1084   // equality_comparable
1085   friend constexpr bool operator==(const iterator& x,
1086                                    const iterator& y) noexcept {
1087     return x.it_ == y.it_;
1088   }
1089   friend constexpr bool operator!=(const iterator& x,
1090                                    const iterator& y) noexcept {
1091     return x.it_ != y.it_;
1092   }
1093 
1094   // less_than_comparable
1095   friend constexpr bool operator<(const iterator& x,
1096                                   const iterator& y) noexcept {
1097     return x.it_ < y.it_;
1098   }
1099   friend constexpr bool operator<=(const iterator& x,
1100                                    const iterator& y) noexcept {
1101     return x.it_ <= y.it_;
1102   }
1103   friend constexpr bool operator>(const iterator& x,
1104                                   const iterator& y) noexcept {
1105     return x.it_ > y.it_;
1106   }
1107   friend constexpr bool operator>=(const iterator& x,
1108                                    const iterator& y) noexcept {
1109     return x.it_ >= y.it_;
1110   }
1111 
1112   // addable, subtractable
1113   iterator& operator+=(difference_type d) noexcept {
1114     it_ += d;
1115     return *this;
1116   }
1117   constexpr iterator operator+(difference_type d) const noexcept {
1118     return iterator(it_ + d);
1119   }
1120   friend constexpr iterator operator+(const difference_type d,
1121                                       iterator it) noexcept {
1122     return it + d;
1123   }
1124 
1125   iterator& operator-=(difference_type d) noexcept {
1126     it_ -= d;
1127     return *this;
1128   }
1129   iterator constexpr operator-(difference_type d) const noexcept {
1130     return iterator(it_ - d);
1131   }
1132 
1133   // indexable
1134   constexpr reference operator[](difference_type d) const noexcept {
1135     return it_[d];
1136   }
1137 
1138   // random access iterator
1139   friend constexpr difference_type operator-(iterator it1,
1140                                              iterator it2) noexcept {
1141     return it1.it_ - it2.it_;
1142   }
1143 
1144  private:
1145   template <typename OtherElement>
1146   friend class RepeatedIterator;
1147 
1148   // Allow construction from RepeatedField.
1149   friend class RepeatedField<value_type>;
1150   explicit RepeatedIterator(pointer it) noexcept : it_(it) {}
1151 
1152   // The internal iterator.
1153   pointer it_;
1154 };
1155 
1156 // A back inserter for RepeatedField objects.
1157 template <typename T>
1158 class RepeatedFieldBackInsertIterator {
1159  public:
1160   using iterator_category = std::output_iterator_tag;
1161   using value_type = T;
1162   using pointer = void;
1163   using reference = void;
1164   using difference_type = std::ptrdiff_t;
1165 
1166   explicit RepeatedFieldBackInsertIterator(
1167       RepeatedField<T>* const mutable_field)
1168       : field_(mutable_field) {}
1169   RepeatedFieldBackInsertIterator<T>& operator=(const T& value) {
1170     field_->Add(value);
1171     return *this;
1172   }
1173   RepeatedFieldBackInsertIterator<T>& operator*() { return *this; }
1174   RepeatedFieldBackInsertIterator<T>& operator++() { return *this; }
1175   RepeatedFieldBackInsertIterator<T>& operator++(int /* unused */) {
1176     return *this;
1177   }
1178 
1179  private:
1180   RepeatedField<T>* field_;
1181 };
1182 
1183 }  // namespace internal
1184 
1185 // Provides a back insert iterator for RepeatedField instances,
1186 // similar to std::back_inserter().
1187 template <typename T>
1188 internal::RepeatedFieldBackInsertIterator<T> RepeatedFieldBackInserter(
1189     RepeatedField<T>* const mutable_field) {
1190   return internal::RepeatedFieldBackInsertIterator<T>(mutable_field);
1191 }
1192 
1193 
1194 }  // namespace protobuf
1195 }  // namespace google
1196 
1197 #include "google/protobuf/port_undef.inc"
1198 
1199 #endif  // GOOGLE_PROTOBUF_REPEATED_FIELD_H__