Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(20)

Side by Side Diff: third_party/protobuf/src/google/protobuf/repeated_field.h

Issue 2590803003: Revert "third_party/protobuf: Update to HEAD (83d681ee2c)" (Closed)
Patch Set: Created 3 years, 12 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Protocol Buffers - Google's data interchange format 1 // Protocol Buffers - Google's data interchange format
2 // Copyright 2008 Google Inc. All rights reserved. 2 // Copyright 2008 Google Inc. All rights reserved.
3 // https://developers.google.com/protocol-buffers/ 3 // https://developers.google.com/protocol-buffers/
4 // 4 //
5 // Redistribution and use in source and binary forms, with or without 5 // Redistribution and use in source and binary forms, with or without
6 // modification, are permitted provided that the following conditions are 6 // modification, are permitted provided that the following conditions are
7 // met: 7 // met:
8 // 8 //
9 // * Redistributions of source code must retain the above copyright 9 // * Redistributions of source code must retain the above copyright
10 // notice, this list of conditions and the following disclaimer. 10 // notice, this list of conditions and the following disclaimer.
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
54 #include <string> 54 #include <string>
55 #include <iterator> 55 #include <iterator>
56 #include <google/protobuf/stubs/casts.h> 56 #include <google/protobuf/stubs/casts.h>
57 #include <google/protobuf/stubs/logging.h> 57 #include <google/protobuf/stubs/logging.h>
58 #include <google/protobuf/stubs/common.h> 58 #include <google/protobuf/stubs/common.h>
59 #include <google/protobuf/stubs/type_traits.h> 59 #include <google/protobuf/stubs/type_traits.h>
60 #include <google/protobuf/arena.h> 60 #include <google/protobuf/arena.h>
61 #include <google/protobuf/generated_message_util.h> 61 #include <google/protobuf/generated_message_util.h>
62 #include <google/protobuf/message_lite.h> 62 #include <google/protobuf/message_lite.h>
63 63
64 namespace google {
64 65
65 // Forward-declare these so that we can make them friends.
66 namespace google {
67 namespace upb { 66 namespace upb {
68 namespace google_opensource { 67 namespace google_opensource {
69 class GMR_Handlers; 68 class GMR_Handlers;
70 } // namespace google_opensource 69 } // namespace google_opensource
71 } // namespace upb 70 } // namespace upb
72 71
73 namespace protobuf { 72 namespace protobuf {
74 73
75 class Message; 74 class Message;
76 75
(...skipping 21 matching lines...) Expand all
98 return CalculateReserve(begin, end, Category()); 97 return CalculateReserve(begin, end, Category());
99 } 98 }
100 } // namespace internal 99 } // namespace internal
101 100
102 101
103 // RepeatedField is used to represent repeated fields of a primitive type (in 102 // RepeatedField is used to represent repeated fields of a primitive type (in
104 // other words, everything except strings and nested Messages). Most users will 103 // other words, everything except strings and nested Messages). Most users will
105 // not ever use a RepeatedField directly; they will use the get-by-index, 104 // not ever use a RepeatedField directly; they will use the get-by-index,
106 // set-by-index, and add accessors that are generated for all repeated fields. 105 // set-by-index, and add accessors that are generated for all repeated fields.
107 template <typename Element> 106 template <typename Element>
108 class RepeatedField PROTOBUF_FINAL { 107 class RepeatedField {
109 public: 108 public:
110 RepeatedField(); 109 RepeatedField();
111 explicit RepeatedField(Arena* arena); 110 explicit RepeatedField(Arena* arena);
112 RepeatedField(const RepeatedField& other); 111 RepeatedField(const RepeatedField& other);
113 template <typename Iter> 112 template <typename Iter>
114 RepeatedField(Iter begin, const Iter& end); 113 RepeatedField(Iter begin, const Iter& end);
115 ~RepeatedField(); 114 ~RepeatedField();
116 115
117 RepeatedField& operator=(const RepeatedField& other); 116 RepeatedField& operator=(const RepeatedField& other);
118 117
119 bool empty() const; 118 bool empty() const;
120 int size() const; 119 int size() const;
121 120
122 const Element& Get(int index) const; 121 const Element& Get(int index) const;
123 Element* Mutable(int index); 122 Element* Mutable(int index);
124
125 const Element& operator[](int index) const { return Get(index); }
126 Element& operator[](int index) { return *Mutable(index); }
127
128 void Set(int index, const Element& value); 123 void Set(int index, const Element& value);
129 void Add(const Element& value); 124 void Add(const Element& value);
130 // Appends a new element and return a pointer to it.
131 // The new element is uninitialized if |Element| is a POD type.
132 Element* Add(); 125 Element* Add();
133 // Remove the last element in the array. 126 // Remove the last element in the array.
134 void RemoveLast(); 127 void RemoveLast();
135 128
136 // Extract elements with indices in "[start .. start+num-1]". 129 // Extract elements with indices in "[start .. start+num-1]".
137 // Copy them into "elements[0 .. num-1]" if "elements" is not NULL. 130 // Copy them into "elements[0 .. num-1]" if "elements" is not NULL.
138 // Caution: implementation also moves elements with indices [start+num ..]. 131 // Caution: implementation also moves elements with indices [start+num ..].
139 // Calling this routine inside a loop can cause quadratic behavior. 132 // Calling this routine inside a loop can cause quadratic behavior.
140 void ExtractSubrange(int start, int num, Element* elements); 133 void ExtractSubrange(int start, int num, Element* elements);
141 134
142 void Clear(); 135 void Clear();
143 void MergeFrom(const RepeatedField& other); 136 void MergeFrom(const RepeatedField& other);
144 void CopyFrom(const RepeatedField& other); 137 void CopyFrom(const RepeatedField& other);
145 138
146 // Reserve space to expand the field to at least the given size. If the 139 // Reserve space to expand the field to at least the given size. If the
147 // array is grown, it will always be at least doubled in size. 140 // array is grown, it will always be at least doubled in size.
148 void Reserve(int new_size); 141 void Reserve(int new_size);
149 142
150 // Resize the RepeatedField to a new, smaller size. This is O(1). 143 // Resize the RepeatedField to a new, smaller size. This is O(1).
151 void Truncate(int new_size); 144 void Truncate(int new_size);
152 145
153 void AddAlreadyReserved(const Element& value); 146 void AddAlreadyReserved(const Element& value);
154 // Appends a new element and return a pointer to it.
155 // The new element is uninitialized if |Element| is a POD type.
156 // Should be called only if Capacity() > Size().
157 Element* AddAlreadyReserved(); 147 Element* AddAlreadyReserved();
158 int Capacity() const; 148 int Capacity() const;
159 149
160 // Like STL resize. Uses value to fill appended elements. 150 // Like STL resize. Uses value to fill appended elements.
161 // Like Truncate() if new_size <= size(), otherwise this is 151 // Like Truncate() if new_size <= size(), otherwise this is
162 // O(new_size - size()). 152 // O(new_size - size()).
163 void Resize(int new_size, const Element& value); 153 void Resize(int new_size, const Element& value);
164 154
165 // Gets the underlying array. This pointer is possibly invalidated by 155 // Gets the underlying array. This pointer is possibly invalidated by
166 // any add or remove operation. 156 // any add or remove operation.
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after
287 // If Element has a trivial destructor (for example, if it's a fundamental 277 // If Element has a trivial destructor (for example, if it's a fundamental
288 // type, like int32), the loop will be removed by the optimizer. 278 // type, like int32), the loop will be removed by the optimizer.
289 void InternalDeallocate(Rep* rep, int size) { 279 void InternalDeallocate(Rep* rep, int size) {
290 if (rep != NULL) { 280 if (rep != NULL) {
291 Element* e = &rep->elements[0]; 281 Element* e = &rep->elements[0];
292 Element* limit = &rep->elements[size]; 282 Element* limit = &rep->elements[size];
293 for (; e < limit; e++) { 283 for (; e < limit; e++) {
294 e->Element::~Element(); 284 e->Element::~Element();
295 } 285 }
296 if (rep->arena == NULL) { 286 if (rep->arena == NULL) {
297 #if defined(__GXX_DELETE_WITH_SIZE__) || defined(__cpp_sized_deallocation) 287 delete[] reinterpret_cast<char*>(rep);
298 const size_t bytes = size * sizeof(*e) + kRepHeaderSize;
299 ::operator delete(static_cast<void*>(rep), bytes);
300 #else
301 ::operator delete(static_cast<void*>(rep));
302 #endif
303 } 288 }
304 } 289 }
305 } 290 }
306 }; 291 };
307 292
308 template<typename Element> 293 template<typename Element>
309 const size_t RepeatedField<Element>::kRepHeaderSize = 294 const size_t RepeatedField<Element>::kRepHeaderSize =
310 reinterpret_cast<size_t>(&reinterpret_cast<Rep*>(16)->elements[0]) - 16; 295 reinterpret_cast<size_t>(&reinterpret_cast<Rep*>(16)->elements[0]) - 16;
311 296
312 namespace internal { 297 namespace internal {
313 template <typename It> class RepeatedPtrIterator; 298 template <typename It> class RepeatedPtrIterator;
314 template <typename It, typename VoidPtr> class RepeatedPtrOverPtrsIterator; 299 template <typename It, typename VoidPtr> class RepeatedPtrOverPtrsIterator;
315 } // namespace internal 300 } // namespace internal
316 301
317 namespace internal { 302 namespace internal {
318 303
319 // This is a helper template to copy an array of elements efficiently when they 304 // This is a helper template to copy an array of elements effeciently when they
320 // have a trivial copy constructor, and correctly otherwise. This really 305 // have a trivial copy constructor, and correctly otherwise. This really
321 // shouldn't be necessary, but our compiler doesn't optimize std::copy very 306 // shouldn't be necessary, but our compiler doesn't optimize std::copy very
322 // effectively. 307 // effectively.
323 template <typename Element, 308 template <typename Element,
324 bool HasTrivialCopy = has_trivial_copy<Element>::value> 309 bool HasTrivialCopy = has_trivial_copy<Element>::value>
325 struct ElementCopier { 310 struct ElementCopier {
326 void operator()(Element* to, const Element* from, int array_size); 311 void operator()(Element* to, const Element* from, int array_size);
327 }; 312 };
328 313
329 } // namespace internal 314 } // namespace internal
(...skipping 242 matching lines...) Expand 10 before | Expand all | Expand 10 after
572 }; 557 };
573 558
574 template <typename GenericType> 559 template <typename GenericType>
575 class GenericTypeHandler { 560 class GenericTypeHandler {
576 public: 561 public:
577 typedef GenericType Type; 562 typedef GenericType Type;
578 static inline GenericType* New(Arena* arena) { 563 static inline GenericType* New(Arena* arena) {
579 return ::google::protobuf::Arena::CreateMaybeMessage<Type>( 564 return ::google::protobuf::Arena::CreateMaybeMessage<Type>(
580 arena, static_cast<GenericType*>(0)); 565 arena, static_cast<GenericType*>(0));
581 } 566 }
582 // We force NewFromPrototype() to be non-inline to reduce code size: 567 // We force NewFromPrototype() and Delete() to be non-inline to reduce code
583 // else, several other methods get inlined copies of message types' 568 // size: else, several other methods get inlined copies of message types'
584 // constructors. 569 // constructors and destructors.
585 GOOGLE_ATTRIBUTE_NOINLINE static GenericType* NewFromPrototype( 570 GOOGLE_ATTRIBUTE_NOINLINE static GenericType* NewFromPrototype(
586 const GenericType* prototype, ::google::protobuf::Arena* arena = NULL); 571 const GenericType* prototype, ::google::protobuf::Arena* arena = NULL);
587 static inline void Delete(GenericType* value, Arena* arena) { 572 GOOGLE_ATTRIBUTE_NOINLINE static void Delete(GenericType* value, Arena* arena) ;
588 if (arena == NULL) {
589 delete value;
590 }
591 }
592 static inline ::google::protobuf::Arena* GetArena(GenericType* value) { 573 static inline ::google::protobuf::Arena* GetArena(GenericType* value) {
593 return ::google::protobuf::Arena::GetArena<Type>(value); 574 return ::google::protobuf::Arena::GetArena<Type>(value);
594 } 575 }
595 static inline void* GetMaybeArenaPointer(GenericType* value) { 576 static inline void* GetMaybeArenaPointer(GenericType* value) {
596 return ::google::protobuf::Arena::GetArena<Type>(value); 577 return ::google::protobuf::Arena::GetArena<Type>(value);
597 } 578 }
598 579
599 static inline void Clear(GenericType* value) { value->Clear(); } 580 static inline void Clear(GenericType* value) { value->Clear(); }
600 GOOGLE_ATTRIBUTE_NOINLINE static void Merge(const GenericType& from, 581 GOOGLE_ATTRIBUTE_NOINLINE static void Merge(const GenericType& from,
601 GenericType* to); 582 GenericType* to);
602 static inline int SpaceUsed(const GenericType& value) { 583 static inline int SpaceUsed(const GenericType& value) {
603 return value.SpaceUsed(); 584 return value.SpaceUsed();
604 } 585 }
605 static inline const Type& default_instance() { 586 static inline const Type& default_instance() {
606 return Type::default_instance(); 587 return Type::default_instance();
607 } 588 }
608 }; 589 };
609 590
610 template <typename GenericType> 591 template <typename GenericType>
611 GenericType* GenericTypeHandler<GenericType>::NewFromPrototype( 592 GenericType* GenericTypeHandler<GenericType>::NewFromPrototype(
612 const GenericType* /* prototype */, ::google::protobuf::Arena* arena) { 593 const GenericType* /* prototype */, ::google::protobuf::Arena* arena) {
613 return New(arena); 594 return New(arena);
614 } 595 }
615 template <typename GenericType> 596 template <typename GenericType>
597 void GenericTypeHandler<GenericType>::Delete(GenericType* value, Arena* arena) {
598 if (arena == NULL) {
599 delete value;
600 }
601 }
602 template <typename GenericType>
616 void GenericTypeHandler<GenericType>::Merge(const GenericType& from, 603 void GenericTypeHandler<GenericType>::Merge(const GenericType& from,
617 GenericType* to) { 604 GenericType* to) {
618 to->MergeFrom(from); 605 to->MergeFrom(from);
619 } 606 }
620 607
621 // NewFromPrototype() and Merge() cannot be defined here; if they're declared 608 // NewFromPrototype() and Merge() cannot be defined here; if they're declared
622 // inline the compiler will complain about not matching GOOGLE_ATTRIBUTE_NOINLIN E 609 // inline the compiler will complain about not matching GOOGLE_ATTRIBUTE_NOINLIN E
623 // above, and if not, compilation will result in multiple definitions. These 610 // above, and if not, compilation will result in multiple definitions. These
624 // are therefore declared as specializations here and defined in 611 // are therefore declared as specializations here and defined in
625 // message_lite.cc. 612 // message_lite.cc.
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
679 666
680 template <> 667 template <>
681 inline const Message& GenericTypeHandler<Message>::default_instance() { 668 inline const Message& GenericTypeHandler<Message>::default_instance() {
682 // Yes, the behavior of the code is undefined, but this function is only 669 // Yes, the behavior of the code is undefined, but this function is only
683 // called when we're already deep into the world of undefined, because the 670 // called when we're already deep into the world of undefined, because the
684 // caller called Get(index) out of bounds. 671 // caller called Get(index) out of bounds.
685 Message* null = NULL; 672 Message* null = NULL;
686 return *null; 673 return *null;
687 } 674 }
688 675
689 class LIBPROTOBUF_EXPORT StringTypeHandler { 676
677 // HACK: If a class is declared as DLL-exported in MSVC, it insists on
678 // generating copies of all its methods -- even inline ones -- to include
679 // in the DLL. But SpaceUsed() calls StringSpaceUsedExcludingSelf() which
680 // isn't in the lite library, therefore the lite library cannot link if
681 // StringTypeHandler is exported. So, we factor out StringTypeHandlerBase,
682 // export that, then make StringTypeHandler be a subclass which is NOT
683 // exported.
684 // TODO(kenton): Now that StringSpaceUsedExcludingSelf() is in the lite
685 // library, this can be cleaned up.
686 class LIBPROTOBUF_EXPORT StringTypeHandlerBase {
690 public: 687 public:
691 typedef string Type; 688 typedef string Type;
692 689
693 static inline string* New(Arena* arena) { 690 static inline string* New(Arena* arena) {
694 return Arena::Create<string>(arena); 691 return Arena::Create<string>(arena);
695 } 692 }
696 static inline string* NewFromPrototype(const string*, 693 static inline string* NewFromPrototype(const string*,
697 ::google::protobuf::Arena* arena) { 694 ::google::protobuf::Arena* arena) {
698 return New(arena); 695 return New(arena);
699 } 696 }
700 static inline ::google::protobuf::Arena* GetArena(string*) { 697 static inline ::google::protobuf::Arena* GetArena(string*) {
701 return NULL; 698 return NULL;
702 } 699 }
703 static inline void* GetMaybeArenaPointer(string* /* value */) { 700 static inline void* GetMaybeArenaPointer(string* /* value */) {
704 return NULL; 701 return NULL;
705 } 702 }
706 static inline void Delete(string* value, Arena* arena) { 703 static inline void Delete(string* value, Arena* arena) {
707 if (arena == NULL) { 704 if (arena == NULL) {
708 delete value; 705 delete value;
709 } 706 }
710 } 707 }
711 static inline void Clear(string* value) { value->clear(); } 708 static inline void Clear(string* value) { value->clear(); }
712 static inline void Merge(const string& from, string* to) { *to = from; } 709 static inline void Merge(const string& from, string* to) { *to = from; }
713 static inline const Type& default_instance() { 710 static inline const Type& default_instance() {
714 return ::google::protobuf::internal::GetEmptyString(); 711 return ::google::protobuf::internal::GetEmptyString();
715 } 712 }
713 };
714
715 class StringTypeHandler : public StringTypeHandlerBase {
716 public:
716 static int SpaceUsed(const string& value) { 717 static int SpaceUsed(const string& value) {
717 return static_cast<int>(sizeof(value)) + StringSpaceUsedExcludingSelf(value) ; 718 return static_cast<int>(sizeof(value)) + StringSpaceUsedExcludingSelf(value) ;
718 } 719 }
719 }; 720 };
720 721
721 722
722 } // namespace internal 723 } // namespace internal
723 724
724 // RepeatedPtrField is like RepeatedField, but used for repeated strings or 725 // RepeatedPtrField is like RepeatedField, but used for repeated strings or
725 // Messages. 726 // Messages.
726 template <typename Element> 727 template <typename Element>
727 class RepeatedPtrField PROTOBUF_FINAL : public internal::RepeatedPtrFieldBase { 728 class RepeatedPtrField : public internal::RepeatedPtrFieldBase {
728 public: 729 public:
729 RepeatedPtrField(); 730 RepeatedPtrField();
730 explicit RepeatedPtrField(::google::protobuf::Arena* arena); 731 explicit RepeatedPtrField(::google::protobuf::Arena* arena);
731 732
732 RepeatedPtrField(const RepeatedPtrField& other); 733 RepeatedPtrField(const RepeatedPtrField& other);
733 template <typename Iter> 734 template <typename Iter>
734 RepeatedPtrField(Iter begin, const Iter& end); 735 RepeatedPtrField(Iter begin, const Iter& end);
735 ~RepeatedPtrField(); 736 ~RepeatedPtrField();
736 737
737 RepeatedPtrField& operator=(const RepeatedPtrField& other); 738 RepeatedPtrField& operator=(const RepeatedPtrField& other);
738 739
739 bool empty() const; 740 bool empty() const;
740 int size() const; 741 int size() const;
741 742
742 const Element& Get(int index) const; 743 const Element& Get(int index) const;
743 Element* Mutable(int index); 744 Element* Mutable(int index);
744 Element* Add(); 745 Element* Add();
745 746
746 const Element& operator[](int index) const { return Get(index); }
747 Element& operator[](int index) { return *Mutable(index); }
748
749 // Remove the last element in the array. 747 // Remove the last element in the array.
750 // Ownership of the element is retained by the array. 748 // Ownership of the element is retained by the array.
751 void RemoveLast(); 749 void RemoveLast();
752 750
753 // Delete elements with indices in the range [start .. start+num-1]. 751 // Delete elements with indices in the range [start .. start+num-1].
754 // Caution: implementation moves all elements with indices [start+num .. ]. 752 // Caution: implementation moves all elements with indices [start+num .. ].
755 // Calling this routine inside a loop can cause quadratic behavior. 753 // Calling this routine inside a loop can cause quadratic behavior.
756 void DeleteSubrange(int start, int num); 754 void DeleteSubrange(int start, int num);
757 755
758 void Clear(); 756 void Clear();
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
856 // If this RepeatedPtrField is on an arena, an object copy is required to pass 854 // If this RepeatedPtrField is on an arena, an object copy is required to pass
857 // ownership back to the user (for compatible semantics). Use 855 // ownership back to the user (for compatible semantics). Use
858 // UnsafeArenaReleaseLast() if this behavior is undesired. 856 // UnsafeArenaReleaseLast() if this behavior is undesired.
859 Element* ReleaseLast(); 857 Element* ReleaseLast();
860 858
861 // Add an already-allocated object, skipping arena-ownership checks. The user 859 // Add an already-allocated object, skipping arena-ownership checks. The user
862 // must guarantee that the given object is in the same arena as this 860 // must guarantee that the given object is in the same arena as this
863 // RepeatedPtrField. 861 // RepeatedPtrField.
864 // It is also useful in legacy code that uses temporary ownership to avoid 862 // It is also useful in legacy code that uses temporary ownership to avoid
865 // copies. Example: 863 // copies. Example:
866 // RepeatedPtrField<T> temp_field; 864 // RepeatedPtrField<T> temp_field;
867 // temp_field.AddAllocated(new T); 865 // temp_field.AddAllocated(new T);
868 // ... // Do something with temp_field 866 // ... // Do something with temp_field
869 // temp_field.ExtractSubrange(0, temp_field.size(), NULL); 867 // temp_field.ExtractSubrange(0, temp_field.size(), NULL);
870 // If you put temp_field on the arena this fails, because the ownership 868 // If you put temp_field on the arena this fails, because the ownership
871 // transfers to the arena at the "AddAllocated" call and is not released 869 // transfers to the arena at the "AddAllocated" call and is not released
872 // anymore causing a double delete. UnsafeArenaAddAllocated prevents this. 870 // anymore causing a double delete. UnsafeArenaAddAllocated prevents this.
873 void UnsafeArenaAddAllocated(Element* value); 871 void UnsafeArenaAddAllocated(Element* value);
874 872
875 // Remove the last element and return it. Works only when operating on an 873 // Remove the last element and return it. Works only when operating on an
876 // arena. The returned pointer is to the original object in the arena, hence 874 // arena. The returned pointer is to the original object in the arena, hence
877 // has the arena's lifetime. 875 // has the arena's lifetime.
878 // Requires: current_size_ > 0 876 // Requires: current_size_ > 0
879 Element* UnsafeArenaReleaseLast(); 877 Element* UnsafeArenaReleaseLast();
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
941 // Returns an iterator to the element immediately following the removed range. 939 // Returns an iterator to the element immediately following the removed range.
942 // 940 //
943 // Invalidates all iterators at or after the removed range, including end(). 941 // Invalidates all iterators at or after the removed range, including end().
944 iterator erase(const_iterator first, const_iterator last); 942 iterator erase(const_iterator first, const_iterator last);
945 943
946 // Gets the arena on which this RepeatedPtrField stores its elements. 944 // Gets the arena on which this RepeatedPtrField stores its elements.
947 ::google::protobuf::Arena* GetArena() const { 945 ::google::protobuf::Arena* GetArena() const {
948 return GetArenaNoVirtual(); 946 return GetArenaNoVirtual();
949 } 947 }
950 948
951 private: 949 protected:
952 // Note: RepeatedPtrField SHOULD NOT be subclassed by users. 950 // Note: RepeatedPtrField SHOULD NOT be subclassed by users. We only
951 // subclass it in one place as a hack for compatibility with proto1. The
952 // subclass needs to know about TypeHandler in order to call protected
953 // methods on RepeatedPtrFieldBase.
953 class TypeHandler; 954 class TypeHandler;
954 955
955 // Internal arena accessor expected by helpers in Arena. 956 // Internal arena accessor expected by helpers in Arena.
956 inline Arena* GetArenaNoVirtual() const; 957 inline Arena* GetArenaNoVirtual() const;
957 958
959 private:
958 // Implementations for ExtractSubrange(). The copying behavior must be 960 // Implementations for ExtractSubrange(). The copying behavior must be
959 // included only if the type supports the necessary operations (e.g., 961 // included only if the type supports the necessary operations (e.g.,
960 // MergeFrom()), so we must resolve this at compile time. ExtractSubrange() 962 // MergeFrom()), so we must resolve this at compile time. ExtractSubrange()
961 // uses SFINAE to choose one of the below implementations. 963 // uses SFINAE to choose one of the below implementations.
962 void ExtractSubrangeInternal(int start, int num, Element** elements, 964 void ExtractSubrangeInternal(int start, int num, Element** elements,
963 google::protobuf::internal::true_type); 965 google::protobuf::internal::true_type);
964 void ExtractSubrangeInternal(int start, int num, Element** elements, 966 void ExtractSubrangeInternal(int start, int num, Element** elements,
965 google::protobuf::internal::false_type); 967 google::protobuf::internal::false_type);
966 968
967 friend class Arena; 969 friend class Arena;
(...skipping 22 matching lines...) Expand all
990 ::google::protobuf::Arena::CreateArray<char>(arena, kRepHeaderSize)); 992 ::google::protobuf::Arena::CreateArray<char>(arena, kRepHeaderSize));
991 rep_->arena = arena; 993 rep_->arena = arena;
992 } 994 }
993 } 995 }
994 996
995 template <typename Element> 997 template <typename Element>
996 inline RepeatedField<Element>::RepeatedField(const RepeatedField& other) 998 inline RepeatedField<Element>::RepeatedField(const RepeatedField& other)
997 : current_size_(0), 999 : current_size_(0),
998 total_size_(0), 1000 total_size_(0),
999 rep_(NULL) { 1001 rep_(NULL) {
1000 if (other.current_size_ != 0) { 1002 CopyFrom(other);
1001 Reserve(other.current_size_);
1002 CopyArray(rep_->elements,
1003 other.rep_->elements, other.current_size_);
1004 current_size_ = other.current_size_;
1005 }
1006 } 1003 }
1007 1004
1008 template <typename Element> 1005 template <typename Element>
1009 template <typename Iter> 1006 template <typename Iter>
1010 RepeatedField<Element>::RepeatedField(Iter begin, const Iter& end) 1007 RepeatedField<Element>::RepeatedField(Iter begin, const Iter& end)
1011 : current_size_(0), 1008 : current_size_(0),
1012 total_size_(0), 1009 total_size_(0),
1013 rep_(NULL) { 1010 rep_(NULL) {
1014 int reserve = internal::CalculateReserve(begin, end); 1011 int reserve = internal::CalculateReserve(begin, end);
1015 if (reserve != -1) { 1012 if (reserve != -1) {
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after
1137 } 1134 }
1138 } 1135 }
1139 1136
1140 template <typename Element> 1137 template <typename Element>
1141 inline void RepeatedField<Element>::Clear() { 1138 inline void RepeatedField<Element>::Clear() {
1142 current_size_ = 0; 1139 current_size_ = 0;
1143 } 1140 }
1144 1141
1145 template <typename Element> 1142 template <typename Element>
1146 inline void RepeatedField<Element>::MergeFrom(const RepeatedField& other) { 1143 inline void RepeatedField<Element>::MergeFrom(const RepeatedField& other) {
1147 GOOGLE_DCHECK_NE(&other, this); 1144 GOOGLE_CHECK_NE(&other, this);
1148 if (other.current_size_ != 0) { 1145 if (other.current_size_ != 0) {
1149 Reserve(current_size_ + other.current_size_); 1146 Reserve(current_size_ + other.current_size_);
1150 CopyArray(rep_->elements + current_size_, 1147 CopyArray(rep_->elements + current_size_,
1151 other.rep_->elements, other.current_size_); 1148 other.rep_->elements, other.current_size_);
1152 current_size_ += other.current_size_; 1149 current_size_ += other.current_size_;
1153 } 1150 }
1154 } 1151 }
1155 1152
1156 template <typename Element> 1153 template <typename Element>
1157 inline void RepeatedField<Element>::CopyFrom(const RepeatedField& other) { 1154 inline void RepeatedField<Element>::CopyFrom(const RepeatedField& other) {
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
1263 void RepeatedField<Element>::Reserve(int new_size) { 1260 void RepeatedField<Element>::Reserve(int new_size) {
1264 if (total_size_ >= new_size) return; 1261 if (total_size_ >= new_size) return;
1265 Rep* old_rep = rep_; 1262 Rep* old_rep = rep_;
1266 Arena* arena = GetArenaNoVirtual(); 1263 Arena* arena = GetArenaNoVirtual();
1267 new_size = std::max(google::protobuf::internal::kMinRepeatedFieldAllocationSiz e, 1264 new_size = std::max(google::protobuf::internal::kMinRepeatedFieldAllocationSiz e,
1268 std::max(total_size_ * 2, new_size)); 1265 std::max(total_size_ * 2, new_size));
1269 GOOGLE_CHECK_LE(static_cast<size_t>(new_size), 1266 GOOGLE_CHECK_LE(static_cast<size_t>(new_size),
1270 (std::numeric_limits<size_t>::max() - kRepHeaderSize) / 1267 (std::numeric_limits<size_t>::max() - kRepHeaderSize) /
1271 sizeof(Element)) 1268 sizeof(Element))
1272 << "Requested size is too large to fit into size_t."; 1269 << "Requested size is too large to fit into size_t.";
1273 size_t bytes = kRepHeaderSize + sizeof(Element) * new_size;
1274 if (arena == NULL) { 1270 if (arena == NULL) {
1275 rep_ = static_cast<Rep*>(::operator new(bytes)); 1271 rep_ = reinterpret_cast<Rep*>(
1272 new char[kRepHeaderSize + sizeof(Element) * new_size]);
1276 } else { 1273 } else {
1277 rep_ = reinterpret_cast<Rep*>( 1274 rep_ = reinterpret_cast<Rep*>(
1278 ::google::protobuf::Arena::CreateArray<char>(arena, bytes)); 1275 ::google::protobuf::Arena::CreateArray<char>(arena,
1276 kRepHeaderSize + sizeof(Element) * new_size));
1279 } 1277 }
1280 rep_->arena = arena; 1278 rep_->arena = arena;
1281 int old_total_size = total_size_; 1279 int old_total_size = total_size_;
1282 total_size_ = new_size; 1280 total_size_ = new_size;
1283 // Invoke placement-new on newly allocated elements. We shouldn't have to do 1281 // Invoke placement-new on newly allocated elements. We shouldn't have to do
1284 // this, since Element is supposed to be POD, but a previous version of this 1282 // this, since Element is supposed to be POD, but a previous version of this
1285 // code allocated storage with "new Element[size]" and some code uses 1283 // code allocated storage with "new Element[size]" and some code uses
1286 // RepeatedField with non-POD types, relying on constructor invocation. If 1284 // RepeatedField with non-POD types, relying on constructor invocation. If
1287 // Element has a trivial constructor (e.g., int32), gcc (tested with -O2) 1285 // Element has a trivial constructor (e.g., int32), gcc (tested with -O2)
1288 // completely removes this loop because the loop body is empty, so this has no 1286 // completely removes this loop because the loop body is empty, so this has no
1289 // effect unless its side-effects are required for correctness. 1287 // effect unless its side-effects are required for correctness.
1290 // Note that we do this before MoveArray() below because Element's copy 1288 // Note that we do this before MoveArray() below because Element's copy
1291 // assignment implementation will want an initialized instance first. 1289 // assignment implementation will want an initialized instance first.
1292 Element* e = &rep_->elements[0]; 1290 Element* e = &rep_->elements[0];
1293 Element* limit = &rep_->elements[total_size_]; 1291 Element* limit = &rep_->elements[total_size_];
1294 for (; e < limit; e++) { 1292 for (; e < limit; e++) {
1295 new (e) Element; 1293 new (e) Element();
1296 } 1294 }
1297 if (current_size_ > 0) { 1295 if (current_size_ > 0) {
1298 MoveArray(rep_->elements, old_rep->elements, current_size_); 1296 MoveArray(rep_->elements, old_rep->elements, current_size_);
1299 } 1297 }
1300 1298
1301 // Likewise, we need to invoke destructors on the old array. 1299 // Likewise, we need to invoke destructors on the old array.
1302 InternalDeallocate(old_rep, old_total_size); 1300 InternalDeallocate(old_rep, old_total_size);
1303 1301
1304 } 1302 }
1305 1303
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
1354 1352
1355 inline RepeatedPtrFieldBase::RepeatedPtrFieldBase(::google::protobuf::Arena* are na) 1353 inline RepeatedPtrFieldBase::RepeatedPtrFieldBase(::google::protobuf::Arena* are na)
1356 : arena_(arena), 1354 : arena_(arena),
1357 current_size_(0), 1355 current_size_(0),
1358 total_size_(0), 1356 total_size_(0),
1359 rep_(NULL) { 1357 rep_(NULL) {
1360 } 1358 }
1361 1359
1362 template <typename TypeHandler> 1360 template <typename TypeHandler>
1363 void RepeatedPtrFieldBase::Destroy() { 1361 void RepeatedPtrFieldBase::Destroy() {
1364 if (rep_ != NULL && arena_ == NULL) { 1362 if (rep_ != NULL) {
1365 int n = rep_->allocated_size; 1363 for (int i = 0; i < rep_->allocated_size; i++) {
1366 void* const* elements = rep_->elements; 1364 TypeHandler::Delete(cast<TypeHandler>(rep_->elements[i]), arena_);
1367 for (int i = 0; i < n; i++) {
1368 TypeHandler::Delete(cast<TypeHandler>(elements[i]), NULL);
1369 } 1365 }
1370 #if defined(__GXX_DELETE_WITH_SIZE__) || defined(__cpp_sized_deallocation) 1366 if (arena_ == NULL) {
1371 const size_t size = total_size_ * sizeof(elements[0]) + kRepHeaderSize; 1367 delete [] reinterpret_cast<char*>(rep_);
1372 ::operator delete(static_cast<void*>(rep_), size); 1368 }
1373 #else
1374 ::operator delete(static_cast<void*>(rep_));
1375 #endif
1376 } 1369 }
1377 rep_ = NULL; 1370 rep_ = NULL;
1378 } 1371 }
1379 1372
1380 template <typename TypeHandler> 1373 template <typename TypeHandler>
1381 inline void RepeatedPtrFieldBase::Swap(RepeatedPtrFieldBase* other) { 1374 inline void RepeatedPtrFieldBase::Swap(RepeatedPtrFieldBase* other) {
1382 if (other->GetArenaNoVirtual() == GetArenaNoVirtual()) { 1375 if (other->GetArenaNoVirtual() == GetArenaNoVirtual()) {
1383 InternalSwap(other); 1376 InternalSwap(other);
1384 } else { 1377 } else {
1385 SwapFallback<TypeHandler>(other); 1378 SwapFallback<TypeHandler>(other);
(...skipping 399 matching lines...) Expand 10 before | Expand all | Expand 10 after
1785 : RepeatedPtrFieldBase() {} 1778 : RepeatedPtrFieldBase() {}
1786 1779
1787 template <typename Element> 1780 template <typename Element>
1788 inline RepeatedPtrField<Element>::RepeatedPtrField(::google::protobuf::Arena* ar ena) : 1781 inline RepeatedPtrField<Element>::RepeatedPtrField(::google::protobuf::Arena* ar ena) :
1789 RepeatedPtrFieldBase(arena) {} 1782 RepeatedPtrFieldBase(arena) {}
1790 1783
1791 template <typename Element> 1784 template <typename Element>
1792 inline RepeatedPtrField<Element>::RepeatedPtrField( 1785 inline RepeatedPtrField<Element>::RepeatedPtrField(
1793 const RepeatedPtrField& other) 1786 const RepeatedPtrField& other)
1794 : RepeatedPtrFieldBase() { 1787 : RepeatedPtrFieldBase() {
1795 MergeFrom(other); 1788 CopyFrom(other);
1796 } 1789 }
1797 1790
1798 template <typename Element> 1791 template <typename Element>
1799 template <typename Iter> 1792 template <typename Iter>
1800 inline RepeatedPtrField<Element>::RepeatedPtrField( 1793 inline RepeatedPtrField<Element>::RepeatedPtrField(
1801 Iter begin, const Iter& end) { 1794 Iter begin, const Iter& end) {
1802 int reserve = internal::CalculateReserve(begin, end); 1795 int reserve = internal::CalculateReserve(begin, end);
1803 if (reserve != -1) { 1796 if (reserve != -1) {
1804 Reserve(reserve); 1797 Reserve(reserve);
1805 } 1798 }
(...skipping 559 matching lines...) Expand 10 before | Expand all | Expand 10 after
2365 return *this; 2358 return *this;
2366 } 2359 }
2367 RepeatedPtrFieldBackInsertIterator<T>& operator++(int /* unused */) { 2360 RepeatedPtrFieldBackInsertIterator<T>& operator++(int /* unused */) {
2368 return *this; 2361 return *this;
2369 } 2362 }
2370 2363
2371 private: 2364 private:
2372 RepeatedPtrField<T>* field_; 2365 RepeatedPtrField<T>* field_;
2373 }; 2366 };
2374 2367
2375 // A back inserter for RepeatedPtrFields that inserts by transferring ownership 2368 // A back inserter for RepeatedPtrFields that inserts by transfering ownership
2376 // of a pointer. 2369 // of a pointer.
2377 template<typename T> class AllocatedRepeatedPtrFieldBackInsertIterator 2370 template<typename T> class AllocatedRepeatedPtrFieldBackInsertIterator
2378 : public std::iterator<std::output_iterator_tag, T> { 2371 : public std::iterator<std::output_iterator_tag, T> {
2379 public: 2372 public:
2380 explicit AllocatedRepeatedPtrFieldBackInsertIterator( 2373 explicit AllocatedRepeatedPtrFieldBackInsertIterator(
2381 RepeatedPtrField<T>* const mutable_field) 2374 RepeatedPtrField<T>* const mutable_field)
2382 : field_(mutable_field) { 2375 : field_(mutable_field) {
2383 } 2376 }
2384 AllocatedRepeatedPtrFieldBackInsertIterator<T>& operator=( 2377 AllocatedRepeatedPtrFieldBackInsertIterator<T>& operator=(
2385 T* const ptr_to_value) { 2378 T* const ptr_to_value) {
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
2462 AllocatedRepeatedPtrFieldBackInserter( 2455 AllocatedRepeatedPtrFieldBackInserter(
2463 RepeatedPtrField<T>* const mutable_field) { 2456 RepeatedPtrField<T>* const mutable_field) {
2464 return internal::AllocatedRepeatedPtrFieldBackInsertIterator<T>( 2457 return internal::AllocatedRepeatedPtrFieldBackInsertIterator<T>(
2465 mutable_field); 2458 mutable_field);
2466 } 2459 }
2467 2460
2468 // Similar to AllocatedRepeatedPtrFieldBackInserter, using 2461 // Similar to AllocatedRepeatedPtrFieldBackInserter, using
2469 // UnsafeArenaAddAllocated instead of AddAllocated. 2462 // UnsafeArenaAddAllocated instead of AddAllocated.
2470 // This is slightly faster if that matters. It is also useful in legacy code 2463 // This is slightly faster if that matters. It is also useful in legacy code
2471 // that uses temporary ownership to avoid copies. Example: 2464 // that uses temporary ownership to avoid copies. Example:
2472 // RepeatedPtrField<T> temp_field; 2465 // RepeatedPtrField<T> temp_field;
2473 // temp_field.AddAllocated(new T); 2466 // temp_field.AddAllocated(new T);
2474 // ... // Do something with temp_field 2467 // ... // Do something with temp_field
2475 // temp_field.ExtractSubrange(0, temp_field.size(), NULL); 2468 // temp_field.ExtractSubrange(0, temp_field.size(), NULL);
2476 // If you put temp_field on the arena this fails, because the ownership 2469 // If you put temp_field on the arena this fails, because the ownership
2477 // transfers to the arena at the "AddAllocated" call and is not released anymore 2470 // transfers to the arena at the "AddAllocated" call and is not released anymore
2478 // causing a double delete. Using UnsafeArenaAddAllocated prevents this. 2471 // causing a double delete. Using UnsafeArenaAddAllocated prevents this.
2479 template<typename T> 2472 template<typename T>
2480 internal::UnsafeArenaAllocatedRepeatedPtrFieldBackInsertIterator<T> 2473 internal::UnsafeArenaAllocatedRepeatedPtrFieldBackInsertIterator<T>
2481 UnsafeArenaAllocatedRepeatedPtrFieldBackInserter( 2474 UnsafeArenaAllocatedRepeatedPtrFieldBackInserter(
2482 ::google::protobuf::RepeatedPtrField<T>* const mutable_field) { 2475 ::google::protobuf::RepeatedPtrField<T>* const mutable_field) {
2483 return internal::UnsafeArenaAllocatedRepeatedPtrFieldBackInsertIterator<T>( 2476 return internal::UnsafeArenaAllocatedRepeatedPtrFieldBackInsertIterator<T>(
2484 mutable_field); 2477 mutable_field);
2485 } 2478 }
2486 2479
2487 } // namespace protobuf 2480 } // namespace protobuf
2488 2481
2489 } // namespace google 2482 } // namespace google
2490 #endif // GOOGLE_PROTOBUF_REPEATED_FIELD_H__ 2483 #endif // GOOGLE_PROTOBUF_REPEATED_FIELD_H__
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698