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