1// Protocol Buffers - Google's data interchange format
2// Copyright 2008 Google Inc.  All rights reserved.
3// http://code.google.com/p/protobuf/
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#include <algorithm>
50#include <string>
51#include <iterator>
52#include <google/protobuf/stubs/common.h>
53#include <google/protobuf/stubs/type_traits.h>
54#include <google/protobuf/generated_message_util.h>
55#include <google/protobuf/message_lite.h>
56
57namespace google {
58
59namespace upb {
60namespace google_opensource {
61class GMR_Handlers;
62}  // namespace google_opensource
63}  // namespace upb
64
65namespace protobuf {
66
67class Message;
68
69namespace internal {
70
71static const int kMinRepeatedFieldAllocationSize = 4;
72
73// A utility function for logging that doesn't need any template types.
74void LogIndexOutOfBounds(int index, int size);
75}  // namespace internal
76
77
78// RepeatedField is used to represent repeated fields of a primitive type (in
79// other words, everything except strings and nested Messages).  Most users will
80// not ever use a RepeatedField directly; they will use the get-by-index,
81// set-by-index, and add accessors that are generated for all repeated fields.
82template <typename Element>
83class RepeatedField {
84 public:
85  RepeatedField();
86  RepeatedField(const RepeatedField& other);
87  template <typename Iter>
88  RepeatedField(Iter begin, const Iter& end);
89  ~RepeatedField();
90
91  RepeatedField& operator=(const RepeatedField& other);
92
93  int size() const;
94
95  const Element& Get(int index) const;
96  Element* Mutable(int index);
97  void Set(int index, const Element& value);
98  void Add(const Element& value);
99  Element* Add();
100  // Remove the last element in the array.
101  void RemoveLast();
102
103  // Extract elements with indices in "[start .. start+num-1]".
104  // Copy them into "elements[0 .. num-1]" if "elements" is not NULL.
105  // Caution: implementation also moves elements with indices [start+num ..].
106  // Calling this routine inside a loop can cause quadratic behavior.
107  void ExtractSubrange(int start, int num, Element* elements);
108
109  void Clear();
110  void MergeFrom(const RepeatedField& other);
111  void CopyFrom(const RepeatedField& other);
112
113  // Reserve space to expand the field to at least the given size.  If the
114  // array is grown, it will always be at least doubled in size.
115  void Reserve(int new_size);
116
117  // Resize the RepeatedField to a new, smaller size.  This is O(1).
118  void Truncate(int new_size);
119
120  void AddAlreadyReserved(const Element& value);
121  Element* AddAlreadyReserved();
122  int Capacity() const;
123
124  // Gets the underlying array.  This pointer is possibly invalidated by
125  // any add or remove operation.
126  Element* mutable_data();
127  const Element* data() const;
128
129  // Swap entire contents with "other".
130  void Swap(RepeatedField* other);
131
132  // Swap two elements.
133  void SwapElements(int index1, int index2);
134
135  // STL-like iterator support
136  typedef Element* iterator;
137  typedef const Element* const_iterator;
138  typedef Element value_type;
139  typedef value_type& reference;
140  typedef const value_type& const_reference;
141  typedef value_type* pointer;
142  typedef const value_type* const_pointer;
143  typedef int size_type;
144  typedef ptrdiff_t difference_type;
145
146  iterator begin();
147  const_iterator begin() const;
148  iterator end();
149  const_iterator end() const;
150
151  // Reverse iterator support
152  typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
153  typedef std::reverse_iterator<iterator> reverse_iterator;
154  reverse_iterator rbegin() {
155    return reverse_iterator(end());
156  }
157  const_reverse_iterator rbegin() const {
158    return const_reverse_iterator(end());
159  }
160  reverse_iterator rend() {
161    return reverse_iterator(begin());
162  }
163  const_reverse_iterator rend() const {
164    return const_reverse_iterator(begin());
165  }
166
167  // Returns the number of bytes used by the repeated field, excluding
168  // sizeof(*this)
169  int SpaceUsedExcludingSelf() const;
170
171 private:
172  static const int kInitialSize = 0;
173
174  Element* elements_;
175  int      current_size_;
176  int      total_size_;
177
178  // Move the contents of |from| into |to|, possibly clobbering |from| in the
179  // process.  For primitive types this is just a memcpy(), but it could be
180  // specialized for non-primitive types to, say, swap each element instead.
181  void MoveArray(Element to[], Element from[], int size);
182
183  // Copy the elements of |from| into |to|.
184  void CopyArray(Element to[], const Element from[], int size);
185};
186
187namespace internal {
188template <typename It> class RepeatedPtrIterator;
189template <typename It, typename VoidPtr> class RepeatedPtrOverPtrsIterator;
190}  // namespace internal
191
192namespace internal {
193
194// This is a helper template to copy an array of elements effeciently when they
195// have a trivial copy constructor, and correctly otherwise. This really
196// shouldn't be necessary, but our compiler doesn't optimize std::copy very
197// effectively.
198template <typename Element,
199          bool HasTrivialCopy = has_trivial_copy<Element>::value>
200struct ElementCopier {
201  void operator()(Element to[], const Element from[], int array_size);
202};
203
204}  // namespace internal
205
206namespace internal {
207
208// This is the common base class for RepeatedPtrFields.  It deals only in void*
209// pointers.  Users should not use this interface directly.
210//
211// The methods of this interface correspond to the methods of RepeatedPtrField,
212// but may have a template argument called TypeHandler.  Its signature is:
213//   class TypeHandler {
214//    public:
215//     typedef MyType Type;
216//     static Type* New();
217//     static void Delete(Type*);
218//     static void Clear(Type*);
219//     static void Merge(const Type& from, Type* to);
220//
221//     // Only needs to be implemented if SpaceUsedExcludingSelf() is called.
222//     static int SpaceUsed(const Type&);
223//   };
224class LIBPROTOBUF_EXPORT RepeatedPtrFieldBase {
225 protected:
226  // The reflection implementation needs to call protected methods directly,
227  // reinterpreting pointers as being to Message instead of a specific Message
228  // subclass.
229  friend class GeneratedMessageReflection;
230
231  // ExtensionSet stores repeated message extensions as
232  // RepeatedPtrField<MessageLite>, but non-lite ExtensionSets need to
233  // implement SpaceUsed(), and thus need to call SpaceUsedExcludingSelf()
234  // reinterpreting MessageLite as Message.  ExtensionSet also needs to make
235  // use of AddFromCleared(), which is not part of the public interface.
236  friend class ExtensionSet;
237
238  // To parse directly into a proto2 generated class, the upb class GMR_Handlers
239  // needs to be able to modify a RepeatedPtrFieldBase directly.
240  friend class LIBPROTOBUF_EXPORT upb::google_opensource::GMR_Handlers;
241
242  RepeatedPtrFieldBase();
243
244  // Must be called from destructor.
245  template <typename TypeHandler>
246  void Destroy();
247
248  int size() const;
249
250  template <typename TypeHandler>
251  const typename TypeHandler::Type& Get(int index) const;
252  template <typename TypeHandler>
253  typename TypeHandler::Type* Mutable(int index);
254  template <typename TypeHandler>
255  typename TypeHandler::Type* Add();
256  template <typename TypeHandler>
257  void RemoveLast();
258  template <typename TypeHandler>
259  void Clear();
260  template <typename TypeHandler>
261  void MergeFrom(const RepeatedPtrFieldBase& other);
262  template <typename TypeHandler>
263  void CopyFrom(const RepeatedPtrFieldBase& other);
264
265  void CloseGap(int start, int num) {
266    // Close up a gap of "num" elements starting at offset "start".
267    for (int i = start + num; i < allocated_size_; ++i)
268      elements_[i - num] = elements_[i];
269    current_size_ -= num;
270    allocated_size_ -= num;
271  }
272
273  void Reserve(int new_size);
274
275  int Capacity() const;
276
277  // Used for constructing iterators.
278  void* const* raw_data() const;
279  void** raw_mutable_data() const;
280
281  template <typename TypeHandler>
282  typename TypeHandler::Type** mutable_data();
283  template <typename TypeHandler>
284  const typename TypeHandler::Type* const* data() const;
285
286  void Swap(RepeatedPtrFieldBase* other);
287
288  void SwapElements(int index1, int index2);
289
290  template <typename TypeHandler>
291  int SpaceUsedExcludingSelf() const;
292
293
294  // Advanced memory management --------------------------------------
295
296  // Like Add(), but if there are no cleared objects to use, returns NULL.
297  template <typename TypeHandler>
298  typename TypeHandler::Type* AddFromCleared();
299
300  template <typename TypeHandler>
301  void AddAllocated(typename TypeHandler::Type* value);
302  template <typename TypeHandler>
303  typename TypeHandler::Type* ReleaseLast();
304
305  int ClearedCount() const;
306  template <typename TypeHandler>
307  void AddCleared(typename TypeHandler::Type* value);
308  template <typename TypeHandler>
309  typename TypeHandler::Type* ReleaseCleared();
310
311 private:
312  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RepeatedPtrFieldBase);
313
314  static const int kInitialSize = 0;
315
316  void** elements_;
317  int    current_size_;
318  int    allocated_size_;
319  int    total_size_;
320
321  template <typename TypeHandler>
322  static inline typename TypeHandler::Type* cast(void* element) {
323    return reinterpret_cast<typename TypeHandler::Type*>(element);
324  }
325  template <typename TypeHandler>
326  static inline const typename TypeHandler::Type* cast(const void* element) {
327    return reinterpret_cast<const typename TypeHandler::Type*>(element);
328  }
329};
330
331template <typename GenericType>
332class GenericTypeHandler {
333 public:
334  typedef GenericType Type;
335  static GenericType* New() { return new GenericType; }
336  static void Delete(GenericType* value) { delete value; }
337  static void Clear(GenericType* value) { value->Clear(); }
338  static void Merge(const GenericType& from, GenericType* to) {
339    to->MergeFrom(from);
340  }
341  static int SpaceUsed(const GenericType& value) { return value.SpaceUsed(); }
342  static const Type& default_instance() { return Type::default_instance(); }
343};
344
345template <>
346inline void GenericTypeHandler<MessageLite>::Merge(
347    const MessageLite& from, MessageLite* to) {
348  to->CheckTypeAndMergeFrom(from);
349}
350
351template <>
352inline const MessageLite& GenericTypeHandler<MessageLite>::default_instance() {
353  // Yes, the behavior of the code is undefined, but this function is only
354  // called when we're already deep into the world of undefined, because the
355  // caller called Get(index) out of bounds.
356  MessageLite* null = NULL;
357  return *null;
358}
359
360template <>
361inline const Message& GenericTypeHandler<Message>::default_instance() {
362  // Yes, the behavior of the code is undefined, but this function is only
363  // called when we're already deep into the world of undefined, because the
364  // caller called Get(index) out of bounds.
365  Message* null = NULL;
366  return *null;
367}
368
369
370// HACK:  If a class is declared as DLL-exported in MSVC, it insists on
371//   generating copies of all its methods -- even inline ones -- to include
372//   in the DLL.  But SpaceUsed() calls StringSpaceUsedExcludingSelf() which
373//   isn't in the lite library, therefore the lite library cannot link if
374//   StringTypeHandler is exported.  So, we factor out StringTypeHandlerBase,
375//   export that, then make StringTypeHandler be a subclass which is NOT
376//   exported.
377// TODO(kenton):  There has to be a better way.
378class LIBPROTOBUF_EXPORT StringTypeHandlerBase {
379 public:
380  typedef string Type;
381  static string* New();
382  static void Delete(string* value);
383  static void Clear(string* value) { value->clear(); }
384  static void Merge(const string& from, string* to) { *to = from; }
385  static const Type& default_instance() {
386    return ::google::protobuf::internal::GetEmptyString();
387  }
388};
389
390class StringTypeHandler : public StringTypeHandlerBase {
391 public:
392  static int SpaceUsed(const string& value)  {
393    return sizeof(value) + StringSpaceUsedExcludingSelf(value);
394  }
395};
396
397
398}  // namespace internal
399
400// RepeatedPtrField is like RepeatedField, but used for repeated strings or
401// Messages.
402template <typename Element>
403class RepeatedPtrField : public internal::RepeatedPtrFieldBase {
404 public:
405  RepeatedPtrField();
406  RepeatedPtrField(const RepeatedPtrField& other);
407  template <typename Iter>
408  RepeatedPtrField(Iter begin, const Iter& end);
409  ~RepeatedPtrField();
410
411  RepeatedPtrField& operator=(const RepeatedPtrField& other);
412
413  int size() const;
414
415  const Element& Get(int index) const;
416  Element* Mutable(int index);
417  Element* Add();
418
419  // Remove the last element in the array.
420  // Ownership of the element is retained by the array.
421  void RemoveLast();
422
423  // Delete elements with indices in the range [start .. start+num-1].
424  // Caution: implementation moves all elements with indices [start+num .. ].
425  // Calling this routine inside a loop can cause quadratic behavior.
426  void DeleteSubrange(int start, int num);
427
428  void Clear();
429  void MergeFrom(const RepeatedPtrField& other);
430  void CopyFrom(const RepeatedPtrField& other);
431
432  // Reserve space to expand the field to at least the given size.  This only
433  // resizes the pointer array; it doesn't allocate any objects.  If the
434  // array is grown, it will always be at least doubled in size.
435  void Reserve(int new_size);
436
437  int Capacity() const;
438
439  // Gets the underlying array.  This pointer is possibly invalidated by
440  // any add or remove operation.
441  Element** mutable_data();
442  const Element* const* data() const;
443
444  // Swap entire contents with "other".
445  void Swap(RepeatedPtrField* other);
446
447  // Swap two elements.
448  void SwapElements(int index1, int index2);
449
450  // STL-like iterator support
451  typedef internal::RepeatedPtrIterator<Element> iterator;
452  typedef internal::RepeatedPtrIterator<const Element> const_iterator;
453  typedef Element value_type;
454  typedef value_type& reference;
455  typedef const value_type& const_reference;
456  typedef value_type* pointer;
457  typedef const value_type* const_pointer;
458  typedef int size_type;
459  typedef ptrdiff_t difference_type;
460
461  iterator begin();
462  const_iterator begin() const;
463  iterator end();
464  const_iterator end() const;
465
466  // Reverse iterator support
467  typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
468  typedef std::reverse_iterator<iterator> reverse_iterator;
469  reverse_iterator rbegin() {
470    return reverse_iterator(end());
471  }
472  const_reverse_iterator rbegin() const {
473    return const_reverse_iterator(end());
474  }
475  reverse_iterator rend() {
476    return reverse_iterator(begin());
477  }
478  const_reverse_iterator rend() const {
479    return const_reverse_iterator(begin());
480  }
481
482  // Custom STL-like iterator that iterates over and returns the underlying
483  // pointers to Element rather than Element itself.
484  typedef internal::RepeatedPtrOverPtrsIterator<Element, void*>
485  pointer_iterator;
486  typedef internal::RepeatedPtrOverPtrsIterator<const Element, const void*>
487  const_pointer_iterator;
488  pointer_iterator pointer_begin();
489  const_pointer_iterator pointer_begin() const;
490  pointer_iterator pointer_end();
491  const_pointer_iterator pointer_end() const;
492
493  // Returns (an estimate of) the number of bytes used by the repeated field,
494  // excluding sizeof(*this).
495  int SpaceUsedExcludingSelf() const;
496
497  // Advanced memory management --------------------------------------
498  // When hardcore memory management becomes necessary -- as it sometimes
499  // does here at Google -- the following methods may be useful.
500
501  // Add an already-allocated object, passing ownership to the
502  // RepeatedPtrField.
503  void AddAllocated(Element* value);
504  // Remove the last element and return it, passing ownership to the caller.
505  // Requires:  size() > 0
506  Element* ReleaseLast();
507
508  // Extract elements with indices in the range "[start .. start+num-1]".
509  // The caller assumes ownership of the extracted elements and is responsible
510  // for deleting them when they are no longer needed.
511  // If "elements" is non-NULL, then pointers to the extracted elements
512  // are stored in "elements[0 .. num-1]" for the convenience of the caller.
513  // If "elements" is NULL, then the caller must use some other mechanism
514  // to perform any further operations (like deletion) on these elements.
515  // Caution: implementation also moves elements with indices [start+num ..].
516  // Calling this routine inside a loop can cause quadratic behavior.
517  void ExtractSubrange(int start, int num, Element** elements);
518
519  // When elements are removed by calls to RemoveLast() or Clear(), they
520  // are not actually freed.  Instead, they are cleared and kept so that
521  // they can be reused later.  This can save lots of CPU time when
522  // repeatedly reusing a protocol message for similar purposes.
523  //
524  // Hardcore programs may choose to manipulate these cleared objects
525  // to better optimize memory management using the following routines.
526
527  // Get the number of cleared objects that are currently being kept
528  // around for reuse.
529  int ClearedCount() const;
530  // Add an element to the pool of cleared objects, passing ownership to
531  // the RepeatedPtrField.  The element must be cleared prior to calling
532  // this method.
533  void AddCleared(Element* value);
534  // Remove a single element from the cleared pool and return it, passing
535  // ownership to the caller.  The element is guaranteed to be cleared.
536  // Requires:  ClearedCount() > 0
537  Element* ReleaseCleared();
538
539 protected:
540  // Note:  RepeatedPtrField SHOULD NOT be subclassed by users.  We only
541  //   subclass it in one place as a hack for compatibility with proto1.  The
542  //   subclass needs to know about TypeHandler in order to call protected
543  //   methods on RepeatedPtrFieldBase.
544  class TypeHandler;
545
546};
547
548// implementation ====================================================
549
550template <typename Element>
551inline RepeatedField<Element>::RepeatedField()
552  : elements_(NULL),
553    current_size_(0),
554    total_size_(kInitialSize) {
555}
556
557template <typename Element>
558inline RepeatedField<Element>::RepeatedField(const RepeatedField& other)
559  : elements_(NULL),
560    current_size_(0),
561    total_size_(kInitialSize) {
562  CopyFrom(other);
563}
564
565template <typename Element>
566template <typename Iter>
567inline RepeatedField<Element>::RepeatedField(Iter begin, const Iter& end)
568  : elements_(NULL),
569    current_size_(0),
570    total_size_(kInitialSize) {
571  for (; begin != end; ++begin) {
572    Add(*begin);
573  }
574}
575
576template <typename Element>
577RepeatedField<Element>::~RepeatedField() {
578  delete [] elements_;
579}
580
581template <typename Element>
582inline RepeatedField<Element>&
583RepeatedField<Element>::operator=(const RepeatedField& other) {
584  if (this != &other)
585    CopyFrom(other);
586  return *this;
587}
588
589template <typename Element>
590inline int RepeatedField<Element>::size() const {
591  return current_size_;
592}
593
594template <typename Element>
595inline int RepeatedField<Element>::Capacity() const {
596  return total_size_;
597}
598
599template<typename Element>
600inline void RepeatedField<Element>::AddAlreadyReserved(const Element& value) {
601  GOOGLE_DCHECK_LT(size(), Capacity());
602  elements_[current_size_++] = value;
603}
604
605template<typename Element>
606inline Element* RepeatedField<Element>::AddAlreadyReserved() {
607  GOOGLE_DCHECK_LT(size(), Capacity());
608  return &elements_[current_size_++];
609}
610
611template <typename Element>
612inline const Element& RepeatedField<Element>::Get(int index) const {
613  GOOGLE_DCHECK_LT(index, size());
614  return elements_[index];
615}
616
617template <typename Element>
618inline Element* RepeatedField<Element>::Mutable(int index) {
619  GOOGLE_DCHECK_LT(index, size());
620  return elements_ + index;
621}
622
623template <typename Element>
624inline void RepeatedField<Element>::Set(int index, const Element& value) {
625  GOOGLE_DCHECK_LT(index, size());
626  elements_[index] = value;
627}
628
629template <typename Element>
630inline void RepeatedField<Element>::Add(const Element& value) {
631  if (current_size_ == total_size_) Reserve(total_size_ + 1);
632  elements_[current_size_++] = value;
633}
634
635template <typename Element>
636inline Element* RepeatedField<Element>::Add() {
637  if (current_size_ == total_size_) Reserve(total_size_ + 1);
638  return &elements_[current_size_++];
639}
640
641template <typename Element>
642inline void RepeatedField<Element>::RemoveLast() {
643  GOOGLE_DCHECK_GT(current_size_, 0);
644  --current_size_;
645}
646
647template <typename Element>
648void RepeatedField<Element>::ExtractSubrange(
649    int start, int num, Element* elements) {
650  GOOGLE_DCHECK_GE(start, 0);
651  GOOGLE_DCHECK_GE(num, 0);
652  GOOGLE_DCHECK_LE(start + num, this->size());
653
654  // Save the values of the removed elements if requested.
655  if (elements != NULL) {
656    for (int i = 0; i < num; ++i)
657      elements[i] = this->Get(i + start);
658  }
659
660  // Slide remaining elements down to fill the gap.
661  if (num > 0) {
662    for (int i = start + num; i < this->size(); ++i)
663      this->Set(i - num, this->Get(i));
664    this->Truncate(this->size() - num);
665  }
666}
667
668template <typename Element>
669inline void RepeatedField<Element>::Clear() {
670  current_size_ = 0;
671}
672
673template <typename Element>
674inline void RepeatedField<Element>::MergeFrom(const RepeatedField& other) {
675  if (other.current_size_ != 0) {
676    Reserve(current_size_ + other.current_size_);
677    CopyArray(elements_ + current_size_, other.elements_, other.current_size_);
678    current_size_ += other.current_size_;
679  }
680}
681
682template <typename Element>
683inline void RepeatedField<Element>::CopyFrom(const RepeatedField& other) {
684  Clear();
685  MergeFrom(other);
686}
687
688template <typename Element>
689inline Element* RepeatedField<Element>::mutable_data() {
690  return elements_;
691}
692
693template <typename Element>
694inline const Element* RepeatedField<Element>::data() const {
695  return elements_;
696}
697
698
699template <typename Element>
700void RepeatedField<Element>::Swap(RepeatedField* other) {
701  if (this == other) return;
702  Element* swap_elements     = elements_;
703  int      swap_current_size = current_size_;
704  int      swap_total_size   = total_size_;
705
706  elements_     = other->elements_;
707  current_size_ = other->current_size_;
708  total_size_   = other->total_size_;
709
710  other->elements_     = swap_elements;
711  other->current_size_ = swap_current_size;
712  other->total_size_   = swap_total_size;
713}
714
715template <typename Element>
716void RepeatedField<Element>::SwapElements(int index1, int index2) {
717  std::swap(elements_[index1], elements_[index2]);
718}
719
720template <typename Element>
721inline typename RepeatedField<Element>::iterator
722RepeatedField<Element>::begin() {
723  return elements_;
724}
725template <typename Element>
726inline typename RepeatedField<Element>::const_iterator
727RepeatedField<Element>::begin() const {
728  return elements_;
729}
730template <typename Element>
731inline typename RepeatedField<Element>::iterator
732RepeatedField<Element>::end() {
733  return elements_ + current_size_;
734}
735template <typename Element>
736inline typename RepeatedField<Element>::const_iterator
737RepeatedField<Element>::end() const {
738  return elements_ + current_size_;
739}
740
741template <typename Element>
742inline int RepeatedField<Element>::SpaceUsedExcludingSelf() const {
743  return (elements_ != NULL) ? total_size_ * sizeof(elements_[0]) : 0;
744}
745
746// Avoid inlining of Reserve(): new, copy, and delete[] lead to a significant
747// amount of code bloat.
748template <typename Element>
749void RepeatedField<Element>::Reserve(int new_size) {
750  if (total_size_ >= new_size) return;
751
752  Element* old_elements = elements_;
753  total_size_ = max(google::protobuf::internal::kMinRepeatedFieldAllocationSize,
754                    max(total_size_ * 2, new_size));
755  elements_ = new Element[total_size_];
756  if (old_elements != NULL) {
757    MoveArray(elements_, old_elements, current_size_);
758    delete [] old_elements;
759  }
760}
761
762template <typename Element>
763inline void RepeatedField<Element>::Truncate(int new_size) {
764  GOOGLE_DCHECK_LE(new_size, current_size_);
765  current_size_ = new_size;
766}
767
768template <typename Element>
769inline void RepeatedField<Element>::MoveArray(
770    Element to[], Element from[], int array_size) {
771  CopyArray(to, from, array_size);
772}
773
774template <typename Element>
775inline void RepeatedField<Element>::CopyArray(
776    Element to[], const Element from[], int array_size) {
777  internal::ElementCopier<Element>()(to, from, array_size);
778}
779
780namespace internal {
781
782template <typename Element, bool HasTrivialCopy>
783void ElementCopier<Element, HasTrivialCopy>::operator()(
784    Element to[], const Element from[], int array_size) {
785  std::copy(from, from + array_size, to);
786}
787
788template <typename Element>
789struct ElementCopier<Element, true> {
790  void operator()(Element to[], const Element from[], int array_size) {
791    memcpy(to, from, array_size * sizeof(Element));
792  }
793};
794
795}  // namespace internal
796
797
798// -------------------------------------------------------------------
799
800namespace internal {
801
802inline RepeatedPtrFieldBase::RepeatedPtrFieldBase()
803  : elements_(NULL),
804    current_size_(0),
805    allocated_size_(0),
806    total_size_(kInitialSize) {
807}
808
809template <typename TypeHandler>
810void RepeatedPtrFieldBase::Destroy() {
811  for (int i = 0; i < allocated_size_; i++) {
812    TypeHandler::Delete(cast<TypeHandler>(elements_[i]));
813  }
814  delete [] elements_;
815}
816
817inline int RepeatedPtrFieldBase::size() const {
818  return current_size_;
819}
820
821template <typename TypeHandler>
822inline const typename TypeHandler::Type&
823RepeatedPtrFieldBase::Get(int index) const {
824  GOOGLE_DCHECK_LT(index, size());
825  return *cast<TypeHandler>(elements_[index]);
826}
827
828
829template <typename TypeHandler>
830inline typename TypeHandler::Type*
831RepeatedPtrFieldBase::Mutable(int index) {
832  GOOGLE_DCHECK_LT(index, size());
833  return cast<TypeHandler>(elements_[index]);
834}
835
836template <typename TypeHandler>
837inline typename TypeHandler::Type* RepeatedPtrFieldBase::Add() {
838  if (current_size_ < allocated_size_) {
839    return cast<TypeHandler>(elements_[current_size_++]);
840  }
841  if (allocated_size_ == total_size_) Reserve(total_size_ + 1);
842  ++allocated_size_;
843  typename TypeHandler::Type* result = TypeHandler::New();
844  elements_[current_size_++] = result;
845  return result;
846}
847
848template <typename TypeHandler>
849inline void RepeatedPtrFieldBase::RemoveLast() {
850  GOOGLE_DCHECK_GT(current_size_, 0);
851  TypeHandler::Clear(cast<TypeHandler>(elements_[--current_size_]));
852}
853
854template <typename TypeHandler>
855void RepeatedPtrFieldBase::Clear() {
856  for (int i = 0; i < current_size_; i++) {
857    TypeHandler::Clear(cast<TypeHandler>(elements_[i]));
858  }
859  current_size_ = 0;
860}
861
862template <typename TypeHandler>
863inline void RepeatedPtrFieldBase::MergeFrom(const RepeatedPtrFieldBase& other) {
864  Reserve(current_size_ + other.current_size_);
865  for (int i = 0; i < other.current_size_; i++) {
866    TypeHandler::Merge(other.template Get<TypeHandler>(i), Add<TypeHandler>());
867  }
868}
869
870template <typename TypeHandler>
871inline void RepeatedPtrFieldBase::CopyFrom(const RepeatedPtrFieldBase& other) {
872  RepeatedPtrFieldBase::Clear<TypeHandler>();
873  RepeatedPtrFieldBase::MergeFrom<TypeHandler>(other);
874}
875
876inline int RepeatedPtrFieldBase::Capacity() const {
877  return total_size_;
878}
879
880inline void* const* RepeatedPtrFieldBase::raw_data() const {
881  return elements_;
882}
883
884inline void** RepeatedPtrFieldBase::raw_mutable_data() const {
885  return elements_;
886}
887
888template <typename TypeHandler>
889inline typename TypeHandler::Type** RepeatedPtrFieldBase::mutable_data() {
890  // TODO(kenton):  Breaks C++ aliasing rules.  We should probably remove this
891  //   method entirely.
892  return reinterpret_cast<typename TypeHandler::Type**>(elements_);
893}
894
895template <typename TypeHandler>
896inline const typename TypeHandler::Type* const*
897RepeatedPtrFieldBase::data() const {
898  // TODO(kenton):  Breaks C++ aliasing rules.  We should probably remove this
899  //   method entirely.
900  return reinterpret_cast<const typename TypeHandler::Type* const*>(elements_);
901}
902
903inline void RepeatedPtrFieldBase::SwapElements(int index1, int index2) {
904  std::swap(elements_[index1], elements_[index2]);
905}
906
907template <typename TypeHandler>
908inline int RepeatedPtrFieldBase::SpaceUsedExcludingSelf() const {
909  int allocated_bytes =
910      (elements_ != NULL) ? total_size_ * sizeof(elements_[0]) : 0;
911  for (int i = 0; i < allocated_size_; ++i) {
912    allocated_bytes += TypeHandler::SpaceUsed(*cast<TypeHandler>(elements_[i]));
913  }
914  return allocated_bytes;
915}
916
917template <typename TypeHandler>
918inline typename TypeHandler::Type* RepeatedPtrFieldBase::AddFromCleared() {
919  if (current_size_ < allocated_size_) {
920    return cast<TypeHandler>(elements_[current_size_++]);
921  } else {
922    return NULL;
923  }
924}
925
926template <typename TypeHandler>
927void RepeatedPtrFieldBase::AddAllocated(
928    typename TypeHandler::Type* value) {
929  // Make room for the new pointer.
930  if (current_size_ == total_size_) {
931    // The array is completely full with no cleared objects, so grow it.
932    Reserve(total_size_ + 1);
933    ++allocated_size_;
934  } else if (allocated_size_ == total_size_) {
935    // There is no more space in the pointer array because it contains some
936    // cleared objects awaiting reuse.  We don't want to grow the array in this
937    // case because otherwise a loop calling AddAllocated() followed by Clear()
938    // would leak memory.
939    TypeHandler::Delete(cast<TypeHandler>(elements_[current_size_]));
940  } else if (current_size_ < allocated_size_) {
941    // We have some cleared objects.  We don't care about their order, so we
942    // can just move the first one to the end to make space.
943    elements_[allocated_size_] = elements_[current_size_];
944    ++allocated_size_;
945  } else {
946    // There are no cleared objects.
947    ++allocated_size_;
948  }
949
950  elements_[current_size_++] = value;
951}
952
953template <typename TypeHandler>
954inline typename TypeHandler::Type* RepeatedPtrFieldBase::ReleaseLast() {
955  GOOGLE_DCHECK_GT(current_size_, 0);
956  typename TypeHandler::Type* result =
957      cast<TypeHandler>(elements_[--current_size_]);
958  --allocated_size_;
959  if (current_size_ < allocated_size_) {
960    // There are cleared elements on the end; replace the removed element
961    // with the last allocated element.
962    elements_[current_size_] = elements_[allocated_size_];
963  }
964  return result;
965}
966
967inline int RepeatedPtrFieldBase::ClearedCount() const {
968  return allocated_size_ - current_size_;
969}
970
971template <typename TypeHandler>
972inline void RepeatedPtrFieldBase::AddCleared(
973    typename TypeHandler::Type* value) {
974  if (allocated_size_ == total_size_) Reserve(total_size_ + 1);
975  elements_[allocated_size_++] = value;
976}
977
978template <typename TypeHandler>
979inline typename TypeHandler::Type* RepeatedPtrFieldBase::ReleaseCleared() {
980  GOOGLE_DCHECK_GT(allocated_size_, current_size_);
981  return cast<TypeHandler>(elements_[--allocated_size_]);
982}
983
984}  // namespace internal
985
986// -------------------------------------------------------------------
987
988template <typename Element>
989class RepeatedPtrField<Element>::TypeHandler
990    : public internal::GenericTypeHandler<Element> {
991};
992
993template <>
994class RepeatedPtrField<string>::TypeHandler
995    : public internal::StringTypeHandler {
996};
997
998
999template <typename Element>
1000inline RepeatedPtrField<Element>::RepeatedPtrField() {}
1001
1002template <typename Element>
1003inline RepeatedPtrField<Element>::RepeatedPtrField(
1004    const RepeatedPtrField& other) {
1005  CopyFrom(other);
1006}
1007
1008template <typename Element>
1009template <typename Iter>
1010inline RepeatedPtrField<Element>::RepeatedPtrField(
1011    Iter begin, const Iter& end) {
1012  for (; begin != end; ++begin) {
1013    *Add() = *begin;
1014  }
1015}
1016
1017template <typename Element>
1018RepeatedPtrField<Element>::~RepeatedPtrField() {
1019  Destroy<TypeHandler>();
1020}
1021
1022template <typename Element>
1023inline RepeatedPtrField<Element>& RepeatedPtrField<Element>::operator=(
1024    const RepeatedPtrField& other) {
1025  if (this != &other)
1026    CopyFrom(other);
1027  return *this;
1028}
1029
1030template <typename Element>
1031inline int RepeatedPtrField<Element>::size() const {
1032  return RepeatedPtrFieldBase::size();
1033}
1034
1035template <typename Element>
1036inline const Element& RepeatedPtrField<Element>::Get(int index) const {
1037  return RepeatedPtrFieldBase::Get<TypeHandler>(index);
1038}
1039
1040
1041template <typename Element>
1042inline Element* RepeatedPtrField<Element>::Mutable(int index) {
1043  return RepeatedPtrFieldBase::Mutable<TypeHandler>(index);
1044}
1045
1046template <typename Element>
1047inline Element* RepeatedPtrField<Element>::Add() {
1048  return RepeatedPtrFieldBase::Add<TypeHandler>();
1049}
1050
1051template <typename Element>
1052inline void RepeatedPtrField<Element>::RemoveLast() {
1053  RepeatedPtrFieldBase::RemoveLast<TypeHandler>();
1054}
1055
1056template <typename Element>
1057inline void RepeatedPtrField<Element>::DeleteSubrange(int start, int num) {
1058  GOOGLE_DCHECK_GE(start, 0);
1059  GOOGLE_DCHECK_GE(num, 0);
1060  GOOGLE_DCHECK_LE(start + num, size());
1061  for (int i = 0; i < num; ++i)
1062    delete RepeatedPtrFieldBase::Mutable<TypeHandler>(start + i);
1063  ExtractSubrange(start, num, NULL);
1064}
1065
1066template <typename Element>
1067inline void RepeatedPtrField<Element>::ExtractSubrange(
1068    int start, int num, Element** elements) {
1069  GOOGLE_DCHECK_GE(start, 0);
1070  GOOGLE_DCHECK_GE(num, 0);
1071  GOOGLE_DCHECK_LE(start + num, size());
1072
1073  if (num > 0) {
1074    // Save the values of the removed elements if requested.
1075    if (elements != NULL) {
1076      for (int i = 0; i < num; ++i)
1077        elements[i] = RepeatedPtrFieldBase::Mutable<TypeHandler>(i + start);
1078    }
1079    CloseGap(start, num);
1080  }
1081}
1082
1083template <typename Element>
1084inline void RepeatedPtrField<Element>::Clear() {
1085  RepeatedPtrFieldBase::Clear<TypeHandler>();
1086}
1087
1088template <typename Element>
1089inline void RepeatedPtrField<Element>::MergeFrom(
1090    const RepeatedPtrField& other) {
1091  RepeatedPtrFieldBase::MergeFrom<TypeHandler>(other);
1092}
1093
1094template <typename Element>
1095inline void RepeatedPtrField<Element>::CopyFrom(
1096    const RepeatedPtrField& other) {
1097  RepeatedPtrFieldBase::CopyFrom<TypeHandler>(other);
1098}
1099
1100template <typename Element>
1101inline Element** RepeatedPtrField<Element>::mutable_data() {
1102  return RepeatedPtrFieldBase::mutable_data<TypeHandler>();
1103}
1104
1105template <typename Element>
1106inline const Element* const* RepeatedPtrField<Element>::data() const {
1107  return RepeatedPtrFieldBase::data<TypeHandler>();
1108}
1109
1110template <typename Element>
1111void RepeatedPtrField<Element>::Swap(RepeatedPtrField* other) {
1112  RepeatedPtrFieldBase::Swap(other);
1113}
1114
1115template <typename Element>
1116void RepeatedPtrField<Element>::SwapElements(int index1, int index2) {
1117  RepeatedPtrFieldBase::SwapElements(index1, index2);
1118}
1119
1120template <typename Element>
1121inline int RepeatedPtrField<Element>::SpaceUsedExcludingSelf() const {
1122  return RepeatedPtrFieldBase::SpaceUsedExcludingSelf<TypeHandler>();
1123}
1124
1125template <typename Element>
1126inline void RepeatedPtrField<Element>::AddAllocated(Element* value) {
1127  RepeatedPtrFieldBase::AddAllocated<TypeHandler>(value);
1128}
1129
1130template <typename Element>
1131inline Element* RepeatedPtrField<Element>::ReleaseLast() {
1132  return RepeatedPtrFieldBase::ReleaseLast<TypeHandler>();
1133}
1134
1135
1136template <typename Element>
1137inline int RepeatedPtrField<Element>::ClearedCount() const {
1138  return RepeatedPtrFieldBase::ClearedCount();
1139}
1140
1141template <typename Element>
1142inline void RepeatedPtrField<Element>::AddCleared(Element* value) {
1143  return RepeatedPtrFieldBase::AddCleared<TypeHandler>(value);
1144}
1145
1146template <typename Element>
1147inline Element* RepeatedPtrField<Element>::ReleaseCleared() {
1148  return RepeatedPtrFieldBase::ReleaseCleared<TypeHandler>();
1149}
1150
1151template <typename Element>
1152inline void RepeatedPtrField<Element>::Reserve(int new_size) {
1153  return RepeatedPtrFieldBase::Reserve(new_size);
1154}
1155
1156template <typename Element>
1157inline int RepeatedPtrField<Element>::Capacity() const {
1158  return RepeatedPtrFieldBase::Capacity();
1159}
1160
1161// -------------------------------------------------------------------
1162
1163namespace internal {
1164
1165// STL-like iterator implementation for RepeatedPtrField.  You should not
1166// refer to this class directly; use RepeatedPtrField<T>::iterator instead.
1167//
1168// The iterator for RepeatedPtrField<T>, RepeatedPtrIterator<T>, is
1169// very similar to iterator_ptr<T**> in util/gtl/iterator_adaptors.h,
1170// but adds random-access operators and is modified to wrap a void** base
1171// iterator (since RepeatedPtrField stores its array as a void* array and
1172// casting void** to T** would violate C++ aliasing rules).
1173//
1174// This code based on net/proto/proto-array-internal.h by Jeffrey Yasskin
1175// (jyasskin@google.com).
1176template<typename Element>
1177class RepeatedPtrIterator
1178    : public std::iterator<
1179          std::random_access_iterator_tag, Element> {
1180 public:
1181  typedef RepeatedPtrIterator<Element> iterator;
1182  typedef std::iterator<
1183          std::random_access_iterator_tag, Element> superclass;
1184
1185  // Let the compiler know that these are type names, so we don't have to
1186  // write "typename" in front of them everywhere.
1187  typedef typename superclass::reference reference;
1188  typedef typename superclass::pointer pointer;
1189  typedef typename superclass::difference_type difference_type;
1190
1191  RepeatedPtrIterator() : it_(NULL) {}
1192  explicit RepeatedPtrIterator(void* const* it) : it_(it) {}
1193
1194  // Allow "upcasting" from RepeatedPtrIterator<T**> to
1195  // RepeatedPtrIterator<const T*const*>.
1196  template<typename OtherElement>
1197  RepeatedPtrIterator(const RepeatedPtrIterator<OtherElement>& other)
1198      : it_(other.it_) {
1199    // Force a compiler error if the other type is not convertible to ours.
1200    if (false) {
1201      implicit_cast<Element*, OtherElement*>(0);
1202    }
1203  }
1204
1205  // dereferenceable
1206  reference operator*() const { return *reinterpret_cast<Element*>(*it_); }
1207  pointer   operator->() const { return &(operator*()); }
1208
1209  // {inc,dec}rementable
1210  iterator& operator++() { ++it_; return *this; }
1211  iterator  operator++(int) { return iterator(it_++); }
1212  iterator& operator--() { --it_; return *this; }
1213  iterator  operator--(int) { return iterator(it_--); }
1214
1215  // equality_comparable
1216  bool operator==(const iterator& x) const { return it_ == x.it_; }
1217  bool operator!=(const iterator& x) const { return it_ != x.it_; }
1218
1219  // less_than_comparable
1220  bool operator<(const iterator& x) const { return it_ < x.it_; }
1221  bool operator<=(const iterator& x) const { return it_ <= x.it_; }
1222  bool operator>(const iterator& x) const { return it_ > x.it_; }
1223  bool operator>=(const iterator& x) const { return it_ >= x.it_; }
1224
1225  // addable, subtractable
1226  iterator& operator+=(difference_type d) {
1227    it_ += d;
1228    return *this;
1229  }
1230  friend iterator operator+(iterator it, difference_type d) {
1231    it += d;
1232    return it;
1233  }
1234  friend iterator operator+(difference_type d, iterator it) {
1235    it += d;
1236    return it;
1237  }
1238  iterator& operator-=(difference_type d) {
1239    it_ -= d;
1240    return *this;
1241  }
1242  friend iterator operator-(iterator it, difference_type d) {
1243    it -= d;
1244    return it;
1245  }
1246
1247  // indexable
1248  reference operator[](difference_type d) const { return *(*this + d); }
1249
1250  // random access iterator
1251  difference_type operator-(const iterator& x) const { return it_ - x.it_; }
1252
1253 private:
1254  template<typename OtherElement>
1255  friend class RepeatedPtrIterator;
1256
1257  // The internal iterator.
1258  void* const* it_;
1259};
1260
1261// Provide an iterator that operates on pointers to the underlying objects
1262// rather than the objects themselves as RepeatedPtrIterator does.
1263// Consider using this when working with stl algorithms that change
1264// the array.
1265// The VoidPtr template parameter holds the type-agnostic pointer value
1266// referenced by the iterator.  It should either be "void *" for a mutable
1267// iterator, or "const void *" for a constant iterator.
1268template<typename Element, typename VoidPtr>
1269class RepeatedPtrOverPtrsIterator
1270    : public std::iterator<std::random_access_iterator_tag, Element*> {
1271 public:
1272  typedef RepeatedPtrOverPtrsIterator<Element, VoidPtr> iterator;
1273  typedef std::iterator<
1274          std::random_access_iterator_tag, Element*> superclass;
1275
1276  // Let the compiler know that these are type names, so we don't have to
1277  // write "typename" in front of them everywhere.
1278  typedef typename superclass::reference reference;
1279  typedef typename superclass::pointer pointer;
1280  typedef typename superclass::difference_type difference_type;
1281
1282  RepeatedPtrOverPtrsIterator() : it_(NULL) {}
1283  explicit RepeatedPtrOverPtrsIterator(VoidPtr* it) : it_(it) {}
1284
1285  // dereferenceable
1286  reference operator*() const { return *reinterpret_cast<Element**>(it_); }
1287  pointer   operator->() const { return &(operator*()); }
1288
1289  // {inc,dec}rementable
1290  iterator& operator++() { ++it_; return *this; }
1291  iterator  operator++(int) { return iterator(it_++); }
1292  iterator& operator--() { --it_; return *this; }
1293  iterator  operator--(int) { return iterator(it_--); }
1294
1295  // equality_comparable
1296  bool operator==(const iterator& x) const { return it_ == x.it_; }
1297  bool operator!=(const iterator& x) const { return it_ != x.it_; }
1298
1299  // less_than_comparable
1300  bool operator<(const iterator& x) const { return it_ < x.it_; }
1301  bool operator<=(const iterator& x) const { return it_ <= x.it_; }
1302  bool operator>(const iterator& x) const { return it_ > x.it_; }
1303  bool operator>=(const iterator& x) const { return it_ >= x.it_; }
1304
1305  // addable, subtractable
1306  iterator& operator+=(difference_type d) {
1307    it_ += d;
1308    return *this;
1309  }
1310  friend iterator operator+(iterator it, difference_type d) {
1311    it += d;
1312    return it;
1313  }
1314  friend iterator operator+(difference_type d, iterator it) {
1315    it += d;
1316    return it;
1317  }
1318  iterator& operator-=(difference_type d) {
1319    it_ -= d;
1320    return *this;
1321  }
1322  friend iterator operator-(iterator it, difference_type d) {
1323    it -= d;
1324    return it;
1325  }
1326
1327  // indexable
1328  reference operator[](difference_type d) const { return *(*this + d); }
1329
1330  // random access iterator
1331  difference_type operator-(const iterator& x) const { return it_ - x.it_; }
1332
1333 private:
1334  template<typename OtherElement>
1335  friend class RepeatedPtrIterator;
1336
1337  // The internal iterator.
1338  VoidPtr* it_;
1339};
1340
1341}  // namespace internal
1342
1343template <typename Element>
1344inline typename RepeatedPtrField<Element>::iterator
1345RepeatedPtrField<Element>::begin() {
1346  return iterator(raw_data());
1347}
1348template <typename Element>
1349inline typename RepeatedPtrField<Element>::const_iterator
1350RepeatedPtrField<Element>::begin() const {
1351  return iterator(raw_data());
1352}
1353template <typename Element>
1354inline typename RepeatedPtrField<Element>::iterator
1355RepeatedPtrField<Element>::end() {
1356  return iterator(raw_data() + size());
1357}
1358template <typename Element>
1359inline typename RepeatedPtrField<Element>::const_iterator
1360RepeatedPtrField<Element>::end() const {
1361  return iterator(raw_data() + size());
1362}
1363
1364template <typename Element>
1365inline typename RepeatedPtrField<Element>::pointer_iterator
1366RepeatedPtrField<Element>::pointer_begin() {
1367  return pointer_iterator(raw_mutable_data());
1368}
1369template <typename Element>
1370inline typename RepeatedPtrField<Element>::const_pointer_iterator
1371RepeatedPtrField<Element>::pointer_begin() const {
1372  return const_pointer_iterator(const_cast<const void**>(raw_mutable_data()));
1373}
1374template <typename Element>
1375inline typename RepeatedPtrField<Element>::pointer_iterator
1376RepeatedPtrField<Element>::pointer_end() {
1377  return pointer_iterator(raw_mutable_data() + size());
1378}
1379template <typename Element>
1380inline typename RepeatedPtrField<Element>::const_pointer_iterator
1381RepeatedPtrField<Element>::pointer_end() const {
1382  return const_pointer_iterator(
1383      const_cast<const void**>(raw_mutable_data() + size()));
1384}
1385
1386
1387// Iterators and helper functions that follow the spirit of the STL
1388// std::back_insert_iterator and std::back_inserter but are tailor-made
1389// for RepeatedField and RepatedPtrField. Typical usage would be:
1390//
1391//   std::copy(some_sequence.begin(), some_sequence.end(),
1392//             google::protobuf::RepeatedFieldBackInserter(proto.mutable_sequence()));
1393//
1394// Ported by johannes from util/gtl/proto-array-iterators.h
1395
1396namespace internal {
1397// A back inserter for RepeatedField objects.
1398template<typename T> class RepeatedFieldBackInsertIterator
1399    : public std::iterator<std::output_iterator_tag, T> {
1400 public:
1401  explicit RepeatedFieldBackInsertIterator(
1402      RepeatedField<T>* const mutable_field)
1403      : field_(mutable_field) {
1404  }
1405  RepeatedFieldBackInsertIterator<T>& operator=(const T& value) {
1406    field_->Add(value);
1407    return *this;
1408  }
1409  RepeatedFieldBackInsertIterator<T>& operator*() {
1410    return *this;
1411  }
1412  RepeatedFieldBackInsertIterator<T>& operator++() {
1413    return *this;
1414  }
1415  RepeatedFieldBackInsertIterator<T>& operator++(int /* unused */) {
1416    return *this;
1417  }
1418
1419 private:
1420  RepeatedField<T>* field_;
1421};
1422
1423// A back inserter for RepeatedPtrField objects.
1424template<typename T> class RepeatedPtrFieldBackInsertIterator
1425    : public std::iterator<std::output_iterator_tag, T> {
1426 public:
1427  RepeatedPtrFieldBackInsertIterator(
1428      RepeatedPtrField<T>* const mutable_field)
1429      : field_(mutable_field) {
1430  }
1431  RepeatedPtrFieldBackInsertIterator<T>& operator=(const T& value) {
1432    *field_->Add() = value;
1433    return *this;
1434  }
1435  RepeatedPtrFieldBackInsertIterator<T>& operator=(
1436      const T* const ptr_to_value) {
1437    *field_->Add() = *ptr_to_value;
1438    return *this;
1439  }
1440  RepeatedPtrFieldBackInsertIterator<T>& operator*() {
1441    return *this;
1442  }
1443  RepeatedPtrFieldBackInsertIterator<T>& operator++() {
1444    return *this;
1445  }
1446  RepeatedPtrFieldBackInsertIterator<T>& operator++(int /* unused */) {
1447    return *this;
1448  }
1449
1450 private:
1451  RepeatedPtrField<T>* field_;
1452};
1453
1454// A back inserter for RepeatedPtrFields that inserts by transfering ownership
1455// of a pointer.
1456template<typename T> class AllocatedRepeatedPtrFieldBackInsertIterator
1457    : public std::iterator<std::output_iterator_tag, T> {
1458 public:
1459  explicit AllocatedRepeatedPtrFieldBackInsertIterator(
1460      RepeatedPtrField<T>* const mutable_field)
1461      : field_(mutable_field) {
1462  }
1463  AllocatedRepeatedPtrFieldBackInsertIterator<T>& operator=(
1464      T* const ptr_to_value) {
1465    field_->AddAllocated(ptr_to_value);
1466    return *this;
1467  }
1468  AllocatedRepeatedPtrFieldBackInsertIterator<T>& operator*() {
1469    return *this;
1470  }
1471  AllocatedRepeatedPtrFieldBackInsertIterator<T>& operator++() {
1472    return *this;
1473  }
1474  AllocatedRepeatedPtrFieldBackInsertIterator<T>& operator++(
1475      int /* unused */) {
1476    return *this;
1477  }
1478
1479 private:
1480  RepeatedPtrField<T>* field_;
1481};
1482}  // namespace internal
1483
1484// Provides a back insert iterator for RepeatedField instances,
1485// similar to std::back_inserter().
1486template<typename T> internal::RepeatedFieldBackInsertIterator<T>
1487RepeatedFieldBackInserter(RepeatedField<T>* const mutable_field) {
1488  return internal::RepeatedFieldBackInsertIterator<T>(mutable_field);
1489}
1490
1491// Provides a back insert iterator for RepeatedPtrField instances,
1492// similar to std::back_inserter().
1493template<typename T> internal::RepeatedPtrFieldBackInsertIterator<T>
1494RepeatedPtrFieldBackInserter(RepeatedPtrField<T>* const mutable_field) {
1495  return internal::RepeatedPtrFieldBackInsertIterator<T>(mutable_field);
1496}
1497
1498// Special back insert iterator for RepeatedPtrField instances, just in
1499// case someone wants to write generic template code that can access both
1500// RepeatedFields and RepeatedPtrFields using a common name.
1501template<typename T> internal::RepeatedPtrFieldBackInsertIterator<T>
1502RepeatedFieldBackInserter(RepeatedPtrField<T>* const mutable_field) {
1503  return internal::RepeatedPtrFieldBackInsertIterator<T>(mutable_field);
1504}
1505
1506// Provides a back insert iterator for RepeatedPtrField instances
1507// similar to std::back_inserter() which transfers the ownership while
1508// copying elements.
1509template<typename T> internal::AllocatedRepeatedPtrFieldBackInsertIterator<T>
1510AllocatedRepeatedPtrFieldBackInserter(
1511    RepeatedPtrField<T>* const mutable_field) {
1512  return internal::AllocatedRepeatedPtrFieldBackInsertIterator<T>(
1513      mutable_field);
1514}
1515
1516}  // namespace protobuf
1517
1518}  // namespace google
1519#endif  // GOOGLE_PROTOBUF_REPEATED_FIELD_H__
1520