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

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

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

Powered by Google App Engine
This is Rietveld 408576698