BWAPI
Undermind/proxy/cpp/include/google/protobuf/repeated_field.h
Go to the documentation of this file.
00001 // Protocol Buffers - Google's data interchange format
00002 // Copyright 2008 Google Inc.  All rights reserved.
00003 // http://code.google.com/p/protobuf/
00004 //
00005 // Redistribution and use in source and binary forms, with or without
00006 // modification, are permitted provided that the following conditions are
00007 // met:
00008 //
00009 //     * Redistributions of source code must retain the above copyright
00010 // notice, this list of conditions and the following disclaimer.
00011 //     * Redistributions in binary form must reproduce the above
00012 // copyright notice, this list of conditions and the following disclaimer
00013 // in the documentation and/or other materials provided with the
00014 // distribution.
00015 //     * Neither the name of Google Inc. nor the names of its
00016 // contributors may be used to endorse or promote products derived from
00017 // this software without specific prior written permission.
00018 //
00019 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00020 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00021 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
00022 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
00023 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
00024 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
00025 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
00026 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
00027 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00028 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
00029 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00030 
00031 // Author: kenton@google.com (Kenton Varda)
00032 //  Based on original Protocol Buffers design by
00033 //  Sanjay Ghemawat, Jeff Dean, and others.
00034 //
00035 // RepeatedField and RepeatedPtrField are used by generated protocol message
00036 // classes to manipulate repeated fields.  These classes are very similar to
00037 // STL's vector, but include a number of optimizations found to be useful
00038 // specifically in the case of Protocol Buffers.  RepeatedPtrField is
00039 // particularly different from STL vector as it manages ownership of the
00040 // pointers that it contains.
00041 //
00042 // Typically, clients should not need to access RepeatedField objects directly,
00043 // but should instead use the accessor functions generated automatically by the
00044 // protocol compiler.
00045 
00046 #ifndef GOOGLE_PROTOBUF_REPEATED_FIELD_H__
00047 #define GOOGLE_PROTOBUF_REPEATED_FIELD_H__
00048 
00049 #include <string>
00050 #include <iterator>
00051 #include <google/protobuf/stubs/common.h>
00052 #include <google/protobuf/message_lite.h>
00053 
00054 namespace google {
00055 
00056 namespace protobuf {
00057 
00058 class Message;
00059 
00060 namespace internal {
00061 
00062 // We need this (from generated_message_reflection.cc).
00063 LIBPROTOBUF_EXPORT int StringSpaceUsedExcludingSelf(const string& str);
00064 
00065 }  // namespace internal
00066 
00067 // RepeatedField is used to represent repeated fields of a primitive type (in
00068 // other words, everything except strings and nested Messages).  Most users will
00069 // not ever use a RepeatedField directly; they will use the get-by-index,
00070 // set-by-index, and add accessors that are generated for all repeated fields.
00071 template <typename Element>
00072 class RepeatedField {
00073  public:
00074   RepeatedField();
00075   ~RepeatedField();
00076 
00077   int size() const;
00078 
00079   const Element& Get(int index) const;
00080   Element* Mutable(int index);
00081   void Set(int index, const Element& value);
00082   void Add(const Element& value);
00083   Element* Add();
00084   // Remove the last element in the array.
00085   // We don't provide a way to remove any element other than the last
00086   // because it invites inefficient use, such as O(n^2) filtering loops
00087   // that should have been O(n).  If you want to remove an element other
00088   // than the last, the best way to do it is to re-arrange the elements
00089   // so that the one you want removed is at the end, then call RemoveLast().
00090   void RemoveLast();
00091   void Clear();
00092   void MergeFrom(const RepeatedField& other);
00093 
00094   // Reserve space to expand the field to at least the given size.  If the
00095   // array is grown, it will always be at least doubled in size.
00096   void Reserve(int new_size);
00097 
00098   // Resize the RepeatedField to a new, smaller size.  This is O(1).
00099   void Truncate(int new_size);
00100 
00101   void AddAlreadyReserved(const Element& value);
00102   Element* AddAlreadyReserved();
00103   int Capacity() const;
00104 
00105   // Gets the underlying array.  This pointer is possibly invalidated by
00106   // any add or remove operation.
00107   Element* mutable_data();
00108   const Element* data() const;
00109 
00110   // Swap entire contents with "other".
00111   void Swap(RepeatedField* other);
00112 
00113   // Swap two elements.
00114   void SwapElements(int index1, int index2);
00115 
00116   // STL-like iterator support
00117   typedef Element* iterator;
00118   typedef const Element* const_iterator;
00119 
00120   iterator begin();
00121   const_iterator begin() const;
00122   iterator end();
00123   const_iterator end() const;
00124 
00125   // Returns the number of bytes used by the repeated field, excluding
00126   // sizeof(*this)
00127   int SpaceUsedExcludingSelf() const;
00128 
00129  private:
00130   GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RepeatedField);
00131 
00132   static const int kInitialSize = 4;
00133 
00134   Element* elements_;
00135   int      current_size_;
00136   int      total_size_;
00137 
00138   Element  initial_space_[kInitialSize];
00139 
00140   // Move the contents of |from| into |to|, possibly clobbering |from| in the
00141   // process.  For primitive types this is just a memcpy(), but it could be
00142   // specialized for non-primitive types to, say, swap each element instead.
00143   void MoveArray(Element to[], Element from[], int size);
00144 
00145   // Copy the elements of |from| into |to|.
00146   void CopyArray(Element to[], const Element from[], int size);
00147 };
00148 
00149 namespace internal {
00150 template <typename It> class RepeatedPtrIterator;
00151 template <typename It> class RepeatedPtrOverPtrsIterator;
00152 }  // namespace internal
00153 
00154 namespace internal {
00155 
00156 // This is the common base class for RepeatedPtrFields.  It deals only in void*
00157 // pointers.  Users should not use this interface directly.
00158 //
00159 // The methods of this interface correspond to the methods of RepeatedPtrField,
00160 // but may have a template argument called TypeHandler.  Its signature is:
00161 //   class TypeHandler {
00162 //    public:
00163 //     typedef MyType Type;
00164 //     static Type* New();
00165 //     static void Delete(Type*);
00166 //     static void Clear(Type*);
00167 //     static void Merge(const Type& from, Type* to);
00168 //
00169 //     // Only needs to be implemented if SpaceUsedExcludingSelf() is called.
00170 //     static int SpaceUsed(const Type&);
00171 //   };
00172 class LIBPROTOBUF_EXPORT RepeatedPtrFieldBase {
00173  protected:
00174   // The reflection implementation needs to call protected methods directly,
00175   // reinterpreting pointers as being to Message instead of a specific Message
00176   // subclass.
00177   friend class GeneratedMessageReflection;
00178 
00179   // ExtensionSet stores repeated message extensions as
00180   // RepeatedPtrField<MessageLite>, but non-lite ExtensionSets need to
00181   // implement SpaceUsed(), and thus need to call SpaceUsedExcludingSelf()
00182   // reinterpreting MessageLite as Message.  ExtensionSet also needs to make
00183   // use of AddFromCleared(), which is not part of the public interface.
00184   friend class ExtensionSet;
00185 
00186   RepeatedPtrFieldBase();
00187 
00188   // Must be called from destructor.
00189   template <typename TypeHandler>
00190   void Destroy();
00191 
00192   int size() const;
00193 
00194   template <typename TypeHandler>
00195   const typename TypeHandler::Type& Get(int index) const;
00196   template <typename TypeHandler>
00197   typename TypeHandler::Type* Mutable(int index);
00198   template <typename TypeHandler>
00199   typename TypeHandler::Type* Add();
00200   template <typename TypeHandler>
00201   void RemoveLast();
00202   template <typename TypeHandler>
00203   void Clear();
00204   template <typename TypeHandler>
00205   void MergeFrom(const RepeatedPtrFieldBase& other);
00206 
00207   void Reserve(int new_size);
00208 
00209   int Capacity() const;
00210 
00211   // Used for constructing iterators.
00212   void* const* raw_data() const;
00213   void** raw_mutable_data() const;
00214 
00215   template <typename TypeHandler>
00216   typename TypeHandler::Type** mutable_data();
00217   template <typename TypeHandler>
00218   const typename TypeHandler::Type* const* data() const;
00219 
00220   void Swap(RepeatedPtrFieldBase* other);
00221 
00222   void SwapElements(int index1, int index2);
00223 
00224   template <typename TypeHandler>
00225   int SpaceUsedExcludingSelf() const;
00226 
00227 
00228   // Advanced memory management --------------------------------------
00229 
00230   // Like Add(), but if there are no cleared objects to use, returns NULL.
00231   template <typename TypeHandler>
00232   typename TypeHandler::Type* AddFromCleared();
00233 
00234   template <typename TypeHandler>
00235   void AddAllocated(typename TypeHandler::Type* value);
00236   template <typename TypeHandler>
00237   typename TypeHandler::Type* ReleaseLast();
00238 
00239   int ClearedCount() const;
00240   template <typename TypeHandler>
00241   void AddCleared(typename TypeHandler::Type* value);
00242   template <typename TypeHandler>
00243   typename TypeHandler::Type* ReleaseCleared();
00244 
00245  private:
00246   GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RepeatedPtrFieldBase);
00247 
00248   static const int kInitialSize = 4;
00249 
00250   void** elements_;
00251   int    current_size_;
00252   int    allocated_size_;
00253   int    total_size_;
00254 
00255   void*  initial_space_[kInitialSize];
00256 
00257   template <typename TypeHandler>
00258   static inline typename TypeHandler::Type* cast(void* element) {
00259     return reinterpret_cast<typename TypeHandler::Type*>(element);
00260   }
00261   template <typename TypeHandler>
00262   static inline const typename TypeHandler::Type* cast(const void* element) {
00263     return reinterpret_cast<const typename TypeHandler::Type*>(element);
00264   }
00265 };
00266 
00267 template <typename GenericType>
00268 class GenericTypeHandler {
00269  public:
00270   typedef GenericType Type;
00271   static GenericType* New() { return new GenericType; }
00272   static void Delete(GenericType* value) { delete value; }
00273   static void Clear(GenericType* value) { value->Clear(); }
00274   static void Merge(const GenericType& from, GenericType* to) {
00275     to->MergeFrom(from);
00276   }
00277   static int SpaceUsed(const GenericType& value) { return value.SpaceUsed(); }
00278 };
00279 
00280 template <>
00281 inline void GenericTypeHandler<MessageLite>::Merge(
00282     const MessageLite& from, MessageLite* to) {
00283   to->CheckTypeAndMergeFrom(from);
00284 }
00285 
00286 // HACK:  If a class is declared as DLL-exported in MSVC, it insists on
00287 //   generating copies of all its methods -- even inline ones -- to include
00288 //   in the DLL.  But SpaceUsed() calls StringSpaceUsedExcludingSelf() which
00289 //   isn't in the lite library, therefore the lite library cannot link if
00290 //   StringTypeHandler is exported.  So, we factor out StringTypeHandlerBase,
00291 //   export that, then make StringTypeHandler be a subclass which is NOT
00292 //   exported.
00293 // TODO(kenton):  There has to be a better way.
00294 class LIBPROTOBUF_EXPORT StringTypeHandlerBase {
00295  public:
00296   typedef string Type;
00297   static string* New();
00298   static void Delete(string* value);
00299   static void Clear(string* value) { value->clear(); }
00300   static void Merge(const string& from, string* to) { *to = from; }
00301 };
00302 
00303 class StringTypeHandler : public StringTypeHandlerBase {
00304  public:
00305   static int SpaceUsed(const string& value)  {
00306     return sizeof(value) + StringSpaceUsedExcludingSelf(value);
00307   }
00308 };
00309 
00310 
00311 }  // namespace internal
00312 
00313 // RepeatedPtrField is like RepeatedField, but used for repeated strings or
00314 // Messages.
00315 template <typename Element>
00316 class RepeatedPtrField : public internal::RepeatedPtrFieldBase {
00317  public:
00318   RepeatedPtrField();
00319 
00320   ~RepeatedPtrField();
00321 
00322   int size() const;
00323 
00324   const Element& Get(int index) const;
00325   Element* Mutable(int index);
00326   Element* Add();
00327   void RemoveLast();  // Remove the last element in the array.
00328   void Clear();
00329   void MergeFrom(const RepeatedPtrField& other);
00330 
00331   // Reserve space to expand the field to at least the given size.  This only
00332   // resizes the pointer array; it doesn't allocate any objects.  If the
00333   // array is grown, it will always be at least doubled in size.
00334   void Reserve(int new_size);
00335 
00336   int Capacity() const;
00337 
00338   // Gets the underlying array.  This pointer is possibly invalidated by
00339   // any add or remove operation.
00340   Element** mutable_data();
00341   const Element* const* data() const;
00342 
00343   // Swap entire contents with "other".
00344   void Swap(RepeatedPtrField* other);
00345 
00346   // Swap two elements.
00347   void SwapElements(int index1, int index2);
00348 
00349   // STL-like iterator support
00350   typedef internal::RepeatedPtrIterator<Element> iterator;
00351   typedef internal::RepeatedPtrIterator<const Element> const_iterator;
00352 
00353   iterator begin();
00354   const_iterator begin() const;
00355   iterator end();
00356   const_iterator end() const;
00357 
00358   // Custom STL-like iterator that iterates over and returns the underlying
00359   // pointers to Element rather than Element itself.
00360   typedef internal::RepeatedPtrOverPtrsIterator<Element> pointer_iterator;
00361   pointer_iterator pointer_begin();
00362   pointer_iterator pointer_end();
00363 
00364   // Returns (an estimate of) the number of bytes used by the repeated field,
00365   // excluding sizeof(*this).
00366   int SpaceUsedExcludingSelf() const;
00367 
00368   // The spaced used just by the pointer array, not counting the objects pointed
00369   // at.  Returns zero if the array is inlined (i.e. initial_space_ is being
00370   // used).
00371   int SpaceUsedByArray() const;
00372 
00373   // Advanced memory management --------------------------------------
00374   // When hardcore memory management becomes necessary -- as it often
00375   // does here at Google -- the following methods may be useful.
00376 
00377   // Add an already-allocated object, passing ownership to the
00378   // RepeatedPtrField.
00379   void AddAllocated(Element* value);
00380   // Remove the last element and return it, passing ownership to the
00381   // caller.
00382   // Requires:  size() > 0
00383   Element* ReleaseLast();
00384 
00385   // When elements are removed by calls to RemoveLast() or Clear(), they
00386   // are not actually freed.  Instead, they are cleared and kept so that
00387   // they can be reused later.  This can save lots of CPU time when
00388   // repeatedly reusing a protocol message for similar purposes.
00389   //
00390   // Really, extremely hardcore programs may actually want to manipulate
00391   // these objects to better-optimize memory management.  These methods
00392   // allow that.
00393 
00394   // Get the number of cleared objects that are currently being kept
00395   // around for reuse.
00396   int ClearedCount() const;
00397   // Add an element to the pool of cleared objects, passing ownership to
00398   // the RepeatedPtrField.  The element must be cleared prior to calling
00399   // this method.
00400   void AddCleared(Element* value);
00401   // Remove a single element from the cleared pool and return it, passing
00402   // ownership to the caller.  The element is guaranteed to be cleared.
00403   // Requires:  ClearedCount() > 0
00404   Element* ReleaseCleared();
00405 
00406  protected:
00407   // Note:  RepeatedPtrField SHOULD NOT be subclassed by users.  We only
00408   //   subclass it in one place as a hack for compatibility with proto1.  The
00409   //   subclass needs to know about TypeHandler in order to call protected
00410   //   methods on RepeatedPtrFieldBase.
00411   class TypeHandler;
00412 
00413 
00414  private:
00415   GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RepeatedPtrField);
00416 };
00417 
00418 // implementation ====================================================
00419 
00420 template <typename Element>
00421 inline RepeatedField<Element>::RepeatedField()
00422   : elements_(initial_space_),
00423     current_size_(0),
00424     total_size_(kInitialSize) {
00425 }
00426 
00427 template <typename Element>
00428 RepeatedField<Element>::~RepeatedField() {
00429   if (elements_ != initial_space_) {
00430     delete [] elements_;
00431   }
00432 }
00433 
00434 template <typename Element>
00435 inline int RepeatedField<Element>::size() const {
00436   return current_size_;
00437 }
00438 
00439 template <typename Element>
00440 inline int RepeatedField<Element>::Capacity() const {
00441   return total_size_;
00442 }
00443 
00444 template<typename Element>
00445 inline void RepeatedField<Element>::AddAlreadyReserved(const Element& value) {
00446   GOOGLE_DCHECK_LT(size(), Capacity());
00447   elements_[current_size_++] = value;
00448 }
00449 
00450 template<typename Element>
00451 inline Element* RepeatedField<Element>::AddAlreadyReserved() {
00452   GOOGLE_DCHECK_LT(size(), Capacity());
00453   return &elements_[current_size_++];
00454 }
00455 
00456 template <typename Element>
00457 inline const Element& RepeatedField<Element>::Get(int index) const {
00458   GOOGLE_DCHECK_LT(index, size());
00459   return elements_[index];
00460 }
00461 
00462 template <typename Element>
00463 inline Element* RepeatedField<Element>::Mutable(int index) {
00464   GOOGLE_DCHECK_LT(index, size());
00465   return elements_ + index;
00466 }
00467 
00468 template <typename Element>
00469 inline void RepeatedField<Element>::Set(int index, const Element& value) {
00470   GOOGLE_DCHECK_LT(index, size());
00471   elements_[index] = value;
00472 }
00473 
00474 template <typename Element>
00475 inline void RepeatedField<Element>::Add(const Element& value) {
00476   if (current_size_ == total_size_) Reserve(total_size_ + 1);
00477   elements_[current_size_++] = value;
00478 }
00479 
00480 template <typename Element>
00481 inline Element* RepeatedField<Element>::Add() {
00482   if (current_size_ == total_size_) Reserve(total_size_ + 1);
00483   return &elements_[current_size_++];
00484 }
00485 
00486 template <typename Element>
00487 inline void RepeatedField<Element>::RemoveLast() {
00488   GOOGLE_DCHECK_GT(current_size_, 0);
00489   --current_size_;
00490 }
00491 
00492 template <typename Element>
00493 inline void RepeatedField<Element>::Clear() {
00494   current_size_ = 0;
00495 }
00496 
00497 template <typename Element>
00498 inline void RepeatedField<Element>::MergeFrom(const RepeatedField& other) {
00499   Reserve(current_size_ + other.current_size_);
00500   CopyArray(elements_ + current_size_, other.elements_, other.current_size_);
00501   current_size_ += other.current_size_;
00502 }
00503 
00504 template <typename Element>
00505 inline Element* RepeatedField<Element>::mutable_data() {
00506   return elements_;
00507 }
00508 
00509 template <typename Element>
00510 inline const Element* RepeatedField<Element>::data() const {
00511   return elements_;
00512 }
00513 
00514 
00515 template <typename Element>
00516 void RepeatedField<Element>::Swap(RepeatedField* other) {
00517   Element* swap_elements     = elements_;
00518   int      swap_current_size = current_size_;
00519   int      swap_total_size   = total_size_;
00520   // We may not be using initial_space_ but it's not worth checking.  Just
00521   // copy it anyway.
00522   Element swap_initial_space[kInitialSize];
00523   MoveArray(swap_initial_space, initial_space_, kInitialSize);
00524 
00525   elements_     = other->elements_;
00526   current_size_ = other->current_size_;
00527   total_size_   = other->total_size_;
00528   MoveArray(initial_space_, other->initial_space_, kInitialSize);
00529 
00530   other->elements_     = swap_elements;
00531   other->current_size_ = swap_current_size;
00532   other->total_size_   = swap_total_size;
00533   MoveArray(other->initial_space_, swap_initial_space, kInitialSize);
00534 
00535   if (elements_ == other->initial_space_) {
00536     elements_ = initial_space_;
00537   }
00538   if (other->elements_ == initial_space_) {
00539     other->elements_ = other->initial_space_;
00540   }
00541 }
00542 
00543 template <typename Element>
00544 void RepeatedField<Element>::SwapElements(int index1, int index2) {
00545   std::swap(elements_[index1], elements_[index2]);
00546 }
00547 
00548 template <typename Element>
00549 inline typename RepeatedField<Element>::iterator
00550 RepeatedField<Element>::begin() {
00551   return elements_;
00552 }
00553 template <typename Element>
00554 inline typename RepeatedField<Element>::const_iterator
00555 RepeatedField<Element>::begin() const {
00556   return elements_;
00557 }
00558 template <typename Element>
00559 inline typename RepeatedField<Element>::iterator
00560 RepeatedField<Element>::end() {
00561   return elements_ + current_size_;
00562 }
00563 template <typename Element>
00564 inline typename RepeatedField<Element>::const_iterator
00565 RepeatedField<Element>::end() const {
00566   return elements_ + current_size_;
00567 }
00568 
00569 template <typename Element>
00570 inline int RepeatedField<Element>::SpaceUsedExcludingSelf() const {
00571   return (elements_ != initial_space_) ? total_size_ * sizeof(elements_[0]) : 0;
00572 }
00573 
00574 // Avoid inlining of Reserve(): new, memcpy, and delete[] lead to a significant
00575 // amount of code bloat.
00576 template <typename Element>
00577 void RepeatedField<Element>::Reserve(int new_size) {
00578   if (total_size_ >= new_size) return;
00579 
00580   Element* old_elements = elements_;
00581   total_size_ = max(total_size_ * 2, new_size);
00582   elements_ = new Element[total_size_];
00583   MoveArray(elements_, old_elements, current_size_);
00584   if (old_elements != initial_space_) {
00585     delete [] old_elements;
00586   }
00587 }
00588 
00589 template <typename Element>
00590 inline void RepeatedField<Element>::Truncate(int new_size) {
00591   GOOGLE_DCHECK_LE(new_size, current_size_);
00592   current_size_ = new_size;
00593 }
00594 
00595 template <typename Element>
00596 inline void RepeatedField<Element>::MoveArray(
00597     Element to[], Element from[], int size) {
00598   memcpy(to, from, size * sizeof(Element));
00599 }
00600 
00601 template <typename Element>
00602 inline void RepeatedField<Element>::CopyArray(
00603     Element to[], const Element from[], int size) {
00604   memcpy(to, from, size * sizeof(Element));
00605 }
00606 
00607 
00608 // -------------------------------------------------------------------
00609 
00610 namespace internal {
00611 
00612 inline RepeatedPtrFieldBase::RepeatedPtrFieldBase()
00613   : elements_(initial_space_),
00614     current_size_(0),
00615     allocated_size_(0),
00616     total_size_(kInitialSize) {
00617 }
00618 
00619 template <typename TypeHandler>
00620 void RepeatedPtrFieldBase::Destroy() {
00621   for (int i = 0; i < allocated_size_; i++) {
00622     TypeHandler::Delete(cast<TypeHandler>(elements_[i]));
00623   }
00624   if (elements_ != initial_space_) {
00625     delete [] elements_;
00626   }
00627 }
00628 
00629 inline int RepeatedPtrFieldBase::size() const {
00630   return current_size_;
00631 }
00632 
00633 
00634 template <typename TypeHandler>
00635 inline const typename TypeHandler::Type&
00636 RepeatedPtrFieldBase::Get(int index) const {
00637   GOOGLE_DCHECK_LT(index, size());
00638   return *cast<TypeHandler>(elements_[index]);
00639 }
00640 
00641 template <typename TypeHandler>
00642 inline typename TypeHandler::Type*
00643 RepeatedPtrFieldBase::Mutable(int index) {
00644   GOOGLE_DCHECK_LT(index, size());
00645   return cast<TypeHandler>(elements_[index]);
00646 }
00647 
00648 template <typename TypeHandler>
00649 inline typename TypeHandler::Type* RepeatedPtrFieldBase::Add() {
00650   if (current_size_ < allocated_size_) {
00651     return cast<TypeHandler>(elements_[current_size_++]);
00652   }
00653   if (allocated_size_ == total_size_) Reserve(total_size_ + 1);
00654   ++allocated_size_;
00655   typename TypeHandler::Type* result = TypeHandler::New();
00656   elements_[current_size_++] = result;
00657   return result;
00658 }
00659 
00660 template <typename TypeHandler>
00661 inline void RepeatedPtrFieldBase::RemoveLast() {
00662   GOOGLE_DCHECK_GT(current_size_, 0);
00663   TypeHandler::Clear(cast<TypeHandler>(elements_[--current_size_]));
00664 }
00665 
00666 template <typename TypeHandler>
00667 void RepeatedPtrFieldBase::Clear() {
00668   for (int i = 0; i < current_size_; i++) {
00669     TypeHandler::Clear(cast<TypeHandler>(elements_[i]));
00670   }
00671   current_size_ = 0;
00672 }
00673 
00674 template <typename TypeHandler>
00675 inline void RepeatedPtrFieldBase::MergeFrom(const RepeatedPtrFieldBase& other) {
00676   Reserve(current_size_ + other.current_size_);
00677   for (int i = 0; i < other.current_size_; i++) {
00678     TypeHandler::Merge(other.Get<TypeHandler>(i), Add<TypeHandler>());
00679   }
00680 }
00681 
00682 inline int RepeatedPtrFieldBase::Capacity() const {
00683   return total_size_;
00684 }
00685 
00686 inline void* const* RepeatedPtrFieldBase::raw_data() const {
00687   return elements_;
00688 }
00689 
00690 inline void** RepeatedPtrFieldBase::raw_mutable_data() const {
00691   return elements_;
00692 }
00693 
00694 template <typename TypeHandler>
00695 inline typename TypeHandler::Type** RepeatedPtrFieldBase::mutable_data() {
00696   // TODO(kenton):  Breaks C++ aliasing rules.  We should probably remove this
00697   //   method entirely.
00698   return reinterpret_cast<typename TypeHandler::Type**>(elements_);
00699 }
00700 
00701 template <typename TypeHandler>
00702 inline const typename TypeHandler::Type* const*
00703 RepeatedPtrFieldBase::data() const {
00704   // TODO(kenton):  Breaks C++ aliasing rules.  We should probably remove this
00705   //   method entirely.
00706   return reinterpret_cast<const typename TypeHandler::Type* const*>(elements_);
00707 }
00708 
00709 inline void RepeatedPtrFieldBase::SwapElements(int index1, int index2) {
00710   std::swap(elements_[index1], elements_[index2]);
00711 }
00712 
00713 template <typename TypeHandler>
00714 inline int RepeatedPtrFieldBase::SpaceUsedExcludingSelf() const {
00715   int allocated_bytes =
00716       (elements_ != initial_space_) ? total_size_ * sizeof(elements_[0]) : 0;
00717   for (int i = 0; i < allocated_size_; ++i) {
00718     allocated_bytes += TypeHandler::SpaceUsed(*cast<TypeHandler>(elements_[i]));
00719   }
00720   return allocated_bytes;
00721 }
00722 
00723 template <typename TypeHandler>
00724 inline typename TypeHandler::Type* RepeatedPtrFieldBase::AddFromCleared() {
00725   if (current_size_ < allocated_size_) {
00726     return cast<TypeHandler>(elements_[current_size_++]);
00727   } else {
00728     return NULL;
00729   }
00730 }
00731 
00732 template <typename TypeHandler>
00733 void RepeatedPtrFieldBase::AddAllocated(
00734     typename TypeHandler::Type* value) {
00735   // Make room for the new pointer.
00736   if (current_size_ == total_size_) {
00737     // The array is completely full with no cleared objects, so grow it.
00738     Reserve(total_size_ + 1);
00739     ++allocated_size_;
00740   } else if (allocated_size_ == total_size_) {
00741     // There is no more space in the pointer array because it contains some
00742     // cleared objects awaiting reuse.  We don't want to grow the array in this
00743     // case because otherwise a loop calling AddAllocated() followed by Clear()
00744     // would leak memory.
00745     TypeHandler::Delete(cast<TypeHandler>(elements_[current_size_]));
00746   } else if (current_size_ < allocated_size_) {
00747     // We have some cleared objects.  We don't care about their order, so we
00748     // can just move the first one to the end to make space.
00749     elements_[allocated_size_] = elements_[current_size_];
00750     ++allocated_size_;
00751   } else {
00752     // There are no cleared objects.
00753     ++allocated_size_;
00754   }
00755 
00756   elements_[current_size_++] = value;
00757 }
00758 
00759 template <typename TypeHandler>
00760 inline typename TypeHandler::Type* RepeatedPtrFieldBase::ReleaseLast() {
00761   GOOGLE_DCHECK_GT(current_size_, 0);
00762   typename TypeHandler::Type* result =
00763       cast<TypeHandler>(elements_[--current_size_]);
00764   --allocated_size_;
00765   if (current_size_ < allocated_size_) {
00766     // There are cleared elements on the end; replace the removed element
00767     // with the last allocated element.
00768     elements_[current_size_] = elements_[allocated_size_];
00769   }
00770   return result;
00771 }
00772 
00773 
00774 inline int RepeatedPtrFieldBase::ClearedCount() const {
00775   return allocated_size_ - current_size_;
00776 }
00777 
00778 template <typename TypeHandler>
00779 inline void RepeatedPtrFieldBase::AddCleared(
00780     typename TypeHandler::Type* value) {
00781   if (allocated_size_ == total_size_) Reserve(total_size_ + 1);
00782   elements_[allocated_size_++] = value;
00783 }
00784 
00785 template <typename TypeHandler>
00786 inline typename TypeHandler::Type* RepeatedPtrFieldBase::ReleaseCleared() {
00787   GOOGLE_DCHECK_GT(allocated_size_, current_size_);
00788   return cast<TypeHandler>(elements_[--allocated_size_]);
00789 }
00790 
00791 }  // namespace internal
00792 
00793 // -------------------------------------------------------------------
00794 
00795 template <typename Element>
00796 class RepeatedPtrField<Element>::TypeHandler
00797     : public internal::GenericTypeHandler<Element> {};
00798 
00799 template <>
00800 class RepeatedPtrField<string>::TypeHandler
00801     : public internal::StringTypeHandler {};
00802 
00803 
00804 template <typename Element>
00805 inline RepeatedPtrField<Element>::RepeatedPtrField() {}
00806 
00807 template <typename Element>
00808 RepeatedPtrField<Element>::~RepeatedPtrField() {
00809   Destroy<TypeHandler>();
00810 }
00811 
00812 template <typename Element>
00813 inline int RepeatedPtrField<Element>::size() const {
00814   return RepeatedPtrFieldBase::size();
00815 }
00816 
00817 template <typename Element>
00818 inline const Element& RepeatedPtrField<Element>::Get(int index) const {
00819   return RepeatedPtrFieldBase::Get<TypeHandler>(index);
00820 }
00821 
00822 template <typename Element>
00823 inline Element* RepeatedPtrField<Element>::Mutable(int index) {
00824   return RepeatedPtrFieldBase::Mutable<TypeHandler>(index);
00825 }
00826 
00827 template <typename Element>
00828 inline Element* RepeatedPtrField<Element>::Add() {
00829   return RepeatedPtrFieldBase::Add<TypeHandler>();
00830 }
00831 
00832 template <typename Element>
00833 inline void RepeatedPtrField<Element>::RemoveLast() {
00834   RepeatedPtrFieldBase::RemoveLast<TypeHandler>();
00835 }
00836 
00837 template <typename Element>
00838 inline void RepeatedPtrField<Element>::Clear() {
00839   RepeatedPtrFieldBase::Clear<TypeHandler>();
00840 }
00841 
00842 template <typename Element>
00843 inline void RepeatedPtrField<Element>::MergeFrom(
00844     const RepeatedPtrField& other) {
00845   RepeatedPtrFieldBase::MergeFrom<TypeHandler>(other);
00846 }
00847 
00848 template <typename Element>
00849 inline Element** RepeatedPtrField<Element>::mutable_data() {
00850   return RepeatedPtrFieldBase::mutable_data<TypeHandler>();
00851 }
00852 
00853 template <typename Element>
00854 inline const Element* const* RepeatedPtrField<Element>::data() const {
00855   return RepeatedPtrFieldBase::data<TypeHandler>();
00856 }
00857 
00858 template <typename Element>
00859 void RepeatedPtrField<Element>::Swap(RepeatedPtrField* other) {
00860   RepeatedPtrFieldBase::Swap(other);
00861 }
00862 
00863 template <typename Element>
00864 void RepeatedPtrField<Element>::SwapElements(int index1, int index2) {
00865   RepeatedPtrFieldBase::SwapElements(index1, index2);
00866 }
00867 
00868 template <typename Element>
00869 inline int RepeatedPtrField<Element>::SpaceUsedExcludingSelf() const {
00870   return RepeatedPtrFieldBase::SpaceUsedExcludingSelf<TypeHandler>();
00871 }
00872 
00873 template <typename Element>
00874 inline void RepeatedPtrField<Element>::AddAllocated(Element* value) {
00875   RepeatedPtrFieldBase::AddAllocated<TypeHandler>(value);
00876 }
00877 
00878 template <typename Element>
00879 inline Element* RepeatedPtrField<Element>::ReleaseLast() {
00880   return RepeatedPtrFieldBase::ReleaseLast<TypeHandler>();
00881 }
00882 
00883 
00884 template <typename Element>
00885 inline int RepeatedPtrField<Element>::ClearedCount() const {
00886   return RepeatedPtrFieldBase::ClearedCount();
00887 }
00888 
00889 template <typename Element>
00890 inline void RepeatedPtrField<Element>::AddCleared(Element* value) {
00891   return RepeatedPtrFieldBase::AddCleared<TypeHandler>(value);
00892 }
00893 
00894 template <typename Element>
00895 inline Element* RepeatedPtrField<Element>::ReleaseCleared() {
00896   return RepeatedPtrFieldBase::ReleaseCleared<TypeHandler>();
00897 }
00898 
00899 template <typename Element>
00900 inline void RepeatedPtrField<Element>::Reserve(int new_size) {
00901   return RepeatedPtrFieldBase::Reserve(new_size);
00902 }
00903 
00904 template <typename Element>
00905 inline int RepeatedPtrField<Element>::Capacity() const {
00906   return RepeatedPtrFieldBase::Capacity();
00907 }
00908 
00909 // -------------------------------------------------------------------
00910 
00911 namespace internal {
00912 
00913 // STL-like iterator implementation for RepeatedPtrField.  You should not
00914 // refer to this class directly; use RepeatedPtrField<T>::iterator instead.
00915 //
00916 // The iterator for RepeatedPtrField<T>, RepeatedPtrIterator<T>, is
00917 // very similar to iterator_ptr<T**> in util/gtl/iterator_adaptors-inl.h,
00918 // but adds random-access operators and is modified to wrap a void** base
00919 // iterator (since RepeatedPtrField stores its array as a void* array and
00920 // casting void** to T** would violate C++ aliasing rules).
00921 //
00922 // This code based on net/proto/proto-array-internal.h by Jeffrey Yasskin
00923 // (jyasskin@google.com).
00924 template<typename Element>
00925 class RepeatedPtrIterator
00926     : public std::iterator<
00927           std::random_access_iterator_tag, Element> {
00928  public:
00929   typedef RepeatedPtrIterator<Element> iterator;
00930   typedef std::iterator<
00931           std::random_access_iterator_tag, Element> superclass;
00932 
00933   // Let the compiler know that these are type names, so we don't have to
00934   // write "typename" in front of them everywhere.
00935   typedef typename superclass::reference reference;
00936   typedef typename superclass::pointer pointer;
00937   typedef typename superclass::difference_type difference_type;
00938 
00939   RepeatedPtrIterator() : it_(NULL) {}
00940   explicit RepeatedPtrIterator(void* const* it) : it_(it) {}
00941 
00942   // Allow "upcasting" from RepeatedPtrIterator<T**> to
00943   // RepeatedPtrIterator<const T*const*>.
00944   template<typename OtherElement>
00945   RepeatedPtrIterator(const RepeatedPtrIterator<OtherElement>& other)
00946       : it_(other.it_) {
00947     // Force a compiler error if the other type is not convertable to ours.
00948     if (false) {
00949       implicit_cast<Element*, OtherElement*>(0);
00950     }
00951   }
00952 
00953   // dereferenceable
00954   reference operator*() const { return *reinterpret_cast<Element*>(*it_); }
00955   pointer   operator->() const { return &(operator*()); }
00956 
00957   // {inc,dec}rementable
00958   iterator& operator++() { ++it_; return *this; }
00959   iterator  operator++(int) { return iterator(it_++); }
00960   iterator& operator--() { --it_; return *this; }
00961   iterator  operator--(int) { return iterator(it_--); }
00962 
00963   // equality_comparable
00964   bool operator==(const iterator& x) const { return it_ == x.it_; }
00965   bool operator!=(const iterator& x) const { return it_ != x.it_; }
00966 
00967   // less_than_comparable
00968   bool operator<(const iterator& x) const { return it_ < x.it_; }
00969   bool operator<=(const iterator& x) const { return it_ <= x.it_; }
00970   bool operator>(const iterator& x) const { return it_ > x.it_; }
00971   bool operator>=(const iterator& x) const { return it_ >= x.it_; }
00972 
00973   // addable, subtractable
00974   iterator& operator+=(difference_type d) {
00975     it_ += d;
00976     return *this;
00977   }
00978   friend iterator operator+(iterator it, difference_type d) {
00979     it += d;
00980     return it;
00981   }
00982   friend iterator operator+(difference_type d, iterator it) {
00983     it += d;
00984     return it;
00985   }
00986   iterator& operator-=(difference_type d) {
00987     it_ -= d;
00988     return *this;
00989   }
00990   friend iterator operator-(iterator it, difference_type d) {
00991     it -= d;
00992     return it;
00993   }
00994 
00995   // indexable
00996   reference operator[](difference_type d) const { return *(*this + d); }
00997 
00998   // random access iterator
00999   difference_type operator-(const iterator& x) const { return it_ - x.it_; }
01000 
01001  private:
01002   template<typename OtherElement>
01003   friend class RepeatedPtrIterator;
01004 
01005   // The internal iterator.
01006   void* const* it_;
01007 };
01008 
01009 // Provide an iterator that operates on pointers to the underlying objects
01010 // rather than the objects themselves as RepeatedPtrIterator does.
01011 // Consider using this when working with stl algorithms that change
01012 // the array.
01013 template<typename Element>
01014 class RepeatedPtrOverPtrsIterator
01015     : public std::iterator<std::random_access_iterator_tag, Element*> {
01016  public:
01017   typedef RepeatedPtrOverPtrsIterator<Element> iterator;
01018   typedef std::iterator<
01019           std::random_access_iterator_tag, Element*> superclass;
01020 
01021   // Let the compiler know that these are type names, so we don't have to
01022   // write "typename" in front of them everywhere.
01023   typedef typename superclass::reference reference;
01024   typedef typename superclass::pointer pointer;
01025   typedef typename superclass::difference_type difference_type;
01026 
01027   RepeatedPtrOverPtrsIterator() : it_(NULL) {}
01028   explicit RepeatedPtrOverPtrsIterator(void** it) : it_(it) {}
01029 
01030   // dereferenceable
01031   reference operator*() const { return *reinterpret_cast<Element**>(it_); }
01032   pointer   operator->() const { return &(operator*()); }
01033 
01034   // {inc,dec}rementable
01035   iterator& operator++() { ++it_; return *this; }
01036   iterator  operator++(int) { return iterator(it_++); }
01037   iterator& operator--() { --it_; return *this; }
01038   iterator  operator--(int) { return iterator(it_--); }
01039 
01040   // equality_comparable
01041   bool operator==(const iterator& x) const { return it_ == x.it_; }
01042   bool operator!=(const iterator& x) const { return it_ != x.it_; }
01043 
01044   // less_than_comparable
01045   bool operator<(const iterator& x) const { return it_ < x.it_; }
01046   bool operator<=(const iterator& x) const { return it_ <= x.it_; }
01047   bool operator>(const iterator& x) const { return it_ > x.it_; }
01048   bool operator>=(const iterator& x) const { return it_ >= x.it_; }
01049 
01050   // addable, subtractable
01051   iterator& operator+=(difference_type d) {
01052     it_ += d;
01053     return *this;
01054   }
01055   friend iterator operator+(iterator it, difference_type d) {
01056     it += d;
01057     return it;
01058   }
01059   friend iterator operator+(difference_type d, iterator it) {
01060     it += d;
01061     return it;
01062   }
01063   iterator& operator-=(difference_type d) {
01064     it_ -= d;
01065     return *this;
01066   }
01067   friend iterator operator-(iterator it, difference_type d) {
01068     it -= d;
01069     return it;
01070   }
01071 
01072   // indexable
01073   reference operator[](difference_type d) const { return *(*this + d); }
01074 
01075   // random access iterator
01076   difference_type operator-(const iterator& x) const { return it_ - x.it_; }
01077 
01078  private:
01079   template<typename OtherElement>
01080   friend class RepeatedPtrIterator;
01081 
01082   // The internal iterator.
01083   void** it_;
01084 };
01085 
01086 
01087 }  // namespace internal
01088 
01089 template <typename Element>
01090 inline typename RepeatedPtrField<Element>::iterator
01091 RepeatedPtrField<Element>::begin() {
01092   return iterator(raw_data());
01093 }
01094 template <typename Element>
01095 inline typename RepeatedPtrField<Element>::const_iterator
01096 RepeatedPtrField<Element>::begin() const {
01097   return iterator(raw_data());
01098 }
01099 template <typename Element>
01100 inline typename RepeatedPtrField<Element>::iterator
01101 RepeatedPtrField<Element>::end() {
01102   return iterator(raw_data() + size());
01103 }
01104 template <typename Element>
01105 inline typename RepeatedPtrField<Element>::const_iterator
01106 RepeatedPtrField<Element>::end() const {
01107   return iterator(raw_data() + size());
01108 }
01109 
01110 template <typename Element>
01111 inline typename RepeatedPtrField<Element>::pointer_iterator
01112 RepeatedPtrField<Element>::pointer_begin() {
01113   return pointer_iterator(raw_mutable_data());
01114 }
01115 template <typename Element>
01116 inline typename RepeatedPtrField<Element>::pointer_iterator
01117 RepeatedPtrField<Element>::pointer_end() {
01118   return pointer_iterator(raw_mutable_data() + size());
01119 }
01120 
01121 
01122 // Iterators and helper functions that follow the spirit of the STL
01123 // std::back_insert_iterator and std::back_inserter but are tailor-made
01124 // for RepeatedField and RepatedPtrField. Typical usage would be:
01125 //
01126 //   std::copy(some_sequence.begin(), some_sequence.end(),
01127 //             google::protobuf::RepeatedFieldBackInserter(proto.mutable_sequence()));
01128 //
01129 // Ported by johannes from util/gtl/proto-array-iterators-inl.h
01130 
01131 namespace internal {
01132 // A back inserter for RepeatedField objects.
01133 template<typename T> class RepeatedFieldBackInsertIterator
01134     : public std::iterator<std::output_iterator_tag, T> {
01135  public:
01136   explicit RepeatedFieldBackInsertIterator(
01137       RepeatedField<T>* const mutable_field)
01138       : field_(mutable_field) {
01139   }
01140   RepeatedFieldBackInsertIterator<T>& operator=(const T& value) {
01141     field_->Add(value);
01142     return *this;
01143   }
01144   RepeatedFieldBackInsertIterator<T>& operator*() {
01145     return *this;
01146   }
01147   RepeatedFieldBackInsertIterator<T>& operator++() {
01148     return *this;
01149   }
01150   RepeatedFieldBackInsertIterator<T>& operator++(int ignores_parameter) {
01151     return *this;
01152   }
01153 
01154  private:
01155   RepeatedField<T>* const field_;
01156 };
01157 
01158 // A back inserter for RepeatedPtrField objects.
01159 template<typename T> class RepeatedPtrFieldBackInsertIterator
01160     : public std::iterator<std::output_iterator_tag, T> {
01161  public:
01162   RepeatedPtrFieldBackInsertIterator(
01163       RepeatedPtrField<T>* const mutable_field)
01164       : field_(mutable_field) {
01165   }
01166   RepeatedPtrFieldBackInsertIterator<T>& operator=(const T& value) {
01167     *field_->Add() = value;
01168     return *this;
01169   }
01170   RepeatedPtrFieldBackInsertIterator<T>& operator=(
01171       const T* const ptr_to_value) {
01172     *field_->Add() = *ptr_to_value;
01173     return *this;
01174   }
01175   RepeatedPtrFieldBackInsertIterator<T>& operator*() {
01176     return *this;
01177   }
01178   RepeatedPtrFieldBackInsertIterator<T>& operator++() {
01179     return *this;
01180   }
01181   RepeatedPtrFieldBackInsertIterator<T>& operator++(int ignores_parameter) {
01182     return *this;
01183   }
01184 
01185  private:
01186   RepeatedPtrField<T>* const field_;
01187 };
01188 
01189 // A back inserter for RepeatedPtrFields that inserts by transfering ownership
01190 // of a pointer.
01191 template<typename T> class AllocatedRepeatedPtrFieldBackInsertIterator
01192     : public std::iterator<std::output_iterator_tag, T> {
01193  public:
01194   explicit AllocatedRepeatedPtrFieldBackInsertIterator(
01195       RepeatedPtrField<T>* const mutable_field)
01196       : field_(mutable_field) {
01197   }
01198   AllocatedRepeatedPtrFieldBackInsertIterator<T>& operator=(
01199       T* const ptr_to_value) {
01200     field_->AddAllocated(ptr_to_value);
01201     return *this;
01202   }
01203   AllocatedRepeatedPtrFieldBackInsertIterator<T>& operator*() {
01204     return *this;
01205   }
01206   AllocatedRepeatedPtrFieldBackInsertIterator<T>& operator++() {
01207     return *this;
01208   }
01209   AllocatedRepeatedPtrFieldBackInsertIterator<T>& operator++(
01210       int ignores_parameter) {
01211     return *this;
01212   }
01213 
01214  private:
01215   RepeatedPtrField<T>* const field_;
01216 };
01217 }  // namespace internal
01218 
01219 // Provides a back insert iterator for RepeatedField instances,
01220 // similar to std::back_inserter(). Note the identically named
01221 // function for RepeatedPtrField instances.
01222 template<typename T> internal::RepeatedFieldBackInsertIterator<T>
01223 RepeatedFieldBackInserter(RepeatedField<T>* const mutable_field) {
01224   return internal::RepeatedFieldBackInsertIterator<T>(mutable_field);
01225 }
01226 
01227 // Provides a back insert iterator for RepeatedPtrField instances,
01228 // similar to std::back_inserter(). Note the identically named
01229 // function for RepeatedField instances.
01230 template<typename T> internal::RepeatedPtrFieldBackInsertIterator<T>
01231 RepeatedFieldBackInserter(RepeatedPtrField<T>* const mutable_field) {
01232   return internal::RepeatedPtrFieldBackInsertIterator<T>(mutable_field);
01233 }
01234 
01235 // Provides a back insert iterator for RepeatedPtrField instances
01236 // similar to std::back_inserter() which transfers the ownership while
01237 // copying elements.
01238 template<typename T> internal::AllocatedRepeatedPtrFieldBackInsertIterator<T>
01239 AllocatedRepeatedPtrFieldBackInserter(
01240     RepeatedPtrField<T>* const mutable_field) {
01241   return internal::AllocatedRepeatedPtrFieldBackInsertIterator<T>(
01242       mutable_field);
01243 }
01244 
01245 }  // namespace protobuf
01246 
01247 }  // namespace google
01248 #endif  // GOOGLE_PROTOBUF_REPEATED_FIELD_H__
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines