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