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