• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <string>
50 #include <iterator>
51 #include <google/protobuf/stubs/common.h>
52 #include <google/protobuf/message_lite.h>
53 
54 namespace google {
55 
56 namespace protobuf {
57 
58 class Message;
59 
60 namespace internal {
61 
62 // We need this (from generated_message_reflection.cc).
63 LIBPROTOBUF_EXPORT int StringSpaceUsedExcludingSelf(const string& str);
64 
65 }  // namespace internal
66 
67 // RepeatedField is used to represent repeated fields of a primitive type (in
68 // other words, everything except strings and nested Messages).  Most users will
69 // not ever use a RepeatedField directly; they will use the get-by-index,
70 // set-by-index, and add accessors that are generated for all repeated fields.
71 template <typename Element>
72 class RepeatedField {
73  public:
74   RepeatedField();
75   ~RepeatedField();
76 
77   int size() const;
78 
79   const Element& Get(int index) const;
80   Element* Mutable(int index);
81   void Set(int index, const Element& value);
82   void Add(const Element& value);
83   Element* Add();
84   // Remove the last element in the array.
85   // We don't provide a way to remove any element other than the last
86   // because it invites inefficient use, such as O(n^2) filtering loops
87   // that should have been O(n).  If you want to remove an element other
88   // than the last, the best way to do it is to re-arrange the elements
89   // so that the one you want removed is at the end, then call RemoveLast().
90   void RemoveLast();
91   void Clear();
92   void MergeFrom(const RepeatedField& other);
93 
94   // Reserve space to expand the field to at least the given size.  If the
95   // array is grown, it will always be at least doubled in size.
96   void Reserve(int new_size);
97 
98   // Resize the RepeatedField to a new, smaller size.  This is O(1).
99   void Truncate(int new_size);
100 
101   void AddAlreadyReserved(const Element& value);
102   Element* AddAlreadyReserved();
103   int Capacity() const;
104 
105   // Gets the underlying array.  This pointer is possibly invalidated by
106   // any add or remove operation.
107   Element* mutable_data();
108   const Element* data() const;
109 
110   // Swap entire contents with "other".
111   void Swap(RepeatedField* other);
112 
113   // Swap two elements.
114   void SwapElements(int index1, int index2);
115 
116   // STL-like iterator support
117   typedef Element* iterator;
118   typedef const Element* const_iterator;
119 
120   iterator begin();
121   const_iterator begin() const;
122   iterator end();
123   const_iterator end() const;
124 
125   // Returns the number of bytes used by the repeated field, excluding
126   // sizeof(*this)
127   int SpaceUsedExcludingSelf() const;
128 
129  private:
130   GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RepeatedField);
131 
132   static const int kInitialSize = 4;
133 
134   Element* elements_;
135   int      current_size_;
136   int      total_size_;
137 
138   Element  initial_space_[kInitialSize];
139 
140   // Move the contents of |from| into |to|, possibly clobbering |from| in the
141   // process.  For primitive types this is just a memcpy(), but it could be
142   // specialized for non-primitive types to, say, swap each element instead.
143   void MoveArray(Element to[], Element from[], int size);
144 
145   // Copy the elements of |from| into |to|.
146   void CopyArray(Element to[], const Element from[], int size);
147 };
148 
149 namespace internal {
150 template <typename It> class RepeatedPtrIterator;
151 template <typename It> class RepeatedPtrOverPtrsIterator;
152 }  // namespace internal
153 
154 namespace internal {
155 
156 // This is the common base class for RepeatedPtrFields.  It deals only in void*
157 // pointers.  Users should not use this interface directly.
158 //
159 // The methods of this interface correspond to the methods of RepeatedPtrField,
160 // but may have a template argument called TypeHandler.  Its signature is:
161 //   class TypeHandler {
162 //    public:
163 //     typedef MyType Type;
164 //     static Type* New();
165 //     static void Delete(Type*);
166 //     static void Clear(Type*);
167 //     static void Merge(const Type& from, Type* to);
168 //
169 //     // Only needs to be implemented if SpaceUsedExcludingSelf() is called.
170 //     static int SpaceUsed(const Type&);
171 //   };
172 class LIBPROTOBUF_EXPORT RepeatedPtrFieldBase {
173  protected:
174   // The reflection implementation needs to call protected methods directly,
175   // reinterpreting pointers as being to Message instead of a specific Message
176   // subclass.
177   friend class GeneratedMessageReflection;
178 
179   // ExtensionSet stores repeated message extensions as
180   // RepeatedPtrField<MessageLite>, but non-lite ExtensionSets need to
181   // implement SpaceUsed(), and thus need to call SpaceUsedExcludingSelf()
182   // reinterpreting MessageLite as Message.  ExtensionSet also needs to make
183   // use of AddFromCleared(), which is not part of the public interface.
184   friend class ExtensionSet;
185 
186   RepeatedPtrFieldBase();
187 
188   // Must be called from destructor.
189   template <typename TypeHandler>
190   void Destroy();
191 
192   int size() const;
193 
194   template <typename TypeHandler>
195   const typename TypeHandler::Type& Get(int index) const;
196   template <typename TypeHandler>
197   typename TypeHandler::Type* Mutable(int index);
198   template <typename TypeHandler>
199   typename TypeHandler::Type* Add();
200   template <typename TypeHandler>
201   void RemoveLast();
202   template <typename TypeHandler>
203   void Clear();
204   template <typename TypeHandler>
205   void MergeFrom(const RepeatedPtrFieldBase& other);
206 
207   void Reserve(int new_size);
208 
209   int Capacity() const;
210 
211   // Used for constructing iterators.
212   void* const* raw_data() const;
213   void** raw_mutable_data() const;
214 
215   template <typename TypeHandler>
216   typename TypeHandler::Type** mutable_data();
217   template <typename TypeHandler>
218   const typename TypeHandler::Type* const* data() const;
219 
220   void Swap(RepeatedPtrFieldBase* other);
221 
222   void SwapElements(int index1, int index2);
223 
224   template <typename TypeHandler>
225   int SpaceUsedExcludingSelf() const;
226 
227 
228   // Advanced memory management --------------------------------------
229 
230   // Like Add(), but if there are no cleared objects to use, returns NULL.
231   template <typename TypeHandler>
232   typename TypeHandler::Type* AddFromCleared();
233 
234   template <typename TypeHandler>
235   void AddAllocated(typename TypeHandler::Type* value);
236   template <typename TypeHandler>
237   typename TypeHandler::Type* ReleaseLast();
238 
239   int ClearedCount() const;
240   template <typename TypeHandler>
241   void AddCleared(typename TypeHandler::Type* value);
242   template <typename TypeHandler>
243   typename TypeHandler::Type* ReleaseCleared();
244 
245  private:
246   GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RepeatedPtrFieldBase);
247 
248   static const int kInitialSize = 4;
249 
250   void** elements_;
251   int    current_size_;
252   int    allocated_size_;
253   int    total_size_;
254 
255   void*  initial_space_[kInitialSize];
256 
257   template <typename TypeHandler>
cast(void * element)258   static inline typename TypeHandler::Type* cast(void* element) {
259     return reinterpret_cast<typename TypeHandler::Type*>(element);
260   }
261   template <typename TypeHandler>
cast(const void * element)262   static inline const typename TypeHandler::Type* cast(const void* element) {
263     return reinterpret_cast<const typename TypeHandler::Type*>(element);
264   }
265 };
266 
267 template <typename GenericType>
268 class GenericTypeHandler {
269  public:
270   typedef GenericType Type;
New()271   static GenericType* New() { return new GenericType; }
Delete(GenericType * value)272   static void Delete(GenericType* value) { delete value; }
Clear(GenericType * value)273   static void Clear(GenericType* value) { value->Clear(); }
Merge(const GenericType & from,GenericType * to)274   static void Merge(const GenericType& from, GenericType* to) {
275     to->MergeFrom(from);
276   }
SpaceUsed(const GenericType & value)277   static int SpaceUsed(const GenericType& value) { return value.SpaceUsed(); }
278 };
279 
280 template <>
Merge(const MessageLite & from,MessageLite * to)281 inline void GenericTypeHandler<MessageLite>::Merge(
282     const MessageLite& from, MessageLite* to) {
283   to->CheckTypeAndMergeFrom(from);
284 }
285 
286 // HACK:  If a class is declared as DLL-exported in MSVC, it insists on
287 //   generating copies of all its methods -- even inline ones -- to include
288 //   in the DLL.  But SpaceUsed() calls StringSpaceUsedExcludingSelf() which
289 //   isn't in the lite library, therefore the lite library cannot link if
290 //   StringTypeHandler is exported.  So, we factor out StringTypeHandlerBase,
291 //   export that, then make StringTypeHandler be a subclass which is NOT
292 //   exported.
293 // TODO(kenton):  There has to be a better way.
294 class LIBPROTOBUF_EXPORT StringTypeHandlerBase {
295  public:
296   typedef string Type;
297   static string* New();
298   static void Delete(string* value);
Clear(string * value)299   static void Clear(string* value) { value->clear(); }
Merge(const string & from,string * to)300   static void Merge(const string& from, string* to) { *to = from; }
301 };
302 
303 class StringTypeHandler : public StringTypeHandlerBase {
304  public:
SpaceUsed(const string & value)305   static int SpaceUsed(const string& value)  {
306     return sizeof(value) + StringSpaceUsedExcludingSelf(value);
307   }
308 };
309 
310 
311 }  // namespace internal
312 
313 // RepeatedPtrField is like RepeatedField, but used for repeated strings or
314 // Messages.
315 template <typename Element>
316 class RepeatedPtrField : public internal::RepeatedPtrFieldBase {
317  public:
318   RepeatedPtrField();
319 
320   ~RepeatedPtrField();
321 
322   int size() const;
323 
324   const Element& Get(int index) const;
325   Element* Mutable(int index);
326   Element* Add();
327   void RemoveLast();  // Remove the last element in the array.
328   void Clear();
329   void MergeFrom(const RepeatedPtrField& other);
330 
331   // Reserve space to expand the field to at least the given size.  This only
332   // resizes the pointer array; it doesn't allocate any objects.  If the
333   // array is grown, it will always be at least doubled in size.
334   void Reserve(int new_size);
335 
336   int Capacity() const;
337 
338   // Gets the underlying array.  This pointer is possibly invalidated by
339   // any add or remove operation.
340   Element** mutable_data();
341   const Element* const* data() const;
342 
343   // Swap entire contents with "other".
344   void Swap(RepeatedPtrField* other);
345 
346   // Swap two elements.
347   void SwapElements(int index1, int index2);
348 
349   // STL-like iterator support
350   typedef internal::RepeatedPtrIterator<Element> iterator;
351   typedef internal::RepeatedPtrIterator<const Element> const_iterator;
352 
353   iterator begin();
354   const_iterator begin() const;
355   iterator end();
356   const_iterator end() const;
357 
358   // Custom STL-like iterator that iterates over and returns the underlying
359   // pointers to Element rather than Element itself.
360   typedef internal::RepeatedPtrOverPtrsIterator<Element> pointer_iterator;
361   pointer_iterator pointer_begin();
362   pointer_iterator pointer_end();
363 
364   // Returns (an estimate of) the number of bytes used by the repeated field,
365   // excluding sizeof(*this).
366   int SpaceUsedExcludingSelf() const;
367 
368   // The spaced used just by the pointer array, not counting the objects pointed
369   // at.  Returns zero if the array is inlined (i.e. initial_space_ is being
370   // used).
371   int SpaceUsedByArray() const;
372 
373   // Advanced memory management --------------------------------------
374   // When hardcore memory management becomes necessary -- as it often
375   // does here at Google -- the following methods may be useful.
376 
377   // Add an already-allocated object, passing ownership to the
378   // RepeatedPtrField.
379   void AddAllocated(Element* value);
380   // Remove the last element and return it, passing ownership to the
381   // caller.
382   // Requires:  size() > 0
383   Element* ReleaseLast();
384 
385   // When elements are removed by calls to RemoveLast() or Clear(), they
386   // are not actually freed.  Instead, they are cleared and kept so that
387   // they can be reused later.  This can save lots of CPU time when
388   // repeatedly reusing a protocol message for similar purposes.
389   //
390   // Really, extremely hardcore programs may actually want to manipulate
391   // these objects to better-optimize memory management.  These methods
392   // allow that.
393 
394   // Get the number of cleared objects that are currently being kept
395   // around for reuse.
396   int ClearedCount() const;
397   // Add an element to the pool of cleared objects, passing ownership to
398   // the RepeatedPtrField.  The element must be cleared prior to calling
399   // this method.
400   void AddCleared(Element* value);
401   // Remove a single element from the cleared pool and return it, passing
402   // ownership to the caller.  The element is guaranteed to be cleared.
403   // Requires:  ClearedCount() > 0
404   Element* ReleaseCleared();
405 
406  protected:
407   // Note:  RepeatedPtrField SHOULD NOT be subclassed by users.  We only
408   //   subclass it in one place as a hack for compatibility with proto1.  The
409   //   subclass needs to know about TypeHandler in order to call protected
410   //   methods on RepeatedPtrFieldBase.
411   class TypeHandler;
412 
413 
414  private:
415   GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RepeatedPtrField);
416 };
417 
418 // implementation ====================================================
419 
420 template <typename Element>
RepeatedField()421 inline RepeatedField<Element>::RepeatedField()
422   : elements_(initial_space_),
423     current_size_(0),
424     total_size_(kInitialSize) {
425 }
426 
427 template <typename Element>
~RepeatedField()428 RepeatedField<Element>::~RepeatedField() {
429   if (elements_ != initial_space_) {
430     delete [] elements_;
431   }
432 }
433 
434 template <typename Element>
size()435 inline int RepeatedField<Element>::size() const {
436   return current_size_;
437 }
438 
439 template <typename Element>
Capacity()440 inline int RepeatedField<Element>::Capacity() const {
441   return total_size_;
442 }
443 
444 template<typename Element>
AddAlreadyReserved(const Element & value)445 inline void RepeatedField<Element>::AddAlreadyReserved(const Element& value) {
446   GOOGLE_DCHECK_LT(size(), Capacity());
447   elements_[current_size_++] = value;
448 }
449 
450 template<typename Element>
AddAlreadyReserved()451 inline Element* RepeatedField<Element>::AddAlreadyReserved() {
452   GOOGLE_DCHECK_LT(size(), Capacity());
453   return &elements_[current_size_++];
454 }
455 
456 template <typename Element>
Get(int index)457 inline const Element& RepeatedField<Element>::Get(int index) const {
458   GOOGLE_DCHECK_LT(index, size());
459   return elements_[index];
460 }
461 
462 template <typename Element>
Mutable(int index)463 inline Element* RepeatedField<Element>::Mutable(int index) {
464   GOOGLE_DCHECK_LT(index, size());
465   return elements_ + index;
466 }
467 
468 template <typename Element>
Set(int index,const Element & value)469 inline void RepeatedField<Element>::Set(int index, const Element& value) {
470   GOOGLE_DCHECK_LT(index, size());
471   elements_[index] = value;
472 }
473 
474 template <typename Element>
Add(const Element & value)475 inline void RepeatedField<Element>::Add(const Element& value) {
476   if (current_size_ == total_size_) Reserve(total_size_ + 1);
477   elements_[current_size_++] = value;
478 }
479 
480 template <typename Element>
Add()481 inline Element* RepeatedField<Element>::Add() {
482   if (current_size_ == total_size_) Reserve(total_size_ + 1);
483   return &elements_[current_size_++];
484 }
485 
486 template <typename Element>
RemoveLast()487 inline void RepeatedField<Element>::RemoveLast() {
488   GOOGLE_DCHECK_GT(current_size_, 0);
489   --current_size_;
490 }
491 
492 template <typename Element>
Clear()493 inline void RepeatedField<Element>::Clear() {
494   current_size_ = 0;
495 }
496 
497 template <typename Element>
MergeFrom(const RepeatedField & other)498 inline void RepeatedField<Element>::MergeFrom(const RepeatedField& other) {
499   Reserve(current_size_ + other.current_size_);
500   CopyArray(elements_ + current_size_, other.elements_, other.current_size_);
501   current_size_ += other.current_size_;
502 }
503 
504 template <typename Element>
mutable_data()505 inline Element* RepeatedField<Element>::mutable_data() {
506   return elements_;
507 }
508 
509 template <typename Element>
data()510 inline const Element* RepeatedField<Element>::data() const {
511   return elements_;
512 }
513 
514 
515 template <typename Element>
Swap(RepeatedField * other)516 void RepeatedField<Element>::Swap(RepeatedField* other) {
517   Element* swap_elements     = elements_;
518   int      swap_current_size = current_size_;
519   int      swap_total_size   = total_size_;
520   // We may not be using initial_space_ but it's not worth checking.  Just
521   // copy it anyway.
522   Element swap_initial_space[kInitialSize];
523   MoveArray(swap_initial_space, initial_space_, kInitialSize);
524 
525   elements_     = other->elements_;
526   current_size_ = other->current_size_;
527   total_size_   = other->total_size_;
528   MoveArray(initial_space_, other->initial_space_, kInitialSize);
529 
530   other->elements_     = swap_elements;
531   other->current_size_ = swap_current_size;
532   other->total_size_   = swap_total_size;
533   MoveArray(other->initial_space_, swap_initial_space, kInitialSize);
534 
535   if (elements_ == other->initial_space_) {
536     elements_ = initial_space_;
537   }
538   if (other->elements_ == initial_space_) {
539     other->elements_ = other->initial_space_;
540   }
541 }
542 
543 template <typename Element>
SwapElements(int index1,int index2)544 void RepeatedField<Element>::SwapElements(int index1, int index2) {
545   std::swap(elements_[index1], elements_[index2]);
546 }
547 
548 template <typename Element>
549 inline typename RepeatedField<Element>::iterator
begin()550 RepeatedField<Element>::begin() {
551   return elements_;
552 }
553 template <typename Element>
554 inline typename RepeatedField<Element>::const_iterator
begin()555 RepeatedField<Element>::begin() const {
556   return elements_;
557 }
558 template <typename Element>
559 inline typename RepeatedField<Element>::iterator
end()560 RepeatedField<Element>::end() {
561   return elements_ + current_size_;
562 }
563 template <typename Element>
564 inline typename RepeatedField<Element>::const_iterator
end()565 RepeatedField<Element>::end() const {
566   return elements_ + current_size_;
567 }
568 
569 template <typename Element>
SpaceUsedExcludingSelf()570 inline int RepeatedField<Element>::SpaceUsedExcludingSelf() const {
571   return (elements_ != initial_space_) ? total_size_ * sizeof(elements_[0]) : 0;
572 }
573 
574 // Avoid inlining of Reserve(): new, memcpy, and delete[] lead to a significant
575 // amount of code bloat.
576 template <typename Element>
Reserve(int new_size)577 void RepeatedField<Element>::Reserve(int new_size) {
578   if (total_size_ >= new_size) return;
579 
580   Element* old_elements = elements_;
581   total_size_ = max(total_size_ * 2, new_size);
582   elements_ = new Element[total_size_];
583   MoveArray(elements_, old_elements, current_size_);
584   if (old_elements != initial_space_) {
585     delete [] old_elements;
586   }
587 }
588 
589 template <typename Element>
Truncate(int new_size)590 inline void RepeatedField<Element>::Truncate(int new_size) {
591   GOOGLE_DCHECK_LE(new_size, current_size_);
592   current_size_ = new_size;
593 }
594 
595 template <typename Element>
MoveArray(Element to[],Element from[],int size)596 inline void RepeatedField<Element>::MoveArray(
597     Element to[], Element from[], int size) {
598   memcpy(to, from, size * sizeof(Element));
599 }
600 
601 template <typename Element>
CopyArray(Element to[],const Element from[],int size)602 inline void RepeatedField<Element>::CopyArray(
603     Element to[], const Element from[], int size) {
604   memcpy(to, from, size * sizeof(Element));
605 }
606 
607 
608 // -------------------------------------------------------------------
609 
610 namespace internal {
611 
RepeatedPtrFieldBase()612 inline RepeatedPtrFieldBase::RepeatedPtrFieldBase()
613   : elements_(initial_space_),
614     current_size_(0),
615     allocated_size_(0),
616     total_size_(kInitialSize) {
617 }
618 
619 template <typename TypeHandler>
Destroy()620 void RepeatedPtrFieldBase::Destroy() {
621   for (int i = 0; i < allocated_size_; i++) {
622     TypeHandler::Delete(cast<TypeHandler>(elements_[i]));
623   }
624   if (elements_ != initial_space_) {
625     delete [] elements_;
626   }
627 }
628 
size()629 inline int RepeatedPtrFieldBase::size() const {
630   return current_size_;
631 }
632 
633 
634 template <typename TypeHandler>
635 inline const typename TypeHandler::Type&
Get(int index)636 RepeatedPtrFieldBase::Get(int index) const {
637   GOOGLE_DCHECK_LT(index, size());
638   return *cast<TypeHandler>(elements_[index]);
639 }
640 
641 template <typename TypeHandler>
642 inline typename TypeHandler::Type*
Mutable(int index)643 RepeatedPtrFieldBase::Mutable(int index) {
644   GOOGLE_DCHECK_LT(index, size());
645   return cast<TypeHandler>(elements_[index]);
646 }
647 
648 template <typename TypeHandler>
Add()649 inline typename TypeHandler::Type* RepeatedPtrFieldBase::Add() {
650   if (current_size_ < allocated_size_) {
651     return cast<TypeHandler>(elements_[current_size_++]);
652   }
653   if (allocated_size_ == total_size_) Reserve(total_size_ + 1);
654   ++allocated_size_;
655   typename TypeHandler::Type* result = TypeHandler::New();
656   elements_[current_size_++] = result;
657   return result;
658 }
659 
660 template <typename TypeHandler>
RemoveLast()661 inline void RepeatedPtrFieldBase::RemoveLast() {
662   GOOGLE_DCHECK_GT(current_size_, 0);
663   TypeHandler::Clear(cast<TypeHandler>(elements_[--current_size_]));
664 }
665 
666 template <typename TypeHandler>
Clear()667 void RepeatedPtrFieldBase::Clear() {
668   for (int i = 0; i < current_size_; i++) {
669     TypeHandler::Clear(cast<TypeHandler>(elements_[i]));
670   }
671   current_size_ = 0;
672 }
673 
674 template <typename TypeHandler>
MergeFrom(const RepeatedPtrFieldBase & other)675 inline void RepeatedPtrFieldBase::MergeFrom(const RepeatedPtrFieldBase& other) {
676   Reserve(current_size_ + other.current_size_);
677   for (int i = 0; i < other.current_size_; i++) {
678     TypeHandler::Merge(other.Get<TypeHandler>(i), Add<TypeHandler>());
679   }
680 }
681 
Capacity()682 inline int RepeatedPtrFieldBase::Capacity() const {
683   return total_size_;
684 }
685 
raw_data()686 inline void* const* RepeatedPtrFieldBase::raw_data() const {
687   return elements_;
688 }
689 
raw_mutable_data()690 inline void** RepeatedPtrFieldBase::raw_mutable_data() const {
691   return elements_;
692 }
693 
694 template <typename TypeHandler>
mutable_data()695 inline typename TypeHandler::Type** RepeatedPtrFieldBase::mutable_data() {
696   // TODO(kenton):  Breaks C++ aliasing rules.  We should probably remove this
697   //   method entirely.
698   return reinterpret_cast<typename TypeHandler::Type**>(elements_);
699 }
700 
701 template <typename TypeHandler>
702 inline const typename TypeHandler::Type* const*
data()703 RepeatedPtrFieldBase::data() const {
704   // TODO(kenton):  Breaks C++ aliasing rules.  We should probably remove this
705   //   method entirely.
706   return reinterpret_cast<const typename TypeHandler::Type* const*>(elements_);
707 }
708 
SwapElements(int index1,int index2)709 inline void RepeatedPtrFieldBase::SwapElements(int index1, int index2) {
710   std::swap(elements_[index1], elements_[index2]);
711 }
712 
713 template <typename TypeHandler>
SpaceUsedExcludingSelf()714 inline int RepeatedPtrFieldBase::SpaceUsedExcludingSelf() const {
715   int allocated_bytes =
716       (elements_ != initial_space_) ? total_size_ * sizeof(elements_[0]) : 0;
717   for (int i = 0; i < allocated_size_; ++i) {
718     allocated_bytes += TypeHandler::SpaceUsed(*cast<TypeHandler>(elements_[i]));
719   }
720   return allocated_bytes;
721 }
722 
723 template <typename TypeHandler>
AddFromCleared()724 inline typename TypeHandler::Type* RepeatedPtrFieldBase::AddFromCleared() {
725   if (current_size_ < allocated_size_) {
726     return cast<TypeHandler>(elements_[current_size_++]);
727   } else {
728     return NULL;
729   }
730 }
731 
732 template <typename TypeHandler>
AddAllocated(typename TypeHandler::Type * value)733 void RepeatedPtrFieldBase::AddAllocated(
734     typename TypeHandler::Type* value) {
735   // Make room for the new pointer.
736   if (current_size_ == total_size_) {
737     // The array is completely full with no cleared objects, so grow it.
738     Reserve(total_size_ + 1);
739     ++allocated_size_;
740   } else if (allocated_size_ == total_size_) {
741     // There is no more space in the pointer array because it contains some
742     // cleared objects awaiting reuse.  We don't want to grow the array in this
743     // case because otherwise a loop calling AddAllocated() followed by Clear()
744     // would leak memory.
745     TypeHandler::Delete(cast<TypeHandler>(elements_[current_size_]));
746   } else if (current_size_ < allocated_size_) {
747     // We have some cleared objects.  We don't care about their order, so we
748     // can just move the first one to the end to make space.
749     elements_[allocated_size_] = elements_[current_size_];
750     ++allocated_size_;
751   } else {
752     // There are no cleared objects.
753     ++allocated_size_;
754   }
755 
756   elements_[current_size_++] = value;
757 }
758 
759 template <typename TypeHandler>
ReleaseLast()760 inline typename TypeHandler::Type* RepeatedPtrFieldBase::ReleaseLast() {
761   GOOGLE_DCHECK_GT(current_size_, 0);
762   typename TypeHandler::Type* result =
763       cast<TypeHandler>(elements_[--current_size_]);
764   --allocated_size_;
765   if (current_size_ < allocated_size_) {
766     // There are cleared elements on the end; replace the removed element
767     // with the last allocated element.
768     elements_[current_size_] = elements_[allocated_size_];
769   }
770   return result;
771 }
772 
773 
ClearedCount()774 inline int RepeatedPtrFieldBase::ClearedCount() const {
775   return allocated_size_ - current_size_;
776 }
777 
778 template <typename TypeHandler>
AddCleared(typename TypeHandler::Type * value)779 inline void RepeatedPtrFieldBase::AddCleared(
780     typename TypeHandler::Type* value) {
781   if (allocated_size_ == total_size_) Reserve(total_size_ + 1);
782   elements_[allocated_size_++] = value;
783 }
784 
785 template <typename TypeHandler>
ReleaseCleared()786 inline typename TypeHandler::Type* RepeatedPtrFieldBase::ReleaseCleared() {
787   GOOGLE_DCHECK_GT(allocated_size_, current_size_);
788   return cast<TypeHandler>(elements_[--allocated_size_]);
789 }
790 
791 }  // namespace internal
792 
793 // -------------------------------------------------------------------
794 
795 template <typename Element>
796 class RepeatedPtrField<Element>::TypeHandler
797     : public internal::GenericTypeHandler<Element> {};
798 
799 template <>
800 class RepeatedPtrField<string>::TypeHandler
801     : public internal::StringTypeHandler {};
802 
803 
804 template <typename Element>
RepeatedPtrField()805 inline RepeatedPtrField<Element>::RepeatedPtrField() {}
806 
807 template <typename Element>
~RepeatedPtrField()808 RepeatedPtrField<Element>::~RepeatedPtrField() {
809   Destroy<TypeHandler>();
810 }
811 
812 template <typename Element>
size()813 inline int RepeatedPtrField<Element>::size() const {
814   return RepeatedPtrFieldBase::size();
815 }
816 
817 template <typename Element>
Get(int index)818 inline const Element& RepeatedPtrField<Element>::Get(int index) const {
819   return RepeatedPtrFieldBase::Get<TypeHandler>(index);
820 }
821 
822 template <typename Element>
Mutable(int index)823 inline Element* RepeatedPtrField<Element>::Mutable(int index) {
824   return RepeatedPtrFieldBase::Mutable<TypeHandler>(index);
825 }
826 
827 template <typename Element>
Add()828 inline Element* RepeatedPtrField<Element>::Add() {
829   return RepeatedPtrFieldBase::Add<TypeHandler>();
830 }
831 
832 template <typename Element>
RemoveLast()833 inline void RepeatedPtrField<Element>::RemoveLast() {
834   RepeatedPtrFieldBase::RemoveLast<TypeHandler>();
835 }
836 
837 template <typename Element>
Clear()838 inline void RepeatedPtrField<Element>::Clear() {
839   RepeatedPtrFieldBase::Clear<TypeHandler>();
840 }
841 
842 template <typename Element>
MergeFrom(const RepeatedPtrField & other)843 inline void RepeatedPtrField<Element>::MergeFrom(
844     const RepeatedPtrField& other) {
845   RepeatedPtrFieldBase::MergeFrom<TypeHandler>(other);
846 }
847 
848 template <typename Element>
mutable_data()849 inline Element** RepeatedPtrField<Element>::mutable_data() {
850   return RepeatedPtrFieldBase::mutable_data<TypeHandler>();
851 }
852 
853 template <typename Element>
data()854 inline const Element* const* RepeatedPtrField<Element>::data() const {
855   return RepeatedPtrFieldBase::data<TypeHandler>();
856 }
857 
858 template <typename Element>
Swap(RepeatedPtrField * other)859 void RepeatedPtrField<Element>::Swap(RepeatedPtrField* other) {
860   RepeatedPtrFieldBase::Swap(other);
861 }
862 
863 template <typename Element>
SwapElements(int index1,int index2)864 void RepeatedPtrField<Element>::SwapElements(int index1, int index2) {
865   RepeatedPtrFieldBase::SwapElements(index1, index2);
866 }
867 
868 template <typename Element>
SpaceUsedExcludingSelf()869 inline int RepeatedPtrField<Element>::SpaceUsedExcludingSelf() const {
870   return RepeatedPtrFieldBase::SpaceUsedExcludingSelf<TypeHandler>();
871 }
872 
873 template <typename Element>
AddAllocated(Element * value)874 inline void RepeatedPtrField<Element>::AddAllocated(Element* value) {
875   RepeatedPtrFieldBase::AddAllocated<TypeHandler>(value);
876 }
877 
878 template <typename Element>
ReleaseLast()879 inline Element* RepeatedPtrField<Element>::ReleaseLast() {
880   return RepeatedPtrFieldBase::ReleaseLast<TypeHandler>();
881 }
882 
883 
884 template <typename Element>
ClearedCount()885 inline int RepeatedPtrField<Element>::ClearedCount() const {
886   return RepeatedPtrFieldBase::ClearedCount();
887 }
888 
889 template <typename Element>
AddCleared(Element * value)890 inline void RepeatedPtrField<Element>::AddCleared(Element* value) {
891   return RepeatedPtrFieldBase::AddCleared<TypeHandler>(value);
892 }
893 
894 template <typename Element>
ReleaseCleared()895 inline Element* RepeatedPtrField<Element>::ReleaseCleared() {
896   return RepeatedPtrFieldBase::ReleaseCleared<TypeHandler>();
897 }
898 
899 template <typename Element>
Reserve(int new_size)900 inline void RepeatedPtrField<Element>::Reserve(int new_size) {
901   return RepeatedPtrFieldBase::Reserve(new_size);
902 }
903 
904 template <typename Element>
Capacity()905 inline int RepeatedPtrField<Element>::Capacity() const {
906   return RepeatedPtrFieldBase::Capacity();
907 }
908 
909 // -------------------------------------------------------------------
910 
911 namespace internal {
912 
913 // STL-like iterator implementation for RepeatedPtrField.  You should not
914 // refer to this class directly; use RepeatedPtrField<T>::iterator instead.
915 //
916 // The iterator for RepeatedPtrField<T>, RepeatedPtrIterator<T>, is
917 // very similar to iterator_ptr<T**> in util/gtl/iterator_adaptors-inl.h,
918 // but adds random-access operators and is modified to wrap a void** base
919 // iterator (since RepeatedPtrField stores its array as a void* array and
920 // casting void** to T** would violate C++ aliasing rules).
921 //
922 // This code based on net/proto/proto-array-internal.h by Jeffrey Yasskin
923 // (jyasskin@google.com).
924 template<typename Element>
925 class RepeatedPtrIterator
926     : public std::iterator<
927           std::random_access_iterator_tag, Element> {
928  public:
929   typedef RepeatedPtrIterator<Element> iterator;
930   typedef std::iterator<
931           std::random_access_iterator_tag, Element> superclass;
932 
933   // Let the compiler know that these are type names, so we don't have to
934   // write "typename" in front of them everywhere.
935   typedef typename superclass::reference reference;
936   typedef typename superclass::pointer pointer;
937   typedef typename superclass::difference_type difference_type;
938 
RepeatedPtrIterator()939   RepeatedPtrIterator() : it_(NULL) {}
RepeatedPtrIterator(void * const * it)940   explicit RepeatedPtrIterator(void* const* it) : it_(it) {}
941 
942   // Allow "upcasting" from RepeatedPtrIterator<T**> to
943   // RepeatedPtrIterator<const T*const*>.
944   template<typename OtherElement>
RepeatedPtrIterator(const RepeatedPtrIterator<OtherElement> & other)945   RepeatedPtrIterator(const RepeatedPtrIterator<OtherElement>& other)
946       : it_(other.it_) {
947     // Force a compiler error if the other type is not convertable to ours.
948     if (false) {
949       implicit_cast<Element*, OtherElement*>(0);
950     }
951   }
952 
953   // dereferenceable
954   reference operator*() const { return *reinterpret_cast<Element*>(*it_); }
955   pointer   operator->() const { return &(operator*()); }
956 
957   // {inc,dec}rementable
958   iterator& operator++() { ++it_; return *this; }
959   iterator  operator++(int) { return iterator(it_++); }
960   iterator& operator--() { --it_; return *this; }
961   iterator  operator--(int) { return iterator(it_--); }
962 
963   // equality_comparable
964   bool operator==(const iterator& x) const { return it_ == x.it_; }
965   bool operator!=(const iterator& x) const { return it_ != x.it_; }
966 
967   // less_than_comparable
968   bool operator<(const iterator& x) const { return it_ < x.it_; }
969   bool operator<=(const iterator& x) const { return it_ <= x.it_; }
970   bool operator>(const iterator& x) const { return it_ > x.it_; }
971   bool operator>=(const iterator& x) const { return it_ >= x.it_; }
972 
973   // addable, subtractable
974   iterator& operator+=(difference_type d) {
975     it_ += d;
976     return *this;
977   }
978   friend iterator operator+(iterator it, difference_type d) {
979     it += d;
980     return it;
981   }
982   friend iterator operator+(difference_type d, iterator it) {
983     it += d;
984     return it;
985   }
986   iterator& operator-=(difference_type d) {
987     it_ -= d;
988     return *this;
989   }
990   friend iterator operator-(iterator it, difference_type d) {
991     it -= d;
992     return it;
993   }
994 
995   // indexable
996   reference operator[](difference_type d) const { return *(*this + d); }
997 
998   // random access iterator
999   difference_type operator-(const iterator& x) const { return it_ - x.it_; }
1000 
1001  private:
1002   template<typename OtherElement>
1003   friend class RepeatedPtrIterator;
1004 
1005   // The internal iterator.
1006   void* const* it_;
1007 };
1008 
1009 // Provide an iterator that operates on pointers to the underlying objects
1010 // rather than the objects themselves as RepeatedPtrIterator does.
1011 // Consider using this when working with stl algorithms that change
1012 // the array.
1013 template<typename Element>
1014 class RepeatedPtrOverPtrsIterator
1015     : public std::iterator<std::random_access_iterator_tag, Element*> {
1016  public:
1017   typedef RepeatedPtrOverPtrsIterator<Element> iterator;
1018   typedef std::iterator<
1019           std::random_access_iterator_tag, Element*> superclass;
1020 
1021   // Let the compiler know that these are type names, so we don't have to
1022   // write "typename" in front of them everywhere.
1023   typedef typename superclass::reference reference;
1024   typedef typename superclass::pointer pointer;
1025   typedef typename superclass::difference_type difference_type;
1026 
RepeatedPtrOverPtrsIterator()1027   RepeatedPtrOverPtrsIterator() : it_(NULL) {}
RepeatedPtrOverPtrsIterator(void ** it)1028   explicit RepeatedPtrOverPtrsIterator(void** it) : it_(it) {}
1029 
1030   // dereferenceable
1031   reference operator*() const { return *reinterpret_cast<Element**>(it_); }
1032   pointer   operator->() const { return &(operator*()); }
1033 
1034   // {inc,dec}rementable
1035   iterator& operator++() { ++it_; return *this; }
1036   iterator  operator++(int) { return iterator(it_++); }
1037   iterator& operator--() { --it_; return *this; }
1038   iterator  operator--(int) { return iterator(it_--); }
1039 
1040   // equality_comparable
1041   bool operator==(const iterator& x) const { return it_ == x.it_; }
1042   bool operator!=(const iterator& x) const { return it_ != x.it_; }
1043 
1044   // less_than_comparable
1045   bool operator<(const iterator& x) const { return it_ < x.it_; }
1046   bool operator<=(const iterator& x) const { return it_ <= x.it_; }
1047   bool operator>(const iterator& x) const { return it_ > x.it_; }
1048   bool operator>=(const iterator& x) const { return it_ >= x.it_; }
1049 
1050   // addable, subtractable
1051   iterator& operator+=(difference_type d) {
1052     it_ += d;
1053     return *this;
1054   }
1055   friend iterator operator+(iterator it, difference_type d) {
1056     it += d;
1057     return it;
1058   }
1059   friend iterator operator+(difference_type d, iterator it) {
1060     it += d;
1061     return it;
1062   }
1063   iterator& operator-=(difference_type d) {
1064     it_ -= d;
1065     return *this;
1066   }
1067   friend iterator operator-(iterator it, difference_type d) {
1068     it -= d;
1069     return it;
1070   }
1071 
1072   // indexable
1073   reference operator[](difference_type d) const { return *(*this + d); }
1074 
1075   // random access iterator
1076   difference_type operator-(const iterator& x) const { return it_ - x.it_; }
1077 
1078  private:
1079   template<typename OtherElement>
1080   friend class RepeatedPtrIterator;
1081 
1082   // The internal iterator.
1083   void** it_;
1084 };
1085 
1086 
1087 }  // namespace internal
1088 
1089 template <typename Element>
1090 inline typename RepeatedPtrField<Element>::iterator
begin()1091 RepeatedPtrField<Element>::begin() {
1092   return iterator(raw_data());
1093 }
1094 template <typename Element>
1095 inline typename RepeatedPtrField<Element>::const_iterator
begin()1096 RepeatedPtrField<Element>::begin() const {
1097   return iterator(raw_data());
1098 }
1099 template <typename Element>
1100 inline typename RepeatedPtrField<Element>::iterator
end()1101 RepeatedPtrField<Element>::end() {
1102   return iterator(raw_data() + size());
1103 }
1104 template <typename Element>
1105 inline typename RepeatedPtrField<Element>::const_iterator
end()1106 RepeatedPtrField<Element>::end() const {
1107   return iterator(raw_data() + size());
1108 }
1109 
1110 template <typename Element>
1111 inline typename RepeatedPtrField<Element>::pointer_iterator
pointer_begin()1112 RepeatedPtrField<Element>::pointer_begin() {
1113   return pointer_iterator(raw_mutable_data());
1114 }
1115 template <typename Element>
1116 inline typename RepeatedPtrField<Element>::pointer_iterator
pointer_end()1117 RepeatedPtrField<Element>::pointer_end() {
1118   return pointer_iterator(raw_mutable_data() + size());
1119 }
1120 
1121 
1122 // Iterators and helper functions that follow the spirit of the STL
1123 // std::back_insert_iterator and std::back_inserter but are tailor-made
1124 // for RepeatedField and RepatedPtrField. Typical usage would be:
1125 //
1126 //   std::copy(some_sequence.begin(), some_sequence.end(),
1127 //             google::protobuf::RepeatedFieldBackInserter(proto.mutable_sequence()));
1128 //
1129 // Ported by johannes from util/gtl/proto-array-iterators-inl.h
1130 
1131 namespace internal {
1132 // A back inserter for RepeatedField objects.
1133 template<typename T> class RepeatedFieldBackInsertIterator
1134     : public std::iterator<std::output_iterator_tag, T> {
1135  public:
RepeatedFieldBackInsertIterator(RepeatedField<T> * const mutable_field)1136   explicit RepeatedFieldBackInsertIterator(
1137       RepeatedField<T>* const mutable_field)
1138       : field_(mutable_field) {
1139   }
1140   RepeatedFieldBackInsertIterator<T>& operator=(const T& value) {
1141     field_->Add(value);
1142     return *this;
1143   }
1144   RepeatedFieldBackInsertIterator<T>& operator*() {
1145     return *this;
1146   }
1147   RepeatedFieldBackInsertIterator<T>& operator++() {
1148     return *this;
1149   }
1150   RepeatedFieldBackInsertIterator<T>& operator++(int ignores_parameter) {
1151     return *this;
1152   }
1153 
1154  private:
1155   RepeatedField<T>* const field_;
1156 };
1157 
1158 // A back inserter for RepeatedPtrField objects.
1159 template<typename T> class RepeatedPtrFieldBackInsertIterator
1160     : public std::iterator<std::output_iterator_tag, T> {
1161  public:
RepeatedPtrFieldBackInsertIterator(RepeatedPtrField<T> * const mutable_field)1162   RepeatedPtrFieldBackInsertIterator(
1163       RepeatedPtrField<T>* const mutable_field)
1164       : field_(mutable_field) {
1165   }
1166   RepeatedPtrFieldBackInsertIterator<T>& operator=(const T& value) {
1167     *field_->Add() = value;
1168     return *this;
1169   }
1170   RepeatedPtrFieldBackInsertIterator<T>& operator=(
1171       const T* const ptr_to_value) {
1172     *field_->Add() = *ptr_to_value;
1173     return *this;
1174   }
1175   RepeatedPtrFieldBackInsertIterator<T>& operator*() {
1176     return *this;
1177   }
1178   RepeatedPtrFieldBackInsertIterator<T>& operator++() {
1179     return *this;
1180   }
1181   RepeatedPtrFieldBackInsertIterator<T>& operator++(int ignores_parameter) {
1182     return *this;
1183   }
1184 
1185  private:
1186   RepeatedPtrField<T>* const field_;
1187 };
1188 
1189 // A back inserter for RepeatedPtrFields that inserts by transfering ownership
1190 // of a pointer.
1191 template<typename T> class AllocatedRepeatedPtrFieldBackInsertIterator
1192     : public std::iterator<std::output_iterator_tag, T> {
1193  public:
AllocatedRepeatedPtrFieldBackInsertIterator(RepeatedPtrField<T> * const mutable_field)1194   explicit AllocatedRepeatedPtrFieldBackInsertIterator(
1195       RepeatedPtrField<T>* const mutable_field)
1196       : field_(mutable_field) {
1197   }
1198   AllocatedRepeatedPtrFieldBackInsertIterator<T>& operator=(
1199       T* const ptr_to_value) {
1200     field_->AddAllocated(ptr_to_value);
1201     return *this;
1202   }
1203   AllocatedRepeatedPtrFieldBackInsertIterator<T>& operator*() {
1204     return *this;
1205   }
1206   AllocatedRepeatedPtrFieldBackInsertIterator<T>& operator++() {
1207     return *this;
1208   }
1209   AllocatedRepeatedPtrFieldBackInsertIterator<T>& operator++(
1210       int ignores_parameter) {
1211     return *this;
1212   }
1213 
1214  private:
1215   RepeatedPtrField<T>* const field_;
1216 };
1217 }  // namespace internal
1218 
1219 // Provides a back insert iterator for RepeatedField instances,
1220 // similar to std::back_inserter(). Note the identically named
1221 // function for RepeatedPtrField instances.
1222 template<typename T> internal::RepeatedFieldBackInsertIterator<T>
RepeatedFieldBackInserter(RepeatedField<T> * const mutable_field)1223 RepeatedFieldBackInserter(RepeatedField<T>* const mutable_field) {
1224   return internal::RepeatedFieldBackInsertIterator<T>(mutable_field);
1225 }
1226 
1227 // Provides a back insert iterator for RepeatedPtrField instances,
1228 // similar to std::back_inserter(). Note the identically named
1229 // function for RepeatedField instances.
1230 template<typename T> internal::RepeatedPtrFieldBackInsertIterator<T>
RepeatedFieldBackInserter(RepeatedPtrField<T> * const mutable_field)1231 RepeatedFieldBackInserter(RepeatedPtrField<T>* const mutable_field) {
1232   return internal::RepeatedPtrFieldBackInsertIterator<T>(mutable_field);
1233 }
1234 
1235 // Provides a back insert iterator for RepeatedPtrField instances
1236 // similar to std::back_inserter() which transfers the ownership while
1237 // copying elements.
1238 template<typename T> internal::AllocatedRepeatedPtrFieldBackInsertIterator<T>
AllocatedRepeatedPtrFieldBackInserter(RepeatedPtrField<T> * const mutable_field)1239 AllocatedRepeatedPtrFieldBackInserter(
1240     RepeatedPtrField<T>* const mutable_field) {
1241   return internal::AllocatedRepeatedPtrFieldBackInsertIterator<T>(
1242       mutable_field);
1243 }
1244 
1245 }  // namespace protobuf
1246 
1247 }  // namespace google
1248 #endif  // GOOGLE_PROTOBUF_REPEATED_FIELD_H__
1249