diff options
Diffstat (limited to 'src/google/protobuf/repeated_field.h')
-rw-r--r-- | src/google/protobuf/repeated_field.h | 60 |
1 files changed, 30 insertions, 30 deletions
diff --git a/src/google/protobuf/repeated_field.h b/src/google/protobuf/repeated_field.h index 6ede0e1a..bbdef449 100644 --- a/src/google/protobuf/repeated_field.h +++ b/src/google/protobuf/repeated_field.h @@ -61,8 +61,9 @@ #include <google/protobuf/generated_message_util.h> #include <google/protobuf/message_lite.h> -namespace google { +// Forward-declare these so that we can make them friends. +namespace google { namespace upb { namespace google_opensource { class GMR_Handlers; @@ -104,7 +105,7 @@ inline int CalculateReserve(Iter begin, Iter end) { // not ever use a RepeatedField directly; they will use the get-by-index, // set-by-index, and add accessors that are generated for all repeated fields. template <typename Element> -class RepeatedField { +class RepeatedField PROTOBUF_FINAL { public: RepeatedField(); explicit RepeatedField(Arena* arena); @@ -126,6 +127,8 @@ class RepeatedField { void Set(int index, const Element& value); void Add(const Element& value); + // Appends a new element and return a pointer to it. + // The new element is uninitialized if |Element| is a POD type. Element* Add(); // Remove the last element in the array. void RemoveLast(); @@ -138,7 +141,6 @@ class RepeatedField { void Clear(); void MergeFrom(const RepeatedField& other); - void UnsafeMergeFrom(const RepeatedField& other); void CopyFrom(const RepeatedField& other); // Reserve space to expand the field to at least the given size. If the @@ -149,6 +151,9 @@ class RepeatedField { void Truncate(int new_size); void AddAlreadyReserved(const Element& value); + // Appends a new element and return a pointer to it. + // The new element is uninitialized if |Element| is a POD type. + // Should be called only if Capacity() > Size(). Element* AddAlreadyReserved(); int Capacity() const; @@ -311,7 +316,7 @@ template <typename It, typename VoidPtr> class RepeatedPtrOverPtrsIterator; namespace internal { -// This is a helper template to copy an array of elements effeciently when they +// This is a helper template to copy an array of elements efficiently when they // have a trivial copy constructor, and correctly otherwise. This really // shouldn't be necessary, but our compiler doesn't optimize std::copy very // effectively. @@ -719,7 +724,7 @@ class LIBPROTOBUF_EXPORT StringTypeHandler { // RepeatedPtrField is like RepeatedField, but used for repeated strings or // Messages. template <typename Element> -class RepeatedPtrField : public internal::RepeatedPtrFieldBase { +class RepeatedPtrField PROTOBUF_FINAL : public internal::RepeatedPtrFieldBase { public: RepeatedPtrField(); explicit RepeatedPtrField(::google::protobuf::Arena* arena); @@ -752,7 +757,6 @@ class RepeatedPtrField : public internal::RepeatedPtrFieldBase { void Clear(); void MergeFrom(const RepeatedPtrField& other); - void UnsafeMergeFrom(const RepeatedPtrField& other) { MergeFrom(other); } void CopyFrom(const RepeatedPtrField& other); // Reserve space to expand the field to at least the given size. This only @@ -859,10 +863,10 @@ class RepeatedPtrField : public internal::RepeatedPtrFieldBase { // RepeatedPtrField. // It is also useful in legacy code that uses temporary ownership to avoid // copies. Example: - // RepeatedPtrField<T> temp_field; - // temp_field.AddAllocated(new T); - // ... // Do something with temp_field - // temp_field.ExtractSubrange(0, temp_field.size(), NULL); + // RepeatedPtrField<T> temp_field; + // temp_field.AddAllocated(new T); + // ... // Do something with temp_field + // temp_field.ExtractSubrange(0, temp_field.size(), NULL); // If you put temp_field on the arena this fails, because the ownership // transfers to the arena at the "AddAllocated" call and is not released // anymore causing a double delete. UnsafeArenaAddAllocated prevents this. @@ -944,17 +948,13 @@ class RepeatedPtrField : public internal::RepeatedPtrFieldBase { return GetArenaNoVirtual(); } - protected: - // Note: RepeatedPtrField SHOULD NOT be subclassed by users. We only - // subclass it in one place as a hack for compatibility with proto1. The - // subclass needs to know about TypeHandler in order to call protected - // methods on RepeatedPtrFieldBase. + private: + // Note: RepeatedPtrField SHOULD NOT be subclassed by users. class TypeHandler; // Internal arena accessor expected by helpers in Arena. inline Arena* GetArenaNoVirtual() const; - private: // Implementations for ExtractSubrange(). The copying behavior must be // included only if the type supports the necessary operations (e.g., // MergeFrom()), so we must resolve this at compile time. ExtractSubrange() @@ -997,7 +997,12 @@ inline RepeatedField<Element>::RepeatedField(const RepeatedField& other) : current_size_(0), total_size_(0), rep_(NULL) { - CopyFrom(other); + if (other.current_size_ != 0) { + Reserve(other.current_size_); + CopyArray(rep_->elements, + other.rep_->elements, other.current_size_); + current_size_ = other.current_size_; + } } template <typename Element> @@ -1138,7 +1143,8 @@ inline void RepeatedField<Element>::Clear() { } template <typename Element> -inline void RepeatedField<Element>::UnsafeMergeFrom(const RepeatedField& other) { +inline void RepeatedField<Element>::MergeFrom(const RepeatedField& other) { + GOOGLE_DCHECK_NE(&other, this); if (other.current_size_ != 0) { Reserve(current_size_ + other.current_size_); CopyArray(rep_->elements + current_size_, @@ -1148,12 +1154,6 @@ inline void RepeatedField<Element>::UnsafeMergeFrom(const RepeatedField& other) } template <typename Element> -inline void RepeatedField<Element>::MergeFrom(const RepeatedField& other) { - GOOGLE_CHECK_NE(&other, this); - UnsafeMergeFrom(other); -} - -template <typename Element> inline void RepeatedField<Element>::CopyFrom(const RepeatedField& other) { if (&other == this) return; Clear(); @@ -1292,7 +1292,7 @@ void RepeatedField<Element>::Reserve(int new_size) { Element* e = &rep_->elements[0]; Element* limit = &rep_->elements[total_size_]; for (; e < limit; e++) { - new (e) Element(); + new (e) Element; } if (current_size_ > 0) { MoveArray(rep_->elements, old_rep->elements, current_size_); @@ -1792,7 +1792,7 @@ template <typename Element> inline RepeatedPtrField<Element>::RepeatedPtrField( const RepeatedPtrField& other) : RepeatedPtrFieldBase() { - CopyFrom(other); + MergeFrom(other); } template <typename Element> @@ -2469,10 +2469,10 @@ AllocatedRepeatedPtrFieldBackInserter( // UnsafeArenaAddAllocated instead of AddAllocated. // This is slightly faster if that matters. It is also useful in legacy code // that uses temporary ownership to avoid copies. Example: -// RepeatedPtrField<T> temp_field; -// temp_field.AddAllocated(new T); -// ... // Do something with temp_field -// temp_field.ExtractSubrange(0, temp_field.size(), NULL); +// RepeatedPtrField<T> temp_field; +// temp_field.AddAllocated(new T); +// ... // Do something with temp_field +// temp_field.ExtractSubrange(0, temp_field.size(), NULL); // If you put temp_field on the arena this fails, because the ownership // transfers to the arena at the "AddAllocated" call and is not released anymore // causing a double delete. Using UnsafeArenaAddAllocated prevents this. |