LCOV - code coverage report
Current view: top level - third_party/protobuf/src/google/protobuf - repeated_field.h (source / functions) Hit Total Coverage
Test: tmp.zDYK9MVh93 Lines: 193 349 55.3 %
Date: 2015-10-10 Functions: 153 337 45.4 %

          Line data    Source code
       1             : // Protocol Buffers - Google's data interchange format
       2             : // Copyright 2008 Google Inc.  All rights reserved.
       3             : // https://developers.google.com/protocol-buffers/
       4             : //
       5             : // Redistribution and use in source and binary forms, with or without
       6             : // modification, are permitted provided that the following conditions are
       7             : // met:
       8             : //
       9             : //     * Redistributions of source code must retain the above copyright
      10             : // notice, this list of conditions and the following disclaimer.
      11             : //     * Redistributions in binary form must reproduce the above
      12             : // copyright notice, this list of conditions and the following disclaimer
      13             : // in the documentation and/or other materials provided with the
      14             : // distribution.
      15             : //     * Neither the name of Google Inc. nor the names of its
      16             : // contributors may be used to endorse or promote products derived from
      17             : // this software without specific prior written permission.
      18             : //
      19             : // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
      20             : // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
      21             : // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
      22             : // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
      23             : // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
      24             : // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
      25             : // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
      26             : // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
      27             : // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
      28             : // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
      29             : // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
      30             : 
      31             : // Author: kenton@google.com (Kenton Varda)
      32             : //  Based on original Protocol Buffers design by
      33             : //  Sanjay Ghemawat, Jeff Dean, and others.
      34             : //
      35             : // RepeatedField and RepeatedPtrField are used by generated protocol message
      36             : // classes to manipulate repeated fields.  These classes are very similar to
      37             : // STL's vector, but include a number of optimizations found to be useful
      38             : // specifically in the case of Protocol Buffers.  RepeatedPtrField is
      39             : // particularly different from STL vector as it manages ownership of the
      40             : // pointers that it contains.
      41             : //
      42             : // Typically, clients should not need to access RepeatedField objects directly,
      43             : // but should instead use the accessor functions generated automatically by the
      44             : // protocol compiler.
      45             : 
      46             : #ifndef GOOGLE_PROTOBUF_REPEATED_FIELD_H__
      47             : #define GOOGLE_PROTOBUF_REPEATED_FIELD_H__
      48             : 
      49             : #ifdef _MSC_VER
      50             : // This is required for min/max on VS2013 only.
      51             : #include <algorithm>
      52             : #endif
      53             : 
      54             : #include <string>
      55             : #include <iterator>
      56             : #include <google/protobuf/stubs/casts.h>
      57             : #include <google/protobuf/stubs/logging.h>
      58             : #include <google/protobuf/stubs/common.h>
      59             : #include <google/protobuf/stubs/type_traits.h>
      60             : #include <google/protobuf/arena.h>
      61             : #include <google/protobuf/generated_message_util.h>
      62             : #include <google/protobuf/message_lite.h>
      63             : 
      64             : namespace google {
      65             : 
      66             : namespace upb {
      67             : namespace google_opensource {
      68             : class GMR_Handlers;
      69             : }  // namespace google_opensource
      70             : }  // namespace upb
      71             : 
      72             : namespace protobuf {
      73             : 
      74             : class Message;
      75             : 
      76             : namespace internal {
      77             : 
      78             : static const int kMinRepeatedFieldAllocationSize = 4;
      79             : 
      80             : // A utility function for logging that doesn't need any template types.
      81             : void LogIndexOutOfBounds(int index, int size);
      82             : 
      83             : template <typename Iter>
      84             : inline int CalculateReserve(Iter begin, Iter end, std::forward_iterator_tag) {
      85             :   return std::distance(begin, end);
      86             : }
      87             : 
      88             : template <typename Iter>
      89             : inline int CalculateReserve(Iter /*begin*/, Iter /*end*/,
      90             :                             std::input_iterator_tag /*unused*/) {
      91             :   return -1;
      92             : }
      93             : 
      94             : template <typename Iter>
      95             : inline int CalculateReserve(Iter begin, Iter end) {
      96             :   typedef typename std::iterator_traits<Iter>::iterator_category Category;
      97             :   return CalculateReserve(begin, end, Category());
      98             : }
      99             : }  // namespace internal
     100             : 
     101             : 
     102             : // RepeatedField is used to represent repeated fields of a primitive type (in
     103             : // other words, everything except strings and nested Messages).  Most users will
     104             : // not ever use a RepeatedField directly; they will use the get-by-index,
     105             : // set-by-index, and add accessors that are generated for all repeated fields.
     106             : template <typename Element>
     107             : class RepeatedField {
     108             :  public:
     109             :   RepeatedField();
     110             :   explicit RepeatedField(Arena* arena);
     111             :   RepeatedField(const RepeatedField& other);
     112             :   template <typename Iter>
     113             :   RepeatedField(Iter begin, const Iter& end);
     114             :   ~RepeatedField();
     115             : 
     116             :   RepeatedField& operator=(const RepeatedField& other);
     117             : 
     118             :   bool empty() const;
     119             :   int size() const;
     120             : 
     121             :   const Element& Get(int index) const;
     122             :   Element* Mutable(int index);
     123             :   void Set(int index, const Element& value);
     124             :   void Add(const Element& value);
     125             :   Element* Add();
     126             :   // Remove the last element in the array.
     127             :   void RemoveLast();
     128             : 
     129             :   // Extract elements with indices in "[start .. start+num-1]".
     130             :   // Copy them into "elements[0 .. num-1]" if "elements" is not NULL.
     131             :   // Caution: implementation also moves elements with indices [start+num ..].
     132             :   // Calling this routine inside a loop can cause quadratic behavior.
     133             :   void ExtractSubrange(int start, int num, Element* elements);
     134             : 
     135             :   void Clear();
     136             :   void MergeFrom(const RepeatedField& other);
     137             :   void CopyFrom(const RepeatedField& other);
     138             : 
     139             :   // Reserve space to expand the field to at least the given size.  If the
     140             :   // array is grown, it will always be at least doubled in size.
     141             :   void Reserve(int new_size);
     142             : 
     143             :   // Resize the RepeatedField to a new, smaller size.  This is O(1).
     144             :   void Truncate(int new_size);
     145             : 
     146             :   void AddAlreadyReserved(const Element& value);
     147             :   Element* AddAlreadyReserved();
     148             :   int Capacity() const;
     149             : 
     150             :   // Like STL resize.  Uses value to fill appended elements.
     151             :   // Like Truncate() if new_size <= size(), otherwise this is
     152             :   // O(new_size - size()).
     153             :   void Resize(int new_size, const Element& value);
     154             : 
     155             :   // Gets the underlying array.  This pointer is possibly invalidated by
     156             :   // any add or remove operation.
     157             :   Element* mutable_data();
     158             :   const Element* data() const;
     159             : 
     160             :   // Swap entire contents with "other". If they are separate arenas then, copies
     161             :   // data between each other.
     162             :   void Swap(RepeatedField* other);
     163             : 
     164             :   // Swap entire contents with "other". Should be called only if the caller can
     165             :   // guarantee that both repeated fields are on the same arena or are on the
     166             :   // heap. Swapping between different arenas is disallowed and caught by a
     167             :   // GOOGLE_DCHECK (see API docs for details).
     168             :   void UnsafeArenaSwap(RepeatedField* other);
     169             : 
     170             :   // Swap two elements.
     171             :   void SwapElements(int index1, int index2);
     172             : 
     173             :   // STL-like iterator support
     174             :   typedef Element* iterator;
     175             :   typedef const Element* const_iterator;
     176             :   typedef Element value_type;
     177             :   typedef value_type& reference;
     178             :   typedef const value_type& const_reference;
     179             :   typedef value_type* pointer;
     180             :   typedef const value_type* const_pointer;
     181             :   typedef int size_type;
     182             :   typedef ptrdiff_t difference_type;
     183             : 
     184             :   iterator begin();
     185             :   const_iterator begin() const;
     186             :   const_iterator cbegin() const;
     187             :   iterator end();
     188             :   const_iterator end() const;
     189             :   const_iterator cend() const;
     190             : 
     191             :   // Reverse iterator support
     192             :   typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
     193             :   typedef std::reverse_iterator<iterator> reverse_iterator;
     194             :   reverse_iterator rbegin() {
     195             :     return reverse_iterator(end());
     196             :   }
     197             :   const_reverse_iterator rbegin() const {
     198             :     return const_reverse_iterator(end());
     199             :   }
     200             :   reverse_iterator rend() {
     201             :     return reverse_iterator(begin());
     202             :   }
     203             :   const_reverse_iterator rend() const {
     204             :     return const_reverse_iterator(begin());
     205             :   }
     206             : 
     207             :   // Returns the number of bytes used by the repeated field, excluding
     208             :   // sizeof(*this)
     209             :   int SpaceUsedExcludingSelf() const;
     210             : 
     211             :   // Remove the element referenced by position.
     212             :   iterator erase(const_iterator position);
     213             : 
     214             :   // Remove the elements in the range [first, last).
     215             :   iterator erase(const_iterator first, const_iterator last);
     216             : 
     217             :   // Get the Arena on which this RepeatedField stores its elements.
     218             :   ::google::protobuf::Arena* GetArena() const {
     219             :     return GetArenaNoVirtual();
     220             :   }
     221             : 
     222             :  private:
     223             :   static const int kInitialSize = 0;
     224             :   // A note on the representation here (see also comment below for
     225             :   // RepeatedPtrFieldBase's struct Rep):
     226             :   //
     227             :   // We maintain the same sizeof(RepeatedField) as before we added arena support
     228             :   // so that we do not degrade performance by bloating memory usage. Directly
     229             :   // adding an arena_ element to RepeatedField is quite costly. By using
     230             :   // indirection in this way, we keep the same size when the RepeatedField is
     231             :   // empty (common case), and add only an 8-byte header to the elements array
     232             :   // when non-empty. We make sure to place the size fields directly in the
     233             :   // RepeatedField class to avoid costly cache misses due to the indirection.
     234             :   int current_size_;
     235             :   int total_size_;
     236             :   struct Rep {
     237             :     Arena* arena;
     238             :     Element  elements[1];
     239             :   };
     240             :   // We can not use sizeof(Rep) - sizeof(Element) due to the trailing padding on
     241             :   // the struct. We can not use sizeof(Arena*) as well because there might be
     242             :   // a "gap" after the field arena and before the field elements (e.g., when
     243             :   // Element is double and pointer is 32bit).
     244             :   static const size_t kRepHeaderSize;
     245             :   // Contains arena ptr and the elements array. We also keep the invariant that
     246             :   // if rep_ is NULL, then arena is NULL.
     247             :   Rep* rep_;
     248             : 
     249             :   friend class Arena;
     250             :   typedef void InternalArenaConstructable_;
     251             : 
     252             :   // Move the contents of |from| into |to|, possibly clobbering |from| in the
     253             :   // process.  For primitive types this is just a memcpy(), but it could be
     254             :   // specialized for non-primitive types to, say, swap each element instead.
     255             :   void MoveArray(Element* to, Element* from, int size);
     256             : 
     257             :   // Copy the elements of |from| into |to|.
     258             :   void CopyArray(Element* to, const Element* from, int size);
     259             : 
     260             :   inline void InternalSwap(RepeatedField* other);
     261             : 
     262             :   // Internal helper expected by Arena methods.
     263         276 :   inline Arena* GetArenaNoVirtual() const {
     264      118272 :     return (rep_ == NULL) ? NULL : rep_->arena;
     265             :   }
     266             : };
     267             : 
     268             : template<typename Element>
     269             : const size_t RepeatedField<Element>::kRepHeaderSize =
     270             :     reinterpret_cast<size_t>(&reinterpret_cast<Rep*>(16)->elements[0]) - 16;
     271             : 
     272             : namespace internal {
     273             : template <typename It> class RepeatedPtrIterator;
     274             : template <typename It, typename VoidPtr> class RepeatedPtrOverPtrsIterator;
     275             : }  // namespace internal
     276             : 
     277             : namespace internal {
     278             : 
     279             : // This is a helper template to copy an array of elements effeciently when they
     280             : // have a trivial copy constructor, and correctly otherwise. This really
     281             : // shouldn't be necessary, but our compiler doesn't optimize std::copy very
     282             : // effectively.
     283             : template <typename Element,
     284             :           bool HasTrivialCopy = has_trivial_copy<Element>::value>
     285             : struct ElementCopier {
     286             :   void operator()(Element* to, const Element* from, int array_size);
     287             : };
     288             : 
     289             : }  // namespace internal
     290             : 
     291             : namespace internal {
     292             : 
     293             : // type-traits helper for RepeatedPtrFieldBase: we only want to invoke
     294             : // arena-related "copy if on different arena" behavior if the necessary methods
     295             : // exist on the contained type. In particular, we rely on MergeFrom() existing
     296             : // as a general proxy for the fact that a copy will work, and we also provide a
     297             : // specific override for string*.
     298             : template<typename T>
     299             : struct TypeImplementsMergeBehavior {
     300             :   typedef char HasMerge;
     301             :   typedef long HasNoMerge;
     302             : 
     303             :   // We accept either of:
     304             :   // - void MergeFrom(const T& other)
     305             :   // - bool MergeFrom(const T& other)
     306             :   //
     307             :   // We mangle these names a bit to avoid compatibility issues in 'unclean'
     308             :   // include environments that may have, e.g., "#define test ..." (yes, this
     309             :   // exists).
     310             :   template<typename U, typename RetType, RetType (U::*)(const U& arg)>
     311             :       struct CheckType;
     312             :   template<typename U> static HasMerge Check(
     313             :       CheckType<U, void, &U::MergeFrom>*);
     314             :   template<typename U> static HasMerge Check(
     315             :       CheckType<U, bool, &U::MergeFrom>*);
     316             :   template<typename U> static HasNoMerge Check(...);
     317             : 
     318             :   // Resovles to either google::protobuf::internal::true_type or google::protobuf::internal::false_type.
     319             :   typedef google::protobuf::internal::integral_constant<bool,
     320             :                (sizeof(Check<T>(0)) == sizeof(HasMerge))> type;
     321             : };
     322             : 
     323             : template<>
     324             : struct TypeImplementsMergeBehavior< ::std::string > {
     325             :   typedef google::protobuf::internal::true_type type;
     326             : };
     327             : 
     328             : // This is the common base class for RepeatedPtrFields.  It deals only in void*
     329             : // pointers.  Users should not use this interface directly.
     330             : //
     331             : // The methods of this interface correspond to the methods of RepeatedPtrField,
     332             : // but may have a template argument called TypeHandler.  Its signature is:
     333             : //   class TypeHandler {
     334             : //    public:
     335             : //     typedef MyType Type;
     336             : //     static Type* New();
     337             : //     static void Delete(Type*);
     338             : //     static void Clear(Type*);
     339             : //     static void Merge(const Type& from, Type* to);
     340             : //
     341             : //     // Only needs to be implemented if SpaceUsedExcludingSelf() is called.
     342             : //     static int SpaceUsed(const Type&);
     343             : //   };
     344             : class LIBPROTOBUF_EXPORT RepeatedPtrFieldBase {
     345             :  protected:
     346             :   // The reflection implementation needs to call protected methods directly,
     347             :   // reinterpreting pointers as being to Message instead of a specific Message
     348             :   // subclass.
     349             :   friend class GeneratedMessageReflection;
     350             : 
     351             :   // ExtensionSet stores repeated message extensions as
     352             :   // RepeatedPtrField<MessageLite>, but non-lite ExtensionSets need to
     353             :   // implement SpaceUsed(), and thus need to call SpaceUsedExcludingSelf()
     354             :   // reinterpreting MessageLite as Message.  ExtensionSet also needs to make
     355             :   // use of AddFromCleared(), which is not part of the public interface.
     356             :   friend class ExtensionSet;
     357             : 
     358             :   // The MapFieldBase implementation needs to call protected methods directly,
     359             :   // reinterpreting pointers as being to Message instead of a specific Message
     360             :   // subclass.
     361             :   friend class MapFieldBase;
     362             : 
     363             :   // To parse directly into a proto2 generated class, the upb class GMR_Handlers
     364             :   // needs to be able to modify a RepeatedPtrFieldBase directly.
     365             :   friend class upb::google_opensource::GMR_Handlers;
     366             : 
     367             :   RepeatedPtrFieldBase();
     368             :   explicit RepeatedPtrFieldBase(::google::protobuf::Arena* arena);
     369          56 :   ~RepeatedPtrFieldBase() {}
     370             : 
     371             :   // Must be called from destructor.
     372             :   template <typename TypeHandler>
     373             :   void Destroy();
     374             : 
     375             :   bool empty() const;
     376             :   int size() const;
     377             : 
     378             :   template <typename TypeHandler>
     379             :   const typename TypeHandler::Type& Get(int index) const;
     380             :   template <typename TypeHandler>
     381             :   typename TypeHandler::Type* Mutable(int index);
     382             :   template <typename TypeHandler>
     383             :   void Delete(int index);
     384             :   template <typename TypeHandler>
     385             :   typename TypeHandler::Type* Add(typename TypeHandler::Type* prototype = NULL);
     386             : 
     387             :   template <typename TypeHandler>
     388             :   void RemoveLast();
     389             :   template <typename TypeHandler>
     390             :   void Clear();
     391             :   template <typename TypeHandler>
     392             :   void MergeFrom(const RepeatedPtrFieldBase& other);
     393             :   template <typename TypeHandler>
     394             :   void CopyFrom(const RepeatedPtrFieldBase& other);
     395             : 
     396             :   void CloseGap(int start, int num);
     397             : 
     398             :   void Reserve(int new_size);
     399             : 
     400             :   int Capacity() const;
     401             : 
     402             :   // Used for constructing iterators.
     403             :   void* const* raw_data() const;
     404             :   void** raw_mutable_data() const;
     405             : 
     406             :   template <typename TypeHandler>
     407             :   typename TypeHandler::Type** mutable_data();
     408             :   template <typename TypeHandler>
     409             :   const typename TypeHandler::Type* const* data() const;
     410             : 
     411             :   template <typename TypeHandler>
     412             :   GOOGLE_ATTRIBUTE_ALWAYS_INLINE void Swap(RepeatedPtrFieldBase* other);
     413             : 
     414             :   void SwapElements(int index1, int index2);
     415             : 
     416             :   template <typename TypeHandler>
     417             :   int SpaceUsedExcludingSelf() const;
     418             : 
     419             : 
     420             :   // Advanced memory management --------------------------------------
     421             : 
     422             :   // Like Add(), but if there are no cleared objects to use, returns NULL.
     423             :   template <typename TypeHandler>
     424             :   typename TypeHandler::Type* AddFromCleared();
     425             : 
     426             :   template<typename TypeHandler>
     427             :   void AddAllocated(typename TypeHandler::Type* value) {
     428             :     typename TypeImplementsMergeBehavior<typename TypeHandler::Type>::type t;
     429           0 :     AddAllocatedInternal<TypeHandler>(value, t);
     430             :   }
     431             : 
     432             :   template <typename TypeHandler>
     433             :   void UnsafeArenaAddAllocated(typename TypeHandler::Type* value);
     434             : 
     435             :   template <typename TypeHandler>
     436             :   typename TypeHandler::Type* ReleaseLast() {
     437             :     typename TypeImplementsMergeBehavior<typename TypeHandler::Type>::type t;
     438           0 :     return ReleaseLastInternal<TypeHandler>(t);
     439             :   }
     440             : 
     441             :   // Releases last element and returns it, but does not do out-of-arena copy.
     442             :   // And just returns the raw pointer to the contained element in the arena.
     443             :   template <typename TypeHandler>
     444             :   typename TypeHandler::Type* UnsafeArenaReleaseLast();
     445             : 
     446             :   int ClearedCount() const;
     447             :   template <typename TypeHandler>
     448             :   void AddCleared(typename TypeHandler::Type* value);
     449             :   template <typename TypeHandler>
     450             :   typename TypeHandler::Type* ReleaseCleared();
     451             : 
     452             :  protected:
     453             :   inline void InternalSwap(RepeatedPtrFieldBase* other);
     454             : 
     455             :   template <typename TypeHandler>
     456             :   void AddAllocatedInternal(typename TypeHandler::Type* value,
     457             :                             google::protobuf::internal::true_type);
     458             :   template <typename TypeHandler>
     459             :   void AddAllocatedInternal(typename TypeHandler::Type* value,
     460             :                             google::protobuf::internal::false_type);
     461             : 
     462             :   template <typename TypeHandler> GOOGLE_ATTRIBUTE_NOINLINE
     463             :   void AddAllocatedSlowWithCopy(typename TypeHandler::Type* value,
     464             :                                 Arena* value_arena,
     465             :                                 Arena* my_arena);
     466             :   template <typename TypeHandler> GOOGLE_ATTRIBUTE_NOINLINE
     467             :   void AddAllocatedSlowWithoutCopy(typename TypeHandler::Type* value);
     468             : 
     469             :   template <typename TypeHandler>
     470             :   typename TypeHandler::Type* ReleaseLastInternal(google::protobuf::internal::true_type);
     471             :   template <typename TypeHandler>
     472             :   typename TypeHandler::Type* ReleaseLastInternal(google::protobuf::internal::false_type);
     473             : 
     474             :   template<typename TypeHandler> GOOGLE_ATTRIBUTE_NOINLINE
     475             :   void SwapFallback(RepeatedPtrFieldBase* other);
     476             : 
     477          18 :   inline Arena* GetArenaNoVirtual() const {
     478          18 :     return arena_;
     479             :   }
     480             : 
     481             :  private:
     482             :   static const int kInitialSize = 0;
     483             :   // A few notes on internal representation:
     484             :   //
     485             :   // We use an indirected approach, with struct Rep, to keep
     486             :   // sizeof(RepeatedPtrFieldBase) equivalent to what it was before arena support
     487             :   // was added, namely, 3 8-byte machine words on x86-64. An instance of Rep is
     488             :   // allocated only when the repeated field is non-empty, and it is a
     489             :   // dynamically-sized struct (the header is directly followed by elements[]).
     490             :   // We place arena_ and current_size_ directly in the object to avoid cache
     491             :   // misses due to the indirection, because these fields are checked frequently.
     492             :   // Placing all fields directly in the RepeatedPtrFieldBase instance costs
     493             :   // significant performance for memory-sensitive workloads.
     494             :   Arena* arena_;
     495             :   int    current_size_;
     496             :   int    total_size_;
     497             :   struct Rep {
     498             :     int    allocated_size;
     499             :     void*  elements[1];
     500             :   };
     501             :   static const size_t kRepHeaderSize = sizeof(Rep) - sizeof(void*);
     502             :   // Contains arena ptr and the elements array. We also keep the invariant that
     503             :   // if rep_ is NULL, then arena is NULL.
     504             :   Rep* rep_;
     505             : 
     506             :   template <typename TypeHandler>
     507          86 :   static inline typename TypeHandler::Type* cast(void* element) {
     508          86 :     return reinterpret_cast<typename TypeHandler::Type*>(element);
     509             :   }
     510             :   template <typename TypeHandler>
     511             :   static inline const typename TypeHandler::Type* cast(const void* element) {
     512             :     return reinterpret_cast<const typename TypeHandler::Type*>(element);
     513             :   }
     514             : 
     515             :   // Non-templated inner function to avoid code duplication. Takes a function
     516             :   // pointer to the type-specific (templated) inner allocate/merge loop.
     517             :   void MergeFromInternal(
     518             :       const RepeatedPtrFieldBase& other,
     519             :       void (RepeatedPtrFieldBase::*inner_loop)(void**, void**, int, int));
     520             : 
     521             :   template<typename TypeHandler>
     522             :   void MergeFromInnerLoop(
     523             :       void** our_elems, void** other_elems, int length, int already_allocated);
     524             : 
     525             :   // Internal helper: extend array space if necessary to contain |extend_amount|
     526             :   // more elements, and return a pointer to the element immediately following
     527             :   // the old list of elements.  This interface factors out common behavior from
     528             :   // Reserve() and MergeFrom() to reduce code size. |extend_amount| must be > 0.
     529             :   void** InternalExtend(int extend_amount);
     530             : 
     531             :   GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RepeatedPtrFieldBase);
     532             : };
     533             : 
     534             : template <typename GenericType>
     535             : class GenericTypeHandler {
     536             :  public:
     537             :   typedef GenericType Type;
     538       69910 :   static inline GenericType* New(Arena* arena) {
     539             :     return ::google::protobuf::Arena::CreateMaybeMessage<Type>(
     540       69910 :         arena, static_cast<GenericType*>(0));
     541             :   }
     542             :   // We force NewFromPrototype() and Delete() to be non-inline to reduce code
     543             :   // size: else, several other methods get inlined copies of message types'
     544             :   // constructors and destructors.
     545             :   GOOGLE_ATTRIBUTE_NOINLINE static GenericType* NewFromPrototype(
     546             :       const GenericType* prototype, ::google::protobuf::Arena* arena = NULL);
     547             :   GOOGLE_ATTRIBUTE_NOINLINE static void Delete(GenericType* value, Arena* arena);
     548             :   static inline ::google::protobuf::Arena* GetArena(GenericType* value) {
     549             :     return ::google::protobuf::Arena::GetArena<Type>(value);
     550             :   }
     551             :   static inline void* GetMaybeArenaPointer(GenericType* value) {
     552             :     return ::google::protobuf::Arena::GetArena<Type>(value);
     553             :   }
     554             : 
     555         841 :   static inline void Clear(GenericType* value) { value->Clear(); }
     556             :   GOOGLE_ATTRIBUTE_NOINLINE static void Merge(const GenericType& from,
     557             :                                        GenericType* to);
     558             :   static inline int SpaceUsed(const GenericType& value) {
     559           0 :     return value.SpaceUsed();
     560             :   }
     561             :   static inline const Type& default_instance() {
     562             :     return Type::default_instance();
     563             :   }
     564             : };
     565             : 
     566             : template <typename GenericType>
     567       69910 : GenericType* GenericTypeHandler<GenericType>::NewFromPrototype(
     568             :     const GenericType* prototype, ::google::protobuf::Arena* arena) {
     569       69910 :   return New(arena);
     570             : }
     571             : template <typename GenericType>
     572       70315 : void GenericTypeHandler<GenericType>::Delete(GenericType* value, Arena* arena) {
     573       70315 :   if (arena == NULL) {
     574       70315 :     delete value;
     575             :   }
     576       70315 : }
     577             : template <typename GenericType>
     578       25994 : void GenericTypeHandler<GenericType>::Merge(const GenericType& from,
     579             :                                             GenericType* to) {
     580       25994 :   to->MergeFrom(from);
     581       25994 : }
     582             : 
     583             : // NewFromPrototype() and Merge() cannot be defined here; if they're declared
     584             : // inline the compiler will complain about not matching GOOGLE_ATTRIBUTE_NOINLINE
     585             : // above, and if not, compilation will result in multiple definitions.  These
     586             : // are therefore declared as specializations here and defined in
     587             : // message_lite.cc.
     588             : template<>
     589             : MessageLite* GenericTypeHandler<MessageLite>::NewFromPrototype(
     590             :     const MessageLite* prototype, google::protobuf::Arena* arena);
     591             : template<>
     592             : inline google::protobuf::Arena* GenericTypeHandler<MessageLite>::GetArena(
     593             :     MessageLite* value) {
     594             :   return value->GetArena();
     595             : }
     596             : template<>
     597             : inline void* GenericTypeHandler<MessageLite>::GetMaybeArenaPointer(
     598             :     MessageLite* value) {
     599             :   return value->GetMaybeArenaPointer();
     600             : }
     601             : template <>
     602             : void GenericTypeHandler<MessageLite>::Merge(const MessageLite& from,
     603             :                                             MessageLite* to);
     604             : 
     605             : // Declarations of the specialization as we cannot define them here, as the
     606             : // header that defines ProtocolMessage depends on types defined in this header.
     607             : #define DECLARE_SPECIALIZATIONS_FOR_BASE_PROTO_TYPES(TypeName)                 \
     608             :     template<>                                                                 \
     609             :     TypeName* GenericTypeHandler<TypeName>::NewFromPrototype(                  \
     610             :         const TypeName* prototype, google::protobuf::Arena* arena);                      \
     611             :     template<>                                                                 \
     612             :     google::protobuf::Arena* GenericTypeHandler<TypeName>::GetArena(                     \
     613             :         TypeName* value);                                                      \
     614             :     template<>                                                                 \
     615             :     void* GenericTypeHandler<TypeName>::GetMaybeArenaPointer(                  \
     616             :         TypeName* value);
     617             : 
     618             : // Message specialization bodies defined in message.cc. This split is necessary
     619             : // to allow proto2-lite (which includes this header) to be independent of
     620             : // Message.
     621             : DECLARE_SPECIALIZATIONS_FOR_BASE_PROTO_TYPES(Message);
     622             : 
     623             : 
     624             : #undef DECLARE_SPECIALIZATIONS_FOR_BASE_PROTO_TYPES
     625             : 
     626             : template <>
     627             : inline const MessageLite& GenericTypeHandler<MessageLite>::default_instance() {
     628             :   // Yes, the behavior of the code is undefined, but this function is only
     629             :   // called when we're already deep into the world of undefined, because the
     630             :   // caller called Get(index) out of bounds.
     631             :   MessageLite* null = NULL;
     632             :   return *null;
     633             : }
     634             : 
     635             : template <>
     636             : inline const Message& GenericTypeHandler<Message>::default_instance() {
     637             :   // Yes, the behavior of the code is undefined, but this function is only
     638             :   // called when we're already deep into the world of undefined, because the
     639             :   // caller called Get(index) out of bounds.
     640             :   Message* null = NULL;
     641             :   return *null;
     642             : }
     643             : 
     644             : 
     645             : // HACK:  If a class is declared as DLL-exported in MSVC, it insists on
     646             : //   generating copies of all its methods -- even inline ones -- to include
     647             : //   in the DLL.  But SpaceUsed() calls StringSpaceUsedExcludingSelf() which
     648             : //   isn't in the lite library, therefore the lite library cannot link if
     649             : //   StringTypeHandler is exported.  So, we factor out StringTypeHandlerBase,
     650             : //   export that, then make StringTypeHandler be a subclass which is NOT
     651             : //   exported.
     652             : // TODO(kenton):  There has to be a better way.
     653             : class LIBPROTOBUF_EXPORT StringTypeHandlerBase {
     654             :  public:
     655             :   typedef string Type;
     656             : 
     657         476 :   static inline string* New(Arena* arena) {
     658         506 :     return Arena::Create<string>(arena);
     659             :   }
     660          30 :   static inline string* NewFromPrototype(const string*,
     661             :                                          ::google::protobuf::Arena* arena) {
     662         476 :     return New(arena);
     663             :   }
     664             :   static inline ::google::protobuf::Arena* GetArena(string*) {
     665             :     return NULL;
     666             :   }
     667             :   static inline void* GetMaybeArenaPointer(string* value) {
     668             :     return NULL;
     669             :   }
     670         476 :   static inline void Delete(string* value, Arena* arena) {
     671         476 :     if (arena == NULL) {
     672         922 :       delete value;
     673             :     }
     674         476 :   }
     675           0 :   static inline void Clear(string* value) { value->clear(); }
     676          18 :   static inline void Merge(const string& from, string* to) { *to = from; }
     677             :   static inline const Type& default_instance() {
     678             :     return ::google::protobuf::internal::GetEmptyString();
     679             :   }
     680             : };
     681             : 
     682             : class StringTypeHandler : public StringTypeHandlerBase {
     683             :  public:
     684             :   static int SpaceUsed(const string& value)  {
     685           0 :     return sizeof(value) + StringSpaceUsedExcludingSelf(value);
     686             :   }
     687             : };
     688             : 
     689             : 
     690             : }  // namespace internal
     691             : 
     692             : // RepeatedPtrField is like RepeatedField, but used for repeated strings or
     693             : // Messages.
     694             : template <typename Element>
     695             : class RepeatedPtrField : public internal::RepeatedPtrFieldBase {
     696             :  public:
     697             :   RepeatedPtrField();
     698             :   explicit RepeatedPtrField(::google::protobuf::Arena* arena);
     699             : 
     700             :   RepeatedPtrField(const RepeatedPtrField& other);
     701             :   template <typename Iter>
     702             :   RepeatedPtrField(Iter begin, const Iter& end);
     703             :   ~RepeatedPtrField();
     704             : 
     705             :   RepeatedPtrField& operator=(const RepeatedPtrField& other);
     706             : 
     707             :   bool empty() const;
     708             :   int size() const;
     709             : 
     710             :   const Element& Get(int index) const;
     711             :   Element* Mutable(int index);
     712             :   Element* Add();
     713             : 
     714             :   // Remove the last element in the array.
     715             :   // Ownership of the element is retained by the array.
     716             :   void RemoveLast();
     717             : 
     718             :   // Delete elements with indices in the range [start .. start+num-1].
     719             :   // Caution: implementation moves all elements with indices [start+num .. ].
     720             :   // Calling this routine inside a loop can cause quadratic behavior.
     721             :   void DeleteSubrange(int start, int num);
     722             : 
     723             :   void Clear();
     724             :   void MergeFrom(const RepeatedPtrField& other);
     725             :   void CopyFrom(const RepeatedPtrField& other);
     726             : 
     727             :   // Reserve space to expand the field to at least the given size.  This only
     728             :   // resizes the pointer array; it doesn't allocate any objects.  If the
     729             :   // array is grown, it will always be at least doubled in size.
     730             :   void Reserve(int new_size);
     731             : 
     732             :   int Capacity() const;
     733             : 
     734             :   // Gets the underlying array.  This pointer is possibly invalidated by
     735             :   // any add or remove operation.
     736             :   Element** mutable_data();
     737             :   const Element* const* data() const;
     738             : 
     739             :   // Swap entire contents with "other". If they are on separate arenas, then
     740             :   // copies data.
     741             :   void Swap(RepeatedPtrField* other);
     742             : 
     743             :   // Swap entire contents with "other". Caller should guarantee that either both
     744             :   // fields are on the same arena or both are on the heap. Swapping between
     745             :   // different arenas with this function is disallowed and is caught via
     746             :   // GOOGLE_DCHECK.
     747             :   void UnsafeArenaSwap(RepeatedPtrField* other);
     748             : 
     749             :   // Swap two elements.
     750             :   void SwapElements(int index1, int index2);
     751             : 
     752             :   // STL-like iterator support
     753             :   typedef internal::RepeatedPtrIterator<Element> iterator;
     754             :   typedef internal::RepeatedPtrIterator<const Element> const_iterator;
     755             :   typedef Element value_type;
     756             :   typedef value_type& reference;
     757             :   typedef const value_type& const_reference;
     758             :   typedef value_type* pointer;
     759             :   typedef const value_type* const_pointer;
     760             :   typedef int size_type;
     761             :   typedef ptrdiff_t difference_type;
     762             : 
     763             :   iterator begin();
     764             :   const_iterator begin() const;
     765             :   const_iterator cbegin() const;
     766             :   iterator end();
     767             :   const_iterator end() const;
     768             :   const_iterator cend() const;
     769             : 
     770             :   // Reverse iterator support
     771             :   typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
     772             :   typedef std::reverse_iterator<iterator> reverse_iterator;
     773             :   reverse_iterator rbegin() {
     774             :     return reverse_iterator(end());
     775             :   }
     776             :   const_reverse_iterator rbegin() const {
     777             :     return const_reverse_iterator(end());
     778             :   }
     779             :   reverse_iterator rend() {
     780             :     return reverse_iterator(begin());
     781             :   }
     782             :   const_reverse_iterator rend() const {
     783             :     return const_reverse_iterator(begin());
     784             :   }
     785             : 
     786             :   // Custom STL-like iterator that iterates over and returns the underlying
     787             :   // pointers to Element rather than Element itself.
     788             :   typedef internal::RepeatedPtrOverPtrsIterator<Element, void*>
     789             :   pointer_iterator;
     790             :   typedef internal::RepeatedPtrOverPtrsIterator<const Element, const void*>
     791             :   const_pointer_iterator;
     792             :   pointer_iterator pointer_begin();
     793             :   const_pointer_iterator pointer_begin() const;
     794             :   pointer_iterator pointer_end();
     795             :   const_pointer_iterator pointer_end() const;
     796             : 
     797             :   // Returns (an estimate of) the number of bytes used by the repeated field,
     798             :   // excluding sizeof(*this).
     799             :   int SpaceUsedExcludingSelf() const;
     800             : 
     801             :   // Advanced memory management --------------------------------------
     802             :   // When hardcore memory management becomes necessary -- as it sometimes
     803             :   // does here at Google -- the following methods may be useful.
     804             : 
     805             :   // Add an already-allocated object, passing ownership to the
     806             :   // RepeatedPtrField.
     807             :   //
     808             :   // Note that some special behavior occurs with respect to arenas:
     809             :   //
     810             :   //   (i) if this field holds submessages, the new submessage will be copied if
     811             :   //   the original is in an arena and this RepeatedPtrField is either in a
     812             :   //   different arena, or on the heap.
     813             :   //   (ii) if this field holds strings, the passed-in string *must* be
     814             :   //   heap-allocated, not arena-allocated. There is no way to dynamically check
     815             :   //   this at runtime, so User Beware.
     816             :   void AddAllocated(Element* value);
     817             : 
     818             :   // Remove the last element and return it, passing ownership to the caller.
     819             :   // Requires:  size() > 0
     820             :   //
     821             :   // If this RepeatedPtrField is on an arena, an object copy is required to pass
     822             :   // ownership back to the user (for compatible semantics). Use
     823             :   // UnsafeArenaReleaseLast() if this behavior is undesired.
     824             :   Element* ReleaseLast();
     825             : 
     826             :   // Add an already-allocated object, skipping arena-ownership checks. The user
     827             :   // must guarantee that the given object is in the same arena as this
     828             :   // RepeatedPtrField.
     829             :   void UnsafeArenaAddAllocated(Element* value);
     830             : 
     831             :   // Remove the last element and return it.  Works only when operating on an
     832             :   // arena. The returned pointer is to the original object in the arena, hence
     833             :   // has the arena's lifetime.
     834             :   // Requires:  current_size_ > 0
     835             :   Element* UnsafeArenaReleaseLast();
     836             : 
     837             :   // Extract elements with indices in the range "[start .. start+num-1]".
     838             :   // The caller assumes ownership of the extracted elements and is responsible
     839             :   // for deleting them when they are no longer needed.
     840             :   // If "elements" is non-NULL, then pointers to the extracted elements
     841             :   // are stored in "elements[0 .. num-1]" for the convenience of the caller.
     842             :   // If "elements" is NULL, then the caller must use some other mechanism
     843             :   // to perform any further operations (like deletion) on these elements.
     844             :   // Caution: implementation also moves elements with indices [start+num ..].
     845             :   // Calling this routine inside a loop can cause quadratic behavior.
     846             :   //
     847             :   // Memory copying behavior is identical to ReleaseLast(), described above: if
     848             :   // this RepeatedPtrField is on an arena, an object copy is performed for each
     849             :   // returned element, so that all returned element pointers are to
     850             :   // heap-allocated copies. If this copy is not desired, the user should call
     851             :   // UnsafeArenaExtractSubrange().
     852             :   void ExtractSubrange(int start, int num, Element** elements);
     853             : 
     854             :   // Identical to ExtractSubrange() described above, except that when this
     855             :   // repeated field is on an arena, no object copies are performed. Instead, the
     856             :   // raw object pointers are returned. Thus, if on an arena, the returned
     857             :   // objects must not be freed, because they will not be heap-allocated objects.
     858             :   void UnsafeArenaExtractSubrange(int start, int num, Element** elements);
     859             : 
     860             :   // When elements are removed by calls to RemoveLast() or Clear(), they
     861             :   // are not actually freed.  Instead, they are cleared and kept so that
     862             :   // they can be reused later.  This can save lots of CPU time when
     863             :   // repeatedly reusing a protocol message for similar purposes.
     864             :   //
     865             :   // Hardcore programs may choose to manipulate these cleared objects
     866             :   // to better optimize memory management using the following routines.
     867             : 
     868             :   // Get the number of cleared objects that are currently being kept
     869             :   // around for reuse.
     870             :   int ClearedCount() const;
     871             :   // Add an element to the pool of cleared objects, passing ownership to
     872             :   // the RepeatedPtrField.  The element must be cleared prior to calling
     873             :   // this method.
     874             :   //
     875             :   // This method cannot be called when the repeated field is on an arena or when
     876             :   // |value| is; both cases will trigger a GOOGLE_DCHECK-failure.
     877             :   void AddCleared(Element* value);
     878             :   // Remove a single element from the cleared pool and return it, passing
     879             :   // ownership to the caller.  The element is guaranteed to be cleared.
     880             :   // Requires:  ClearedCount() > 0
     881             :   //
     882             :   //
     883             :   // This method cannot be called when the repeated field is on an arena; doing
     884             :   // so will trigger a GOOGLE_DCHECK-failure.
     885             :   Element* ReleaseCleared();
     886             : 
     887             :   // Remove the element referenced by position.
     888             :   iterator erase(const_iterator position);
     889             : 
     890             :   // Removes the elements in the range [first, last).
     891             :   iterator erase(const_iterator first, const_iterator last);
     892             : 
     893             :   // Gets the arena on which this RepeatedPtrField stores its elements.
     894             :   ::google::protobuf::Arena* GetArena() const {
     895             :     return GetArenaNoVirtual();
     896             :   }
     897             : 
     898             :  protected:
     899             :   // Note:  RepeatedPtrField SHOULD NOT be subclassed by users.  We only
     900             :   //   subclass it in one place as a hack for compatibility with proto1.  The
     901             :   //   subclass needs to know about TypeHandler in order to call protected
     902             :   //   methods on RepeatedPtrFieldBase.
     903             :   class TypeHandler;
     904             : 
     905             :   // Internal arena accessor expected by helpers in Arena.
     906             :   inline Arena* GetArenaNoVirtual() const;
     907             : 
     908             :  private:
     909             :   // Implementations for ExtractSubrange(). The copying behavior must be
     910             :   // included only if the type supports the necessary operations (e.g.,
     911             :   // MergeFrom()), so we must resolve this at compile time. ExtractSubrange()
     912             :   // uses SFINAE to choose one of the below implementations.
     913             :   void ExtractSubrangeInternal(int start, int num, Element** elements,
     914             :                                google::protobuf::internal::true_type);
     915             :   void ExtractSubrangeInternal(int start, int num, Element** elements,
     916             :                                google::protobuf::internal::false_type);
     917             : 
     918             :   friend class Arena;
     919             :   typedef void InternalArenaConstructable_;
     920             : 
     921             : };
     922             : 
     923             : // implementation ====================================================
     924             : 
     925             : template <typename Element>
     926          47 : inline RepeatedField<Element>::RepeatedField()
     927             :   : current_size_(0),
     928             :     total_size_(0),
     929      102997 :     rep_(NULL) {
     930          47 : }
     931             : 
     932             : template <typename Element>
     933           0 : inline RepeatedField<Element>::RepeatedField(Arena* arena)
     934             :   : current_size_(0),
     935             :     total_size_(0),
     936           0 :     rep_(NULL) {
     937             :  // In case arena is NULL, then we do not create rep_, as code has an invariant
     938             :  // `rep_ == NULL then arena == NULL`.
     939           0 :  if (arena != NULL) {
     940           0 :   rep_ = reinterpret_cast<Rep*>(
     941             :       ::google::protobuf::Arena::CreateArray<char>(arena, kRepHeaderSize));
     942           0 :   rep_->arena = arena;
     943             :  }
     944           0 : }
     945             : 
     946             : template <typename Element>
     947             : inline RepeatedField<Element>::RepeatedField(const RepeatedField& other)
     948             :   : current_size_(0),
     949             :     total_size_(0),
     950             :     rep_(NULL) {
     951             :   CopyFrom(other);
     952             : }
     953             : 
     954             : template <typename Element>
     955             : template <typename Iter>
     956             : RepeatedField<Element>::RepeatedField(Iter begin, const Iter& end)
     957             :   : current_size_(0),
     958             :     total_size_(0),
     959             :     rep_(NULL) {
     960             :   int reserve = internal::CalculateReserve(begin, end);
     961             :   if (reserve != -1) {
     962             :     Reserve(reserve);
     963             :     for (; begin != end; ++begin) {
     964             :       AddAlreadyReserved(*begin);
     965             :     }
     966             :   } else {
     967             :     for (; begin != end; ++begin) {
     968             :       Add(*begin);
     969             :     }
     970             :   }
     971             : }
     972             : 
     973             : template <typename Element>
     974      102480 : RepeatedField<Element>::~RepeatedField() {
     975             :   // See explanation in Reserve(): we need to invoke destructors here for the
     976             :   // case that Element has a non-trivial destructor. If Element has a trivial
     977             :   // destructor (for example, if it's a primitive type, like int32), this entire
     978             :   // loop will be removed by the optimizer.
     979      102480 :   if (rep_ != NULL) {
     980      100666 :     Element* e = &rep_->elements[0];
     981      100666 :     Element* limit = &rep_->elements[total_size_];
     982          36 :     for (; e < limit; e++) {
     983             :       e->Element::~Element();
     984             :     }
     985      100666 :     if (rep_->arena == NULL) {
     986      100666 :       delete[] reinterpret_cast<char*>(rep_);
     987             :     }
     988             :   }
     989      102480 : }
     990             : 
     991             : template <typename Element>
     992             : inline RepeatedField<Element>&
     993             : RepeatedField<Element>::operator=(const RepeatedField& other) {
     994             :   if (this != &other)
     995             :     CopyFrom(other);
     996             :   return *this;
     997             : }
     998             : 
     999             : template <typename Element>
    1000             : inline bool RepeatedField<Element>::empty() const {
    1001           0 :   return current_size_ == 0;
    1002             : }
    1003             : 
    1004             : template <typename Element>
    1005       59922 : inline int RepeatedField<Element>::size() const {
    1006       59922 :   return current_size_;
    1007             : }
    1008             : 
    1009             : template <typename Element>
    1010           0 : inline int RepeatedField<Element>::Capacity() const {
    1011           0 :   return total_size_;
    1012             : }
    1013             : 
    1014             : template<typename Element>
    1015           0 : inline void RepeatedField<Element>::AddAlreadyReserved(const Element& value) {
    1016           0 :   GOOGLE_DCHECK_LT(current_size_, total_size_);
    1017           0 :   rep_->elements[current_size_++] = value;
    1018           0 : }
    1019             : 
    1020             : template<typename Element>
    1021             : inline Element* RepeatedField<Element>::AddAlreadyReserved() {
    1022             :   GOOGLE_DCHECK_LT(current_size_, total_size_);
    1023             :   return &rep_->elements[current_size_++];
    1024             : }
    1025             : 
    1026             : template<typename Element>
    1027             : inline void RepeatedField<Element>::Resize(int new_size, const Element& value) {
    1028             :   GOOGLE_DCHECK_GE(new_size, 0);
    1029             :   if (new_size > current_size_) {
    1030             :     Reserve(new_size);
    1031             :     std::fill(&rep_->elements[current_size_],
    1032             :               &rep_->elements[new_size], value);
    1033             :   }
    1034             :   current_size_ = new_size;
    1035             : }
    1036             : 
    1037             : template <typename Element>
    1038       59880 : inline const Element& RepeatedField<Element>::Get(int index) const {
    1039       59880 :   GOOGLE_DCHECK_GE(index, 0);
    1040       59880 :   GOOGLE_DCHECK_LT(index, current_size_);
    1041       59880 :   return rep_->elements[index];
    1042             : }
    1043             : 
    1044             : template <typename Element>
    1045             : inline Element* RepeatedField<Element>::Mutable(int index) {
    1046             :   GOOGLE_DCHECK_GE(index, 0);
    1047             :   GOOGLE_DCHECK_LT(index, current_size_);
    1048             :   return &rep_->elements[index];
    1049             : }
    1050             : 
    1051             : template <typename Element>
    1052             : inline void RepeatedField<Element>::Set(int index, const Element& value) {
    1053             :   GOOGLE_DCHECK_GE(index, 0);
    1054             :   GOOGLE_DCHECK_LT(index, current_size_);
    1055         678 :   rep_->elements[index] = value;
    1056             : }
    1057             : 
    1058             : template <typename Element>
    1059      168819 : inline void RepeatedField<Element>::Add(const Element& value) {
    1060      168819 :   if (current_size_ == total_size_) Reserve(total_size_ + 1);
    1061      168819 :   rep_->elements[current_size_++] = value;
    1062      168819 : }
    1063             : 
    1064             : template <typename Element>
    1065           2 : inline Element* RepeatedField<Element>::Add() {
    1066           2 :   if (current_size_ == total_size_) Reserve(total_size_ + 1);
    1067           2 :   return &rep_->elements[current_size_++];
    1068             : }
    1069             : 
    1070             : template <typename Element>
    1071             : inline void RepeatedField<Element>::RemoveLast() {
    1072             :   GOOGLE_DCHECK_GT(current_size_, 0);
    1073           0 :   current_size_--;
    1074             : }
    1075             : 
    1076             : template <typename Element>
    1077             : void RepeatedField<Element>::ExtractSubrange(
    1078             :     int start, int num, Element* elements) {
    1079             :   GOOGLE_DCHECK_GE(start, 0);
    1080             :   GOOGLE_DCHECK_GE(num, 0);
    1081             :   GOOGLE_DCHECK_LE(start + num, this->current_size_);
    1082             : 
    1083             :   // Save the values of the removed elements if requested.
    1084             :   if (elements != NULL) {
    1085             :     for (int i = 0; i < num; ++i)
    1086             :       elements[i] = this->Get(i + start);
    1087             :   }
    1088             : 
    1089             :   // Slide remaining elements down to fill the gap.
    1090             :   if (num > 0) {
    1091             :     for (int i = start + num; i < this->current_size_; ++i)
    1092             :       this->Set(i - num, this->Get(i));
    1093             :     this->Truncate(this->current_size_ - num);
    1094             :   }
    1095             : }
    1096             : 
    1097             : template <typename Element>
    1098           0 : inline void RepeatedField<Element>::Clear() {
    1099       22978 :   current_size_ = 0;
    1100           0 : }
    1101             : 
    1102             : template <typename Element>
    1103       74762 : inline void RepeatedField<Element>::MergeFrom(const RepeatedField& other) {
    1104       74762 :   GOOGLE_CHECK_NE(&other, this);
    1105       74762 :   if (other.current_size_ != 0) {
    1106       73807 :     Reserve(current_size_ + other.current_size_);
    1107      147614 :     CopyArray(rep_->elements + current_size_,
    1108      147614 :               other.rep_->elements, other.current_size_);
    1109       73807 :     current_size_ += other.current_size_;
    1110             :   }
    1111       74762 : }
    1112             : 
    1113             : template <typename Element>
    1114             : inline void RepeatedField<Element>::CopyFrom(const RepeatedField& other) {
    1115       22762 :   if (&other == this) return;
    1116       22762 :   Clear();
    1117       22762 :   MergeFrom(other);
    1118             : }
    1119             : 
    1120             : template <typename Element>
    1121             : inline typename RepeatedField<Element>::iterator RepeatedField<Element>::erase(
    1122             :     const_iterator position) {
    1123             :   return erase(position, position + 1);
    1124             : }
    1125             : 
    1126             : template <typename Element>
    1127             : inline typename RepeatedField<Element>::iterator RepeatedField<Element>::erase(
    1128             :     const_iterator first, const_iterator last) {
    1129             :   size_type first_offset = first - cbegin();
    1130             :   if (first != last) {
    1131             :     Truncate(std::copy(last, cend(), begin() + first_offset) - cbegin());
    1132             :   }
    1133             :   return begin() + first_offset;
    1134             : }
    1135             : 
    1136             : template <typename Element>
    1137             : inline Element* RepeatedField<Element>::mutable_data() {
    1138             :   return rep_ ? rep_->elements : NULL;
    1139             : }
    1140             : 
    1141             : template <typename Element>
    1142             : inline const Element* RepeatedField<Element>::data() const {
    1143             :   return rep_ ? rep_->elements : NULL;
    1144             : }
    1145             : 
    1146             : 
    1147             : template <typename Element>
    1148           0 : inline void RepeatedField<Element>::InternalSwap(RepeatedField* other) {
    1149           0 :   std::swap(rep_, other->rep_);
    1150           0 :   std::swap(current_size_, other->current_size_);
    1151           0 :   std::swap(total_size_, other->total_size_);
    1152           0 : }
    1153             : 
    1154             : template <typename Element>
    1155           0 : void RepeatedField<Element>::Swap(RepeatedField* other) {
    1156           0 :   if (this == other) return;
    1157           0 :   if (GetArenaNoVirtual() ==  other->GetArenaNoVirtual()) {
    1158             :     InternalSwap(other);
    1159             :   } else {
    1160           0 :     RepeatedField<Element> temp(other->GetArenaNoVirtual());
    1161           0 :     temp.MergeFrom(*this);
    1162             :     CopyFrom(*other);
    1163           0 :     other->UnsafeArenaSwap(&temp);
    1164             :   }
    1165             : }
    1166             : 
    1167             : template <typename Element>
    1168           0 : void RepeatedField<Element>::UnsafeArenaSwap(RepeatedField* other) {
    1169           0 :   if (this == other) return;
    1170           0 :   GOOGLE_DCHECK(GetArenaNoVirtual() == other->GetArenaNoVirtual());
    1171           0 :   InternalSwap(other);
    1172             : }
    1173             : 
    1174             : template <typename Element>
    1175             : void RepeatedField<Element>::SwapElements(int index1, int index2) {
    1176             :   using std::swap;  // enable ADL with fallback
    1177           0 :   swap(rep_->elements[index1], rep_->elements[index2]);
    1178             : }
    1179             : 
    1180             : template <typename Element>
    1181             : inline typename RepeatedField<Element>::iterator
    1182             : RepeatedField<Element>::begin() {
    1183             :   return rep_ ? rep_->elements : NULL;
    1184             : }
    1185             : template <typename Element>
    1186             : inline typename RepeatedField<Element>::const_iterator
    1187           6 : RepeatedField<Element>::begin() const {
    1188           6 :   return rep_ ? rep_->elements : NULL;
    1189             : }
    1190             : template <typename Element>
    1191             : inline typename RepeatedField<Element>::const_iterator
    1192             : RepeatedField<Element>::cbegin() const {
    1193             :   return rep_ ? rep_->elements : NULL;
    1194             : }
    1195             : template <typename Element>
    1196             : inline typename RepeatedField<Element>::iterator
    1197             : RepeatedField<Element>::end() {
    1198             :   return rep_ ? rep_->elements + current_size_ : NULL;
    1199             : }
    1200             : template <typename Element>
    1201             : inline typename RepeatedField<Element>::const_iterator
    1202             : RepeatedField<Element>::end() const {
    1203           0 :   return rep_ ? rep_->elements + current_size_ : NULL;
    1204             : }
    1205             : template <typename Element>
    1206             : inline typename RepeatedField<Element>::const_iterator
    1207             : RepeatedField<Element>::cend() const {
    1208             :   return rep_ ? rep_->elements + current_size_ : NULL;
    1209             : }
    1210             : 
    1211             : template <typename Element>
    1212             : inline int RepeatedField<Element>::SpaceUsedExcludingSelf() const {
    1213             :   return rep_ ?
    1214           0 :       (total_size_ * sizeof(Element) + kRepHeaderSize) : 0;
    1215             : }
    1216             : 
    1217             : // Avoid inlining of Reserve(): new, copy, and delete[] lead to a significant
    1218             : // amount of code bloat.
    1219             : template <typename Element>
    1220      118272 : void RepeatedField<Element>::Reserve(int new_size) {
    1221      236544 :   if (total_size_ >= new_size) return;
    1222      118272 :   Rep* old_rep = rep_;
    1223      236268 :   Arena* arena = GetArenaNoVirtual();
    1224      118272 :   new_size = max(google::protobuf::internal::kMinRepeatedFieldAllocationSize,
    1225      354540 :                  max(total_size_ * 2, new_size));
    1226      118272 :   GOOGLE_CHECK_LE(static_cast<size_t>(new_size),
    1227             :            (std::numeric_limits<size_t>::max() - kRepHeaderSize) /
    1228             :            sizeof(Element))
    1229           0 :       << "Requested size is too large to fit into size_t.";
    1230      118272 :   if (arena == NULL) {
    1231      118272 :     rep_ = reinterpret_cast<Rep*>(
    1232             :         new char[kRepHeaderSize + sizeof(Element) * new_size]);
    1233             :   } else {
    1234           0 :     rep_ = reinterpret_cast<Rep*>(
    1235             :             ::google::protobuf::Arena::CreateArray<char>(arena,
    1236           0 :                 kRepHeaderSize + sizeof(Element) * new_size));
    1237             :   }
    1238      118272 :   rep_->arena = arena;
    1239      118272 :   int old_total_size = total_size_;
    1240      118272 :   total_size_ = new_size;
    1241             :   // Invoke placement-new on newly allocated elements. We shouldn't have to do
    1242             :   // this, since Element is supposed to be POD, but a previous version of this
    1243             :   // code allocated storage with "new Element[size]" and some code uses
    1244             :   // RepeatedField with non-POD types, relying on constructor invocation. If
    1245             :   // Element has a trivial constructor (e.g., int32), gcc (tested with -O2)
    1246             :   // completely removes this loop because the loop body is empty, so this has no
    1247             :   // effect unless its side-effects are required for correctness.
    1248             :   // Note that we do this before MoveArray() below because Element's copy
    1249             :   // assignment implementation will want an initialized instance first.
    1250      118272 :   Element* e = &rep_->elements[0];
    1251      118272 :   Element* limit = &rep_->elements[total_size_];
    1252      924581 :   for (; e < limit; e++) {
    1253      806309 :     new (e) Element();
    1254             :   }
    1255      118272 :   if (current_size_ > 0) {
    1256       17606 :     MoveArray(rep_->elements, old_rep->elements, current_size_);
    1257             :   }
    1258      118272 :   if (old_rep) {
    1259             :     // Likewise, we need to invoke destructors on the old array. If Element has
    1260             :     // no destructor, this loop will disappear.
    1261       17606 :     e = &old_rep->elements[0];
    1262       17606 :     limit = &old_rep->elements[old_total_size];
    1263         240 :     for (; e < limit; e++) {
    1264             :       e->Element::~Element();
    1265             :     }
    1266       17606 :     if (arena == NULL) {
    1267       17606 :       delete[] reinterpret_cast<char*>(old_rep);
    1268             :     }
    1269             :   }
    1270             : }
    1271             : 
    1272             : template <typename Element>
    1273             : inline void RepeatedField<Element>::Truncate(int new_size) {
    1274             :   GOOGLE_DCHECK_LE(new_size, current_size_);
    1275             :   if (current_size_ > 0) {
    1276             :     current_size_ = new_size;
    1277             :   }
    1278             : }
    1279             : 
    1280             : template <typename Element>
    1281         240 : inline void RepeatedField<Element>::MoveArray(
    1282             :   Element* to, Element* from, int array_size) {
    1283       17606 :   CopyArray(to, from, array_size);
    1284         240 : }
    1285             : 
    1286             : template <typename Element>
    1287         252 : inline void RepeatedField<Element>::CopyArray(
    1288             :   Element* to, const Element* from, int array_size) {
    1289       91413 :   internal::ElementCopier<Element>()(to, from, array_size);
    1290         252 : }
    1291             : 
    1292             : namespace internal {
    1293             : 
    1294             : template <typename Element, bool HasTrivialCopy>
    1295             : void ElementCopier<Element, HasTrivialCopy>::operator()(
    1296             :   Element* to, const Element* from, int array_size) {
    1297             :   std::copy(from, from + array_size, to);
    1298             : }
    1299             : 
    1300             : template <typename Element>
    1301             : struct ElementCopier<Element, true> {
    1302         252 :   void operator()(Element* to, const Element* from, int array_size) {
    1303       91413 :     memcpy(to, from, array_size * sizeof(Element));
    1304         252 :   }
    1305             : };
    1306             : 
    1307             : }  // namespace internal
    1308             : 
    1309             : 
    1310             : // -------------------------------------------------------------------
    1311             : 
    1312             : namespace internal {
    1313             : 
    1314          67 : inline RepeatedPtrFieldBase::RepeatedPtrFieldBase()
    1315             :   : arena_(NULL),
    1316             :     current_size_(0),
    1317             :     total_size_(0),
    1318       78779 :     rep_(NULL) {
    1319          67 : }
    1320             : 
    1321             : inline RepeatedPtrFieldBase::RepeatedPtrFieldBase(::google::protobuf::Arena* arena)
    1322             :   : arena_(arena),
    1323             :     current_size_(0),
    1324             :     total_size_(0),
    1325           0 :     rep_(NULL) {
    1326             : }
    1327             : 
    1328             : template <typename TypeHandler>
    1329       77390 : void RepeatedPtrFieldBase::Destroy() {
    1330       77390 :   if (rep_ != NULL) {
    1331       70821 :     for (int i = 0; i < rep_->allocated_size; i++) {
    1332       70791 :       TypeHandler::Delete(cast<TypeHandler>(rep_->elements[i]), arena_);
    1333             :     }
    1334        6177 :     if (arena_ == NULL) {
    1335        6177 :       delete [] reinterpret_cast<char*>(rep_);
    1336             :     }
    1337             :   }
    1338       77390 :   rep_ = NULL;
    1339       77390 : }
    1340             : 
    1341             : template <typename TypeHandler>
    1342           0 : inline void RepeatedPtrFieldBase::Swap(RepeatedPtrFieldBase* other) {
    1343           0 :   if (other->GetArenaNoVirtual() == GetArenaNoVirtual()) {
    1344           0 :     InternalSwap(other);
    1345             :   } else {
    1346           0 :     SwapFallback<TypeHandler>(other);
    1347             :   }
    1348             : }
    1349             : 
    1350             : template <typename TypeHandler>
    1351           0 : void RepeatedPtrFieldBase::SwapFallback(RepeatedPtrFieldBase* other) {
    1352             :   GOOGLE_DCHECK(other->GetArenaNoVirtual() != GetArenaNoVirtual());
    1353             : 
    1354             :   // Copy semantics in this case. We try to improve efficiency by placing the
    1355             :   // temporary on |other|'s arena so that messages are copied cross-arena only
    1356             :   // once, not twice.
    1357           0 :   RepeatedPtrFieldBase temp(other->GetArenaNoVirtual());
    1358           0 :   temp.MergeFrom<TypeHandler>(*this);
    1359           0 :   this->Clear<TypeHandler>();
    1360           0 :   this->MergeFrom<TypeHandler>(*other);
    1361           0 :   other->Clear<TypeHandler>();
    1362             :   other->InternalSwap(&temp);
    1363           0 :   temp.Destroy<TypeHandler>();  // Frees rep_ if `other` had no arena.
    1364           0 : }
    1365             : 
    1366             : inline bool RepeatedPtrFieldBase::empty() const {
    1367           0 :   return current_size_ == 0;
    1368             : }
    1369             : 
    1370          62 : inline int RepeatedPtrFieldBase::size() const {
    1371          62 :   return current_size_;
    1372             : }
    1373             : 
    1374             : template <typename TypeHandler>
    1375             : inline const typename TypeHandler::Type&
    1376          56 : RepeatedPtrFieldBase::Get(int index) const {
    1377          56 :   GOOGLE_DCHECK_GE(index, 0);
    1378          56 :   GOOGLE_DCHECK_LT(index, current_size_);
    1379       46038 :   return *cast<TypeHandler>(rep_->elements[index]);
    1380             : }
    1381             : 
    1382             : 
    1383             : template <typename TypeHandler>
    1384             : inline typename TypeHandler::Type*
    1385             : RepeatedPtrFieldBase::Mutable(int index) {
    1386             :   GOOGLE_DCHECK_GE(index, 0);
    1387             :   GOOGLE_DCHECK_LT(index, current_size_);
    1388          24 :   return cast<TypeHandler>(rep_->elements[index]);
    1389             : }
    1390             : 
    1391             : template <typename TypeHandler>
    1392             : inline void RepeatedPtrFieldBase::Delete(int index) {
    1393             :   GOOGLE_DCHECK_GE(index, 0);
    1394             :   GOOGLE_DCHECK_LT(index, current_size_);
    1395             :   TypeHandler::Delete(cast<TypeHandler>(rep_->elements[index]), arena_);
    1396             : }
    1397             : 
    1398             : template <typename TypeHandler>
    1399       44226 : inline typename TypeHandler::Type* RepeatedPtrFieldBase::Add(
    1400             :     typename TypeHandler::Type* prototype) {
    1401       44226 :   if (rep_ != NULL && current_size_ < rep_->allocated_size) {
    1402           0 :     return cast<TypeHandler>(rep_->elements[current_size_++]);
    1403             :   }
    1404       44226 :   if (!rep_ || rep_->allocated_size == total_size_) {
    1405        7689 :     Reserve(total_size_ + 1);
    1406             :   }
    1407       44226 :   ++rep_->allocated_size;
    1408             :   typename TypeHandler::Type* result =
    1409       44524 :       TypeHandler::NewFromPrototype(prototype, arena_);
    1410       44226 :   rep_->elements[current_size_++] = result;
    1411       44226 :   return result;
    1412             : }
    1413             : 
    1414             : template <typename TypeHandler>
    1415           0 : inline void RepeatedPtrFieldBase::RemoveLast() {
    1416             :   GOOGLE_DCHECK_GT(current_size_, 0);
    1417           0 :   TypeHandler::Clear(cast<TypeHandler>(rep_->elements[--current_size_]));
    1418           0 : }
    1419             : 
    1420             : template <typename TypeHandler>
    1421        2348 : void RepeatedPtrFieldBase::Clear() {
    1422        2348 :   const int n = current_size_;
    1423          18 :   GOOGLE_DCHECK_GE(n, 0);
    1424        2348 :   if (n > 0) {
    1425         679 :     void* const* elements = rep_->elements;
    1426         679 :     int i = 0;
    1427         841 :     do {
    1428         841 :       TypeHandler::Clear(cast<TypeHandler>(elements[i++]));
    1429             :     } while (i < n);
    1430         679 :     current_size_ = 0;
    1431             :   }
    1432        2348 : }
    1433             : 
    1434             : // To avoid unnecessary code duplication and reduce binary size, we use a
    1435             : // layered approach to implementing MergeFrom(). The toplevel method is
    1436             : // templated, so we get a small thunk per concrete message type in the binary.
    1437             : // This calls a shared implementation with most of the logic, passing a function
    1438             : // pointer to another type-specific piece of code that calls the object-allocate
    1439             : // and merge handlers.
    1440             : template <typename TypeHandler>
    1441       26415 : inline void RepeatedPtrFieldBase::MergeFrom(const RepeatedPtrFieldBase& other) {
    1442          24 :   GOOGLE_DCHECK_NE(&other, this);
    1443       52830 :   if (other.current_size_ == 0) return;
    1444         233 :   MergeFromInternal(
    1445             :       other, &RepeatedPtrFieldBase::MergeFromInnerLoop<TypeHandler>);
    1446             : }
    1447             : 
    1448         233 : inline void RepeatedPtrFieldBase::MergeFromInternal(
    1449             :     const RepeatedPtrFieldBase& other,
    1450             :     void (RepeatedPtrFieldBase::*inner_loop)(void**, void**, int, int)) {
    1451             :   // Note: wrapper has already guaranteed that other.rep_ != NULL here.
    1452         233 :   int other_size = other.current_size_;
    1453         233 :   void** other_elements = other.rep_->elements;
    1454         233 :   void** new_elements = InternalExtend(other_size);
    1455         233 :   int allocated_elems = rep_->allocated_size - current_size_;
    1456             :   (this->*inner_loop)(new_elements, other_elements,
    1457         233 :                       other_size, allocated_elems);
    1458         233 :   current_size_ += other_size;
    1459         233 :   if (rep_->allocated_size < current_size_) {
    1460         233 :     rep_->allocated_size = current_size_;
    1461             :   }
    1462         233 : }
    1463             : 
    1464             : // Merges other_elems to our_elems.
    1465             : template<typename TypeHandler>
    1466         233 : void RepeatedPtrFieldBase::MergeFromInnerLoop(
    1467         215 :     void** our_elems, void** other_elems, int length, int already_allocated) {
    1468             :   // Split into two loops, over ranges [0, allocated) and [allocated, length),
    1469             :   // to avoid a branch within the loop.
    1470         233 :   for (int i = 0; i < already_allocated && i < length; i++) {
    1471             :     // Already allocated: use existing element.
    1472             :     typename TypeHandler::Type* other_elem =
    1473           0 :         reinterpret_cast<typename TypeHandler::Type*>(other_elems[i]);
    1474             :     typename TypeHandler::Type* new_elem =
    1475           0 :         reinterpret_cast<typename TypeHandler::Type*>(our_elems[i]);
    1476           0 :     TypeHandler::Merge(*other_elem, new_elem);
    1477             :   }
    1478         233 :   Arena* arena = GetArenaNoVirtual();
    1479       26393 :   for (int i = already_allocated; i < length; i++) {
    1480             :     // Not allocated: alloc a new element first, then merge it.
    1481             :     typename TypeHandler::Type* other_elem =
    1482       26160 :         reinterpret_cast<typename TypeHandler::Type*>(other_elems[i]);
    1483             :     typename TypeHandler::Type* new_elem =
    1484       26308 :         TypeHandler::NewFromPrototype(other_elem, arena);
    1485       26012 :     TypeHandler::Merge(*other_elem, new_elem);
    1486       26160 :     our_elems[i] = new_elem;
    1487             :   }
    1488         233 : }
    1489             : 
    1490             : template <typename TypeHandler>
    1491             : inline void RepeatedPtrFieldBase::CopyFrom(const RepeatedPtrFieldBase& other) {
    1492             :   if (&other == this) return;
    1493             :   RepeatedPtrFieldBase::Clear<TypeHandler>();
    1494             :   RepeatedPtrFieldBase::MergeFrom<TypeHandler>(other);
    1495             : }
    1496             : 
    1497             : inline int RepeatedPtrFieldBase::Capacity() const {
    1498             :   return total_size_;
    1499             : }
    1500             : 
    1501             : inline void* const* RepeatedPtrFieldBase::raw_data() const {
    1502           0 :   return rep_ ? rep_->elements : NULL;
    1503             : }
    1504             : 
    1505             : inline void** RepeatedPtrFieldBase::raw_mutable_data() const {
    1506           0 :   return rep_ ? const_cast<void**>(rep_->elements) : NULL;
    1507             : }
    1508             : 
    1509             : template <typename TypeHandler>
    1510             : inline typename TypeHandler::Type** RepeatedPtrFieldBase::mutable_data() {
    1511             :   // TODO(kenton):  Breaks C++ aliasing rules.  We should probably remove this
    1512             :   //   method entirely.
    1513             :   return reinterpret_cast<typename TypeHandler::Type**>(raw_mutable_data());
    1514             : }
    1515             : 
    1516             : template <typename TypeHandler>
    1517             : inline const typename TypeHandler::Type* const*
    1518             : RepeatedPtrFieldBase::data() const {
    1519             :   // TODO(kenton):  Breaks C++ aliasing rules.  We should probably remove this
    1520             :   //   method entirely.
    1521             :   return reinterpret_cast<const typename TypeHandler::Type* const*>(raw_data());
    1522             : }
    1523             : 
    1524             : inline void RepeatedPtrFieldBase::SwapElements(int index1, int index2) {
    1525             :   using std::swap;  // enable ADL with fallback
    1526           0 :   swap(rep_->elements[index1], rep_->elements[index2]);
    1527             : }
    1528             : 
    1529             : template <typename TypeHandler>
    1530           0 : inline int RepeatedPtrFieldBase::SpaceUsedExcludingSelf() const {
    1531           0 :   int allocated_bytes = total_size_ * sizeof(void*);
    1532           0 :   if (rep_ != NULL) {
    1533           0 :     for (int i = 0; i < rep_->allocated_size; ++i) {
    1534           0 :       allocated_bytes += TypeHandler::SpaceUsed(
    1535           0 :           *cast<TypeHandler>(rep_->elements[i]));
    1536             :     }
    1537           0 :     allocated_bytes += kRepHeaderSize;
    1538             :   }
    1539           0 :   return allocated_bytes;
    1540             : }
    1541             : 
    1542             : template <typename TypeHandler>
    1543             : inline typename TypeHandler::Type* RepeatedPtrFieldBase::AddFromCleared() {
    1544         405 :   if (rep_ != NULL && current_size_ < rep_->allocated_size) {
    1545           0 :     return cast<TypeHandler>(rep_->elements[current_size_++]);
    1546             :   } else {
    1547             :     return NULL;
    1548             :   }
    1549             : }
    1550             : 
    1551             : // AddAllocated version that implements arena-safe copying behavior.
    1552             : template <typename TypeHandler>
    1553           0 : void RepeatedPtrFieldBase::AddAllocatedInternal(
    1554             :     typename TypeHandler::Type* value,
    1555           0 :     google::protobuf::internal::true_type) {
    1556             :   Arena* element_arena = reinterpret_cast<Arena*>(
    1557           0 :       TypeHandler::GetMaybeArenaPointer(value));
    1558           0 :   Arena* arena = GetArenaNoVirtual();
    1559           0 :   if (arena == element_arena && rep_ &&
    1560             :       rep_->allocated_size < total_size_) {
    1561             :     // Fast path: underlying arena representation (tagged pointer) is equal to
    1562             :     // our arena pointer, and we can add to array without resizing it (at least
    1563             :     // one slot that is not allocated).
    1564           0 :     void** elems = rep_->elements;
    1565           0 :     if (current_size_ < rep_->allocated_size) {
    1566             :       // Make space at [current] by moving first allocated element to end of
    1567             :       // allocated list.
    1568           0 :       elems[rep_->allocated_size] = elems[current_size_];
    1569             :     }
    1570           0 :     elems[current_size_] = value;
    1571           0 :     current_size_ = current_size_ + 1;
    1572           0 :     rep_->allocated_size = rep_->allocated_size + 1;
    1573           0 :     return;
    1574             :   } else {
    1575           0 :     AddAllocatedSlowWithCopy<TypeHandler>(
    1576           0 :         value, TypeHandler::GetArena(value), arena);
    1577             :   }
    1578             : }
    1579             : 
    1580             : // Slowpath handles all cases, copying if necessary.
    1581             : template<typename TypeHandler>
    1582           0 : void RepeatedPtrFieldBase::AddAllocatedSlowWithCopy(
    1583             :     // Pass value_arena and my_arena to avoid duplicate virtual call (value) or
    1584             :     // load (mine).
    1585             :     typename TypeHandler::Type* value, Arena* value_arena, Arena* my_arena) {
    1586             :   // Ensure that either the value is in the same arena, or if not, we do the
    1587             :   // appropriate thing: Own() it (if it's on heap and we're in an arena) or copy
    1588             :   // it to our arena/heap (otherwise).
    1589           0 :   if (my_arena != NULL && value_arena == NULL) {
    1590           0 :     my_arena->Own(value);
    1591           0 :   } else if (my_arena != value_arena) {
    1592             :     typename TypeHandler::Type* new_value =
    1593           0 :         TypeHandler::NewFromPrototype(value, my_arena);
    1594           0 :     TypeHandler::Merge(*value, new_value);
    1595           0 :     TypeHandler::Delete(value, value_arena);
    1596           0 :     value = new_value;
    1597             :   }
    1598             : 
    1599           0 :   UnsafeArenaAddAllocated<TypeHandler>(value);
    1600           0 : }
    1601             : 
    1602             : // AddAllocated version that does not implement arena-safe copying behavior.
    1603             : template <typename TypeHandler>
    1604           0 : void RepeatedPtrFieldBase::AddAllocatedInternal(
    1605             :     typename TypeHandler::Type* value,
    1606             :     google::protobuf::internal::false_type) {
    1607           0 :   if (rep_ &&  rep_->allocated_size < total_size_) {
    1608             :     // Fast path: underlying arena representation (tagged pointer) is equal to
    1609             :     // our arena pointer, and we can add to array without resizing it (at least
    1610             :     // one slot that is not allocated).
    1611           0 :     void** elems = rep_->elements;
    1612           0 :     if (current_size_ < rep_->allocated_size) {
    1613             :       // Make space at [current] by moving first allocated element to end of
    1614             :       // allocated list.
    1615           0 :       elems[rep_->allocated_size] = elems[current_size_];
    1616             :     }
    1617           0 :     elems[current_size_] = value;
    1618           0 :     current_size_ = current_size_ + 1;
    1619           0 :     ++rep_->allocated_size;
    1620           0 :     return;
    1621             :   } else {
    1622           0 :     UnsafeArenaAddAllocated<TypeHandler>(value);
    1623             :   }
    1624             : }
    1625             : 
    1626             : template <typename TypeHandler>
    1627         405 : void RepeatedPtrFieldBase::UnsafeArenaAddAllocated(
    1628             :     typename TypeHandler::Type* value) {
    1629             :   // Make room for the new pointer.
    1630         405 :   if (!rep_ || current_size_ == total_size_) {
    1631             :     // The array is completely full with no cleared objects, so grow it.
    1632         296 :     Reserve(total_size_ + 1);
    1633         296 :     ++rep_->allocated_size;
    1634         109 :   } else if (rep_->allocated_size == total_size_) {
    1635             :     // There is no more space in the pointer array because it contains some
    1636             :     // cleared objects awaiting reuse.  We don't want to grow the array in this
    1637             :     // case because otherwise a loop calling AddAllocated() followed by Clear()
    1638             :     // would leak memory.
    1639           0 :     TypeHandler::Delete(
    1640           0 :         cast<TypeHandler>(rep_->elements[current_size_]), arena_);
    1641         109 :   } else if (current_size_ < rep_->allocated_size) {
    1642             :     // We have some cleared objects.  We don't care about their order, so we
    1643             :     // can just move the first one to the end to make space.
    1644           0 :     rep_->elements[rep_->allocated_size] = rep_->elements[current_size_];
    1645           0 :     ++rep_->allocated_size;
    1646             :   } else {
    1647             :     // There are no cleared objects.
    1648         109 :     ++rep_->allocated_size;
    1649             :   }
    1650             : 
    1651         405 :   rep_->elements[current_size_++] = value;
    1652         405 : }
    1653             : 
    1654             : // ReleaseLast() for types that implement merge/copy behavior.
    1655             : template <typename TypeHandler>
    1656             : inline typename TypeHandler::Type*
    1657           0 : RepeatedPtrFieldBase::ReleaseLastInternal(google::protobuf::internal::true_type) {
    1658             :   // First, release an element.
    1659           0 :   typename TypeHandler::Type* result = UnsafeArenaReleaseLast<TypeHandler>();
    1660             :   // Now perform a copy if we're on an arena.
    1661           0 :   Arena* arena = GetArenaNoVirtual();
    1662           0 :   if (arena == NULL) {
    1663             :     return result;
    1664             :   } else {
    1665             :     typename TypeHandler::Type* new_result =
    1666           0 :         TypeHandler::NewFromPrototype(result, NULL);
    1667           0 :     TypeHandler::Merge(*result, new_result);
    1668             :     return new_result;
    1669             :   }
    1670             : }
    1671             : 
    1672             : // ReleaseLast() for types that *do not* implement merge/copy behavior -- this
    1673             : // is the same as UnsafeArenaReleaseLast(). Note that we GOOGLE_DCHECK-fail if we're on
    1674             : // an arena, since the user really should implement the copy operation in this
    1675             : // case.
    1676             : template <typename TypeHandler>
    1677             : inline typename TypeHandler::Type*
    1678           0 : RepeatedPtrFieldBase::ReleaseLastInternal(google::protobuf::internal::false_type) {
    1679             :   GOOGLE_DCHECK(GetArenaNoVirtual() == NULL)
    1680             :       << "ReleaseLast() called on a RepeatedPtrField that is on an arena, "
    1681             :       << "with a type that does not implement MergeFrom. This is unsafe; "
    1682             :       << "please implement MergeFrom for your type.";
    1683           0 :   return UnsafeArenaReleaseLast<TypeHandler>();
    1684             : }
    1685             : 
    1686             : template <typename TypeHandler>
    1687             : inline typename TypeHandler::Type*
    1688             :   RepeatedPtrFieldBase::UnsafeArenaReleaseLast() {
    1689             :   GOOGLE_DCHECK_GT(current_size_, 0);
    1690             :   typename TypeHandler::Type* result =
    1691           0 :       cast<TypeHandler>(rep_->elements[--current_size_]);
    1692           0 :   --rep_->allocated_size;
    1693           0 :   if (current_size_ < rep_->allocated_size) {
    1694             :     // There are cleared elements on the end; replace the removed element
    1695             :     // with the last allocated element.
    1696           0 :     rep_->elements[current_size_] = rep_->elements[rep_->allocated_size];
    1697             :   }
    1698             :   return result;
    1699             : }
    1700             : 
    1701             : inline int RepeatedPtrFieldBase::ClearedCount() const {
    1702             :   return rep_ ? (rep_->allocated_size - current_size_) : 0;
    1703             : }
    1704             : 
    1705             : template <typename TypeHandler>
    1706             : inline void RepeatedPtrFieldBase::AddCleared(
    1707             :     typename TypeHandler::Type* value) {
    1708             :   GOOGLE_DCHECK(GetArenaNoVirtual() == NULL)
    1709             :       << "AddCleared() can only be used on a RepeatedPtrField not on an arena.";
    1710             :   GOOGLE_DCHECK(TypeHandler::GetArena(value) == NULL)
    1711             :       << "AddCleared() can only accept values not on an arena.";
    1712             :   if (!rep_ || rep_->allocated_size == total_size_) {
    1713             :     Reserve(total_size_ + 1);
    1714             :   }
    1715             :   rep_->elements[rep_->allocated_size++] = value;
    1716             : }
    1717             : 
    1718             : template <typename TypeHandler>
    1719             : inline typename TypeHandler::Type* RepeatedPtrFieldBase::ReleaseCleared() {
    1720             :   GOOGLE_DCHECK(GetArenaNoVirtual() == NULL)
    1721             :       << "ReleaseCleared() can only be used on a RepeatedPtrField not on "
    1722             :       << "an arena.";
    1723             :   GOOGLE_DCHECK(GetArenaNoVirtual() == NULL);
    1724             :   GOOGLE_DCHECK(rep_ != NULL);
    1725             :   GOOGLE_DCHECK_GT(rep_->allocated_size, current_size_);
    1726             :   return cast<TypeHandler>(rep_->elements[--rep_->allocated_size]);
    1727             : }
    1728             : 
    1729             : }  // namespace internal
    1730             : 
    1731             : // -------------------------------------------------------------------
    1732             : 
    1733             : template <typename Element>
    1734             : class RepeatedPtrField<Element>::TypeHandler
    1735             :     : public internal::GenericTypeHandler<Element> {
    1736             : };
    1737             : 
    1738             : template <>
    1739             : class RepeatedPtrField<string>::TypeHandler
    1740             :     : public internal::StringTypeHandler {
    1741             : };
    1742             : 
    1743             : 
    1744             : template <typename Element>
    1745          67 : inline RepeatedPtrField<Element>::RepeatedPtrField()
    1746       78779 :   : RepeatedPtrFieldBase() {}
    1747             : 
    1748             : template <typename Element>
    1749           0 : inline RepeatedPtrField<Element>::RepeatedPtrField(::google::protobuf::Arena* arena) :
    1750           0 :   RepeatedPtrFieldBase(arena) {}
    1751             : 
    1752             : template <typename Element>
    1753             : inline RepeatedPtrField<Element>::RepeatedPtrField(
    1754             :     const RepeatedPtrField& other)
    1755             :   : RepeatedPtrFieldBase() {
    1756             :   CopyFrom(other);
    1757             : }
    1758             : 
    1759             : template <typename Element>
    1760             : template <typename Iter>
    1761             : inline RepeatedPtrField<Element>::RepeatedPtrField(
    1762             :     Iter begin, const Iter& end) {
    1763             :   int reserve = internal::CalculateReserve(begin, end);
    1764             :   if (reserve != -1) {
    1765             :     Reserve(reserve);
    1766             :   }
    1767             :   for (; begin != end; ++begin) {
    1768             :     *Add() = *begin;
    1769             :   }
    1770             : }
    1771             : 
    1772             : template <typename Element>
    1773          56 : RepeatedPtrField<Element>::~RepeatedPtrField() {
    1774       77390 :   Destroy<TypeHandler>();
    1775       77388 : }
    1776             : 
    1777             : template <typename Element>
    1778             : inline RepeatedPtrField<Element>& RepeatedPtrField<Element>::operator=(
    1779             :     const RepeatedPtrField& other) {
    1780             :   if (this != &other)
    1781             :     CopyFrom(other);
    1782             :   return *this;
    1783             : }
    1784             : 
    1785             : template <typename Element>
    1786             : inline bool RepeatedPtrField<Element>::empty() const {
    1787           0 :   return RepeatedPtrFieldBase::empty();
    1788             : }
    1789             : 
    1790             : template <typename Element>
    1791          62 : inline int RepeatedPtrField<Element>::size() const {
    1792       72207 :   return RepeatedPtrFieldBase::size();
    1793             : }
    1794             : 
    1795             : template <typename Element>
    1796          56 : inline const Element& RepeatedPtrField<Element>::Get(int index) const {
    1797       45502 :   return RepeatedPtrFieldBase::Get<TypeHandler>(index);
    1798             : }
    1799             : 
    1800             : 
    1801             : template <typename Element>
    1802             : inline Element* RepeatedPtrField<Element>::Mutable(int index) {
    1803          24 :   return RepeatedPtrFieldBase::Mutable<TypeHandler>(index);
    1804             : }
    1805             : 
    1806             : template <typename Element>
    1807          12 : inline Element* RepeatedPtrField<Element>::Add() {
    1808       44226 :   return RepeatedPtrFieldBase::Add<TypeHandler>();
    1809             : }
    1810             : 
    1811             : template <typename Element>
    1812             : inline void RepeatedPtrField<Element>::RemoveLast() {
    1813           0 :   RepeatedPtrFieldBase::RemoveLast<TypeHandler>();
    1814             : }
    1815             : 
    1816             : template <typename Element>
    1817             : inline void RepeatedPtrField<Element>::DeleteSubrange(int start, int num) {
    1818             :   GOOGLE_DCHECK_GE(start, 0);
    1819             :   GOOGLE_DCHECK_GE(num, 0);
    1820             :   GOOGLE_DCHECK_LE(start + num, size());
    1821             :   for (int i = 0; i < num; ++i) {
    1822             :     RepeatedPtrFieldBase::Delete<TypeHandler>(start + i);
    1823             :   }
    1824             :   ExtractSubrange(start, num, NULL);
    1825             : }
    1826             : 
    1827             : template <typename Element>
    1828             : inline void RepeatedPtrField<Element>::ExtractSubrange(
    1829             :     int start, int num, Element** elements) {
    1830             :   typename internal::TypeImplementsMergeBehavior<
    1831             :       typename TypeHandler::Type>::type t;
    1832             :   ExtractSubrangeInternal(start, num, elements, t);
    1833             : }
    1834             : 
    1835             : // ExtractSubrange() implementation for types that implement merge/copy
    1836             : // behavior.
    1837             : template <typename Element>
    1838             : inline void RepeatedPtrField<Element>::ExtractSubrangeInternal(
    1839             :     int start, int num, Element** elements, google::protobuf::internal::true_type) {
    1840             :   GOOGLE_DCHECK_GE(start, 0);
    1841             :   GOOGLE_DCHECK_GE(num, 0);
    1842             :   GOOGLE_DCHECK_LE(start + num, size());
    1843             : 
    1844             :   if (num > 0) {
    1845             :     // Save the values of the removed elements if requested.
    1846             :     if (elements != NULL) {
    1847             :       if (GetArenaNoVirtual() != NULL) {
    1848             :         // If we're on an arena, we perform a copy for each element so that the
    1849             :         // returned elements are heap-allocated.
    1850             :         for (int i = 0; i < num; ++i) {
    1851             :           Element* element = RepeatedPtrFieldBase::
    1852             :               Mutable<TypeHandler>(i + start);
    1853             :           typename TypeHandler::Type* new_value =
    1854             :               TypeHandler::NewFromPrototype(element, NULL);
    1855             :           TypeHandler::Merge(*element, new_value);
    1856             :           elements[i] = new_value;
    1857             :         }
    1858             :       } else {
    1859             :         for (int i = 0; i < num; ++i) {
    1860             :           elements[i] = RepeatedPtrFieldBase::Mutable<TypeHandler>(i + start);
    1861             :         }
    1862             :       }
    1863             :     }
    1864             :     CloseGap(start, num);
    1865             :   }
    1866             : }
    1867             : 
    1868             : // ExtractSubrange() implementation for types that do not implement merge/copy
    1869             : // behavior.
    1870             : template<typename Element>
    1871             : inline void RepeatedPtrField<Element>::ExtractSubrangeInternal(
    1872             :     int start, int num, Element** elements, google::protobuf::internal::false_type) {
    1873             :   // This case is identical to UnsafeArenaExtractSubrange(). However, since
    1874             :   // ExtractSubrange() must return heap-allocated objects by contract, and we
    1875             :   // cannot fulfill this contract if we are an on arena, we must GOOGLE_DCHECK() that
    1876             :   // we are not on an arena.
    1877             :   GOOGLE_DCHECK(GetArenaNoVirtual() == NULL)
    1878             :       << "ExtractSubrange() when arena is non-NULL is only supported when "
    1879             :       << "the Element type supplies a MergeFrom() operation to make copies.";
    1880             :   UnsafeArenaExtractSubrange(start, num, elements);
    1881             : }
    1882             : 
    1883             : template <typename Element>
    1884             : inline void RepeatedPtrField<Element>::UnsafeArenaExtractSubrange(
    1885             :     int start, int num, Element** elements) {
    1886             :   GOOGLE_DCHECK_GE(start, 0);
    1887             :   GOOGLE_DCHECK_GE(num, 0);
    1888             :   GOOGLE_DCHECK_LE(start + num, size());
    1889             : 
    1890             :   if (num > 0) {
    1891             :     // Save the values of the removed elements if requested.
    1892             :     if (elements != NULL) {
    1893             :       for (int i = 0; i < num; ++i) {
    1894             :         elements[i] = RepeatedPtrFieldBase::Mutable<TypeHandler>(i + start);
    1895             :       }
    1896             :     }
    1897             :     CloseGap(start, num);
    1898             :   }
    1899             : }
    1900             : 
    1901             : template <typename Element>
    1902          18 : inline void RepeatedPtrField<Element>::Clear() {
    1903        2074 :   RepeatedPtrFieldBase::Clear<TypeHandler>();
    1904          18 : }
    1905             : 
    1906             : template <typename Element>
    1907          24 : inline void RepeatedPtrField<Element>::MergeFrom(
    1908             :     const RepeatedPtrField& other) {
    1909       26415 :   RepeatedPtrFieldBase::MergeFrom<TypeHandler>(other);
    1910          24 : }
    1911             : 
    1912             : template <typename Element>
    1913             : inline void RepeatedPtrField<Element>::CopyFrom(
    1914             :     const RepeatedPtrField& other) {
    1915             :   RepeatedPtrFieldBase::CopyFrom<TypeHandler>(other);
    1916             : }
    1917             : 
    1918             : template <typename Element>
    1919             : inline typename RepeatedPtrField<Element>::iterator
    1920             : RepeatedPtrField<Element>::erase(const_iterator position) {
    1921             :   return erase(position, position + 1);
    1922             : }
    1923             : 
    1924             : template <typename Element>
    1925             : inline typename RepeatedPtrField<Element>::iterator
    1926             : RepeatedPtrField<Element>::erase(const_iterator first, const_iterator last) {
    1927             :   size_type pos_offset = std::distance(cbegin(), first);
    1928             :   size_type last_offset = std::distance(cbegin(), last);
    1929             :   DeleteSubrange(pos_offset, last_offset - pos_offset);
    1930             :   return begin() + pos_offset;
    1931             : }
    1932             : 
    1933             : template <typename Element>
    1934             : inline Element** RepeatedPtrField<Element>::mutable_data() {
    1935             :   return RepeatedPtrFieldBase::mutable_data<TypeHandler>();
    1936             : }
    1937             : 
    1938             : template <typename Element>
    1939             : inline const Element* const* RepeatedPtrField<Element>::data() const {
    1940             :   return RepeatedPtrFieldBase::data<TypeHandler>();
    1941             : }
    1942             : 
    1943             : template <typename Element>
    1944           0 : inline void RepeatedPtrField<Element>::Swap(RepeatedPtrField* other) {
    1945           0 :   if (this == other)
    1946           0 :     return;
    1947           0 :   RepeatedPtrFieldBase::Swap<TypeHandler>(other);
    1948             : }
    1949             : 
    1950             : template <typename Element>
    1951           0 : inline void RepeatedPtrField<Element>::UnsafeArenaSwap(
    1952             :     RepeatedPtrField* other) {
    1953           0 :   GOOGLE_DCHECK(GetArenaNoVirtual() == other->GetArenaNoVirtual());
    1954          78 :   if (this == other)
    1955           0 :       return;
    1956          78 :   RepeatedPtrFieldBase::InternalSwap(other);
    1957             : }
    1958             : 
    1959             : template <typename Element>
    1960             : inline void RepeatedPtrField<Element>::SwapElements(int index1, int index2) {
    1961           0 :   RepeatedPtrFieldBase::SwapElements(index1, index2);
    1962             : }
    1963             : 
    1964             : template <typename Element>
    1965           0 : inline Arena* RepeatedPtrField<Element>::GetArenaNoVirtual() const {
    1966           0 :   return RepeatedPtrFieldBase::GetArenaNoVirtual();
    1967             : }
    1968             : 
    1969             : template <typename Element>
    1970             : inline int RepeatedPtrField<Element>::SpaceUsedExcludingSelf() const {
    1971           0 :   return RepeatedPtrFieldBase::SpaceUsedExcludingSelf<TypeHandler>();
    1972             : }
    1973             : 
    1974             : template <typename Element>
    1975             : inline void RepeatedPtrField<Element>::AddAllocated(Element* value) {
    1976           0 :   RepeatedPtrFieldBase::AddAllocated<TypeHandler>(value);
    1977             : }
    1978             : 
    1979             : template <typename Element>
    1980             : inline void RepeatedPtrField<Element>::UnsafeArenaAddAllocated(Element* value) {
    1981             :   RepeatedPtrFieldBase::UnsafeArenaAddAllocated<TypeHandler>(value);
    1982             : }
    1983             : 
    1984             : template <typename Element>
    1985             : inline Element* RepeatedPtrField<Element>::ReleaseLast() {
    1986           0 :   return RepeatedPtrFieldBase::ReleaseLast<TypeHandler>();
    1987             : }
    1988             : 
    1989             : template <typename Element>
    1990             : inline Element* RepeatedPtrField<Element>::UnsafeArenaReleaseLast() {
    1991             :   return RepeatedPtrFieldBase::UnsafeArenaReleaseLast<TypeHandler>();
    1992             : }
    1993             : 
    1994             : template <typename Element>
    1995             : inline int RepeatedPtrField<Element>::ClearedCount() const {
    1996             :   return RepeatedPtrFieldBase::ClearedCount();
    1997             : }
    1998             : 
    1999             : template <typename Element>
    2000             : inline void RepeatedPtrField<Element>::AddCleared(Element* value) {
    2001             :   return RepeatedPtrFieldBase::AddCleared<TypeHandler>(value);
    2002             : }
    2003             : 
    2004             : template <typename Element>
    2005             : inline Element* RepeatedPtrField<Element>::ReleaseCleared() {
    2006             :   return RepeatedPtrFieldBase::ReleaseCleared<TypeHandler>();
    2007             : }
    2008             : 
    2009             : template <typename Element>
    2010             : inline void RepeatedPtrField<Element>::Reserve(int new_size) {
    2011             :   return RepeatedPtrFieldBase::Reserve(new_size);
    2012             : }
    2013             : 
    2014             : template <typename Element>
    2015             : inline int RepeatedPtrField<Element>::Capacity() const {
    2016             :   return RepeatedPtrFieldBase::Capacity();
    2017             : }
    2018             : 
    2019             : // -------------------------------------------------------------------
    2020             : 
    2021             : namespace internal {
    2022             : 
    2023             : // STL-like iterator implementation for RepeatedPtrField.  You should not
    2024             : // refer to this class directly; use RepeatedPtrField<T>::iterator instead.
    2025             : //
    2026             : // The iterator for RepeatedPtrField<T>, RepeatedPtrIterator<T>, is
    2027             : // very similar to iterator_ptr<T**> in util/gtl/iterator_adaptors.h,
    2028             : // but adds random-access operators and is modified to wrap a void** base
    2029             : // iterator (since RepeatedPtrField stores its array as a void* array and
    2030             : // casting void** to T** would violate C++ aliasing rules).
    2031             : //
    2032             : // This code based on net/proto/proto-array-internal.h by Jeffrey Yasskin
    2033             : // (jyasskin@google.com).
    2034             : template<typename Element>
    2035             : class RepeatedPtrIterator
    2036             :     : public std::iterator<
    2037             :           std::random_access_iterator_tag, Element> {
    2038             :  public:
    2039             :   typedef RepeatedPtrIterator<Element> iterator;
    2040             :   typedef std::iterator<
    2041             :           std::random_access_iterator_tag, Element> superclass;
    2042             : 
    2043             :   // Shadow the value_type in std::iterator<> because const_iterator::value_type
    2044             :   // needs to be T, not const T.
    2045             :   typedef typename remove_const<Element>::type value_type;
    2046             : 
    2047             :   // Let the compiler know that these are type names, so we don't have to
    2048             :   // write "typename" in front of them everywhere.
    2049             :   typedef typename superclass::reference reference;
    2050             :   typedef typename superclass::pointer pointer;
    2051             :   typedef typename superclass::difference_type difference_type;
    2052             : 
    2053             :   RepeatedPtrIterator() : it_(NULL) {}
    2054             :   explicit RepeatedPtrIterator(void* const* it) : it_(it) {}
    2055             : 
    2056             :   // Allow "upcasting" from RepeatedPtrIterator<T**> to
    2057             :   // RepeatedPtrIterator<const T*const*>.
    2058             :   template<typename OtherElement>
    2059             :   RepeatedPtrIterator(const RepeatedPtrIterator<OtherElement>& other)
    2060             :       : it_(other.it_) {
    2061             :     // Force a compiler error if the other type is not convertible to ours.
    2062             :     if (false) {
    2063             :       implicit_cast<Element*, OtherElement*>(0);
    2064             :     }
    2065             :   }
    2066             : 
    2067             :   // dereferenceable
    2068           0 :   reference operator*() const { return *reinterpret_cast<Element*>(*it_); }
    2069             :   pointer   operator->() const { return &(operator*()); }
    2070             : 
    2071             :   // {inc,dec}rementable
    2072           0 :   iterator& operator++() { ++it_; return *this; }
    2073             :   iterator  operator++(int) { return iterator(it_++); }
    2074             :   iterator& operator--() { --it_; return *this; }
    2075             :   iterator  operator--(int) { return iterator(it_--); }
    2076             : 
    2077             :   // equality_comparable
    2078             :   bool operator==(const iterator& x) const { return it_ == x.it_; }
    2079           0 :   bool operator!=(const iterator& x) const { return it_ != x.it_; }
    2080             : 
    2081             :   // less_than_comparable
    2082             :   bool operator<(const iterator& x) const { return it_ < x.it_; }
    2083             :   bool operator<=(const iterator& x) const { return it_ <= x.it_; }
    2084             :   bool operator>(const iterator& x) const { return it_ > x.it_; }
    2085             :   bool operator>=(const iterator& x) const { return it_ >= x.it_; }
    2086             : 
    2087             :   // addable, subtractable
    2088             :   iterator& operator+=(difference_type d) {
    2089           0 :     it_ += d;
    2090             :     return *this;
    2091             :   }
    2092             :   friend iterator operator+(iterator it, const difference_type d) {
    2093             :     it += d;
    2094             :     return it;
    2095             :   }
    2096             :   friend iterator operator+(const difference_type d, iterator it) {
    2097             :     it += d;
    2098             :     return it;
    2099             :   }
    2100             :   iterator& operator-=(difference_type d) {
    2101             :     it_ -= d;
    2102             :     return *this;
    2103             :   }
    2104             :   friend iterator operator-(iterator it, difference_type d) {
    2105             :     it -= d;
    2106             :     return it;
    2107             :   }
    2108             : 
    2109             :   // indexable
    2110             :   reference operator[](difference_type d) const { return *(*this + d); }
    2111             : 
    2112             :   // random access iterator
    2113           0 :   difference_type operator-(const iterator& x) const { return it_ - x.it_; }
    2114             : 
    2115             :  private:
    2116             :   template<typename OtherElement>
    2117             :   friend class RepeatedPtrIterator;
    2118             : 
    2119             :   // The internal iterator.
    2120             :   void* const* it_;
    2121             : };
    2122             : 
    2123             : // Provide an iterator that operates on pointers to the underlying objects
    2124             : // rather than the objects themselves as RepeatedPtrIterator does.
    2125             : // Consider using this when working with stl algorithms that change
    2126             : // the array.
    2127             : // The VoidPtr template parameter holds the type-agnostic pointer value
    2128             : // referenced by the iterator.  It should either be "void *" for a mutable
    2129             : // iterator, or "const void *" for a constant iterator.
    2130             : template<typename Element, typename VoidPtr>
    2131             : class RepeatedPtrOverPtrsIterator
    2132             :     : public std::iterator<std::random_access_iterator_tag, Element*> {
    2133             :  public:
    2134             :   typedef RepeatedPtrOverPtrsIterator<Element, VoidPtr> iterator;
    2135             :   typedef std::iterator<
    2136             :           std::random_access_iterator_tag, Element*> superclass;
    2137             : 
    2138             :   // Shadow the value_type in std::iterator<> because const_iterator::value_type
    2139             :   // needs to be T, not const T.
    2140             :   typedef typename remove_const<Element*>::type value_type;
    2141             : 
    2142             :   // Let the compiler know that these are type names, so we don't have to
    2143             :   // write "typename" in front of them everywhere.
    2144             :   typedef typename superclass::reference reference;
    2145             :   typedef typename superclass::pointer pointer;
    2146             :   typedef typename superclass::difference_type difference_type;
    2147             : 
    2148             :   RepeatedPtrOverPtrsIterator() : it_(NULL) {}
    2149             :   explicit RepeatedPtrOverPtrsIterator(VoidPtr* it) : it_(it) {}
    2150             : 
    2151             :   // dereferenceable
    2152             :   reference operator*() const { return *reinterpret_cast<Element**>(it_); }
    2153             :   pointer   operator->() const { return &(operator*()); }
    2154             : 
    2155             :   // {inc,dec}rementable
    2156           0 :   iterator& operator++() { ++it_; return *this; }
    2157             :   iterator  operator++(int) { return iterator(it_++); }
    2158             :   iterator& operator--() { --it_; return *this; }
    2159             :   iterator  operator--(int) { return iterator(it_--); }
    2160             : 
    2161             :   // equality_comparable
    2162             :   bool operator==(const iterator& x) const { return it_ == x.it_; }
    2163             :   bool operator!=(const iterator& x) const { return it_ != x.it_; }
    2164             : 
    2165             :   // less_than_comparable
    2166             :   bool operator<(const iterator& x) const { return it_ < x.it_; }
    2167             :   bool operator<=(const iterator& x) const { return it_ <= x.it_; }
    2168             :   bool operator>(const iterator& x) const { return it_ > x.it_; }
    2169             :   bool operator>=(const iterator& x) const { return it_ >= x.it_; }
    2170             : 
    2171             :   // addable, subtractable
    2172             :   iterator& operator+=(difference_type d) {
    2173             :     it_ += d;
    2174             :     return *this;
    2175             :   }
    2176             :   friend iterator operator+(iterator it, difference_type d) {
    2177             :     it += d;
    2178             :     return it;
    2179             :   }
    2180             :   friend iterator operator+(difference_type d, iterator it) {
    2181             :     it += d;
    2182             :     return it;
    2183             :   }
    2184             :   iterator& operator-=(difference_type d) {
    2185             :     it_ -= d;
    2186             :     return *this;
    2187             :   }
    2188             :   friend iterator operator-(iterator it, difference_type d) {
    2189             :     it -= d;
    2190             :     return it;
    2191             :   }
    2192             : 
    2193             :   // indexable
    2194             :   reference operator[](difference_type d) const { return *(*this + d); }
    2195             : 
    2196             :   // random access iterator
    2197             :   difference_type operator-(const iterator& x) const { return it_ - x.it_; }
    2198             : 
    2199             :  private:
    2200             :   template<typename OtherElement>
    2201             :   friend class RepeatedPtrIterator;
    2202             : 
    2203             :   // The internal iterator.
    2204             :   VoidPtr* it_;
    2205             : };
    2206             : 
    2207           0 : void RepeatedPtrFieldBase::InternalSwap(RepeatedPtrFieldBase* other) {
    2208          78 :   std::swap(rep_, other->rep_);
    2209          78 :   std::swap(current_size_, other->current_size_);
    2210          78 :   std::swap(total_size_, other->total_size_);
    2211           0 : }
    2212             : 
    2213             : }  // namespace internal
    2214             : 
    2215             : template <typename Element>
    2216             : inline typename RepeatedPtrField<Element>::iterator
    2217             : RepeatedPtrField<Element>::begin() {
    2218           0 :   return iterator(raw_data());
    2219             : }
    2220             : template <typename Element>
    2221             : inline typename RepeatedPtrField<Element>::const_iterator
    2222             : RepeatedPtrField<Element>::begin() const {
    2223           0 :   return iterator(raw_data());
    2224             : }
    2225             : template <typename Element>
    2226             : inline typename RepeatedPtrField<Element>::const_iterator
    2227             : RepeatedPtrField<Element>::cbegin() const {
    2228             :   return begin();
    2229             : }
    2230             : template <typename Element>
    2231             : inline typename RepeatedPtrField<Element>::iterator
    2232             : RepeatedPtrField<Element>::end() {
    2233           0 :   return iterator(raw_data() + size());
    2234             : }
    2235             : template <typename Element>
    2236             : inline typename RepeatedPtrField<Element>::const_iterator
    2237             : RepeatedPtrField<Element>::end() const {
    2238           0 :   return iterator(raw_data() + size());
    2239             : }
    2240             : template <typename Element>
    2241             : inline typename RepeatedPtrField<Element>::const_iterator
    2242             : RepeatedPtrField<Element>::cend() const {
    2243             :   return end();
    2244             : }
    2245             : 
    2246             : template <typename Element>
    2247             : inline typename RepeatedPtrField<Element>::pointer_iterator
    2248             : RepeatedPtrField<Element>::pointer_begin() {
    2249             :   return pointer_iterator(raw_mutable_data());
    2250             : }
    2251             : template <typename Element>
    2252             : inline typename RepeatedPtrField<Element>::const_pointer_iterator
    2253             : RepeatedPtrField<Element>::pointer_begin() const {
    2254           0 :   return const_pointer_iterator(const_cast<const void**>(raw_mutable_data()));
    2255             : }
    2256             : template <typename Element>
    2257             : inline typename RepeatedPtrField<Element>::pointer_iterator
    2258             : RepeatedPtrField<Element>::pointer_end() {
    2259             :   return pointer_iterator(raw_mutable_data() + size());
    2260             : }
    2261             : template <typename Element>
    2262             : inline typename RepeatedPtrField<Element>::const_pointer_iterator
    2263             : RepeatedPtrField<Element>::pointer_end() const {
    2264             :   return const_pointer_iterator(
    2265           0 :       const_cast<const void**>(raw_mutable_data() + size()));
    2266             : }
    2267             : 
    2268             : 
    2269             : // Iterators and helper functions that follow the spirit of the STL
    2270             : // std::back_insert_iterator and std::back_inserter but are tailor-made
    2271             : // for RepeatedField and RepeatedPtrField. Typical usage would be:
    2272             : //
    2273             : //   std::copy(some_sequence.begin(), some_sequence.end(),
    2274             : //             google::protobuf::RepeatedFieldBackInserter(proto.mutable_sequence()));
    2275             : //
    2276             : // Ported by johannes from util/gtl/proto-array-iterators.h
    2277             : 
    2278             : namespace internal {
    2279             : // A back inserter for RepeatedField objects.
    2280             : template<typename T> class RepeatedFieldBackInsertIterator
    2281             :     : public std::iterator<std::output_iterator_tag, T> {
    2282             :  public:
    2283             :   explicit RepeatedFieldBackInsertIterator(
    2284             :       RepeatedField<T>* const mutable_field)
    2285             :       : field_(mutable_field) {
    2286             :   }
    2287             :   RepeatedFieldBackInsertIterator<T>& operator=(const T& value) {
    2288             :     field_->Add(value);
    2289             :     return *this;
    2290             :   }
    2291             :   RepeatedFieldBackInsertIterator<T>& operator*() {
    2292             :     return *this;
    2293             :   }
    2294             :   RepeatedFieldBackInsertIterator<T>& operator++() {
    2295             :     return *this;
    2296             :   }
    2297             :   RepeatedFieldBackInsertIterator<T>& operator++(int /* unused */) {
    2298             :     return *this;
    2299             :   }
    2300             : 
    2301             :  private:
    2302             :   RepeatedField<T>* field_;
    2303             : };
    2304             : 
    2305             : // A back inserter for RepeatedPtrField objects.
    2306             : template<typename T> class RepeatedPtrFieldBackInsertIterator
    2307             :     : public std::iterator<std::output_iterator_tag, T> {
    2308             :  public:
    2309             :   RepeatedPtrFieldBackInsertIterator(
    2310             :       RepeatedPtrField<T>* const mutable_field)
    2311             :       : field_(mutable_field) {
    2312             :   }
    2313             :   RepeatedPtrFieldBackInsertIterator<T>& operator=(const T& value) {
    2314             :     *field_->Add() = value;
    2315             :     return *this;
    2316             :   }
    2317             :   RepeatedPtrFieldBackInsertIterator<T>& operator=(
    2318             :       const T* const ptr_to_value) {
    2319             :     *field_->Add() = *ptr_to_value;
    2320             :     return *this;
    2321             :   }
    2322             :   RepeatedPtrFieldBackInsertIterator<T>& operator*() {
    2323             :     return *this;
    2324             :   }
    2325             :   RepeatedPtrFieldBackInsertIterator<T>& operator++() {
    2326             :     return *this;
    2327             :   }
    2328             :   RepeatedPtrFieldBackInsertIterator<T>& operator++(int /* unused */) {
    2329             :     return *this;
    2330             :   }
    2331             : 
    2332             :  private:
    2333             :   RepeatedPtrField<T>* field_;
    2334             : };
    2335             : 
    2336             : // A back inserter for RepeatedPtrFields that inserts by transfering ownership
    2337             : // of a pointer.
    2338             : template<typename T> class AllocatedRepeatedPtrFieldBackInsertIterator
    2339             :     : public std::iterator<std::output_iterator_tag, T> {
    2340             :  public:
    2341             :   explicit AllocatedRepeatedPtrFieldBackInsertIterator(
    2342             :       RepeatedPtrField<T>* const mutable_field)
    2343             :       : field_(mutable_field) {
    2344             :   }
    2345             :   AllocatedRepeatedPtrFieldBackInsertIterator<T>& operator=(
    2346             :       T* const ptr_to_value) {
    2347             :     field_->AddAllocated(ptr_to_value);
    2348             :     return *this;
    2349             :   }
    2350             :   AllocatedRepeatedPtrFieldBackInsertIterator<T>& operator*() {
    2351             :     return *this;
    2352             :   }
    2353             :   AllocatedRepeatedPtrFieldBackInsertIterator<T>& operator++() {
    2354             :     return *this;
    2355             :   }
    2356             :   AllocatedRepeatedPtrFieldBackInsertIterator<T>& operator++(
    2357             :       int /* unused */) {
    2358             :     return *this;
    2359             :   }
    2360             : 
    2361             :  private:
    2362             :   RepeatedPtrField<T>* field_;
    2363             : };
    2364             : }  // namespace internal
    2365             : 
    2366             : // Provides a back insert iterator for RepeatedField instances,
    2367             : // similar to std::back_inserter().
    2368             : template<typename T> internal::RepeatedFieldBackInsertIterator<T>
    2369             : RepeatedFieldBackInserter(RepeatedField<T>* const mutable_field) {
    2370             :   return internal::RepeatedFieldBackInsertIterator<T>(mutable_field);
    2371             : }
    2372             : 
    2373             : // Provides a back insert iterator for RepeatedPtrField instances,
    2374             : // similar to std::back_inserter().
    2375             : template<typename T> internal::RepeatedPtrFieldBackInsertIterator<T>
    2376             : RepeatedPtrFieldBackInserter(RepeatedPtrField<T>* const mutable_field) {
    2377             :   return internal::RepeatedPtrFieldBackInsertIterator<T>(mutable_field);
    2378             : }
    2379             : 
    2380             : // Special back insert iterator for RepeatedPtrField instances, just in
    2381             : // case someone wants to write generic template code that can access both
    2382             : // RepeatedFields and RepeatedPtrFields using a common name.
    2383             : template<typename T> internal::RepeatedPtrFieldBackInsertIterator<T>
    2384             : RepeatedFieldBackInserter(RepeatedPtrField<T>* const mutable_field) {
    2385             :   return internal::RepeatedPtrFieldBackInsertIterator<T>(mutable_field);
    2386             : }
    2387             : 
    2388             : // Provides a back insert iterator for RepeatedPtrField instances
    2389             : // similar to std::back_inserter() which transfers the ownership while
    2390             : // copying elements.
    2391             : template<typename T> internal::AllocatedRepeatedPtrFieldBackInsertIterator<T>
    2392             : AllocatedRepeatedPtrFieldBackInserter(
    2393             :     RepeatedPtrField<T>* const mutable_field) {
    2394             :   return internal::AllocatedRepeatedPtrFieldBackInsertIterator<T>(
    2395             :       mutable_field);
    2396             : }
    2397             : 
    2398             : }  // namespace protobuf
    2399             : 
    2400             : }  // namespace google
    2401             : #endif  // GOOGLE_PROTOBUF_REPEATED_FIELD_H__

Generated by: LCOV version 1.10