| Index: third_party/protobuf/src/google/protobuf/repeated_field.h
|
| diff --git a/third_party/protobuf/src/google/protobuf/repeated_field.h b/third_party/protobuf/src/google/protobuf/repeated_field.h
|
| index 1961bc4810b0c9ee74f01bfd2c5f49422c1a62a8..bbdef4496c153534717b25f3a4c8ef99a71be699 100644
|
| --- a/third_party/protobuf/src/google/protobuf/repeated_field.h
|
| +++ b/third_party/protobuf/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);
|
| @@ -120,8 +121,14 @@ class RepeatedField {
|
|
|
| const Element& Get(int index) const;
|
| Element* Mutable(int index);
|
| +
|
| + const Element& operator[](int index) const { return Get(index); }
|
| + Element& operator[](int index) { return *Mutable(index); }
|
| +
|
| 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();
|
| @@ -144,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;
|
|
|
| @@ -284,7 +294,12 @@ class RepeatedField {
|
| e->Element::~Element();
|
| }
|
| if (rep->arena == NULL) {
|
| - delete[] reinterpret_cast<char*>(rep);
|
| +#if defined(__GXX_DELETE_WITH_SIZE__) || defined(__cpp_sized_deallocation)
|
| + const size_t bytes = size * sizeof(*e) + kRepHeaderSize;
|
| + ::operator delete(static_cast<void*>(rep), bytes);
|
| +#else
|
| + ::operator delete(static_cast<void*>(rep));
|
| +#endif
|
| }
|
| }
|
| }
|
| @@ -301,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.
|
| @@ -564,12 +579,16 @@ class GenericTypeHandler {
|
| return ::google::protobuf::Arena::CreateMaybeMessage<Type>(
|
| arena, static_cast<GenericType*>(0));
|
| }
|
| - // We force NewFromPrototype() and Delete() to be non-inline to reduce code
|
| - // size: else, several other methods get inlined copies of message types'
|
| - // constructors and destructors.
|
| + // We force NewFromPrototype() to be non-inline to reduce code size:
|
| + // else, several other methods get inlined copies of message types'
|
| + // constructors.
|
| GOOGLE_ATTRIBUTE_NOINLINE static GenericType* NewFromPrototype(
|
| const GenericType* prototype, ::google::protobuf::Arena* arena = NULL);
|
| - GOOGLE_ATTRIBUTE_NOINLINE static void Delete(GenericType* value, Arena* arena);
|
| + static inline void Delete(GenericType* value, Arena* arena) {
|
| + if (arena == NULL) {
|
| + delete value;
|
| + }
|
| + }
|
| static inline ::google::protobuf::Arena* GetArena(GenericType* value) {
|
| return ::google::protobuf::Arena::GetArena<Type>(value);
|
| }
|
| @@ -594,12 +613,6 @@ GenericType* GenericTypeHandler<GenericType>::NewFromPrototype(
|
| return New(arena);
|
| }
|
| template <typename GenericType>
|
| -void GenericTypeHandler<GenericType>::Delete(GenericType* value, Arena* arena) {
|
| - if (arena == NULL) {
|
| - delete value;
|
| - }
|
| -}
|
| -template <typename GenericType>
|
| void GenericTypeHandler<GenericType>::Merge(const GenericType& from,
|
| GenericType* to) {
|
| to->MergeFrom(from);
|
| @@ -673,17 +686,7 @@ inline const Message& GenericTypeHandler<Message>::default_instance() {
|
| return *null;
|
| }
|
|
|
| -
|
| -// HACK: If a class is declared as DLL-exported in MSVC, it insists on
|
| -// generating copies of all its methods -- even inline ones -- to include
|
| -// in the DLL. But SpaceUsed() calls StringSpaceUsedExcludingSelf() which
|
| -// isn't in the lite library, therefore the lite library cannot link if
|
| -// StringTypeHandler is exported. So, we factor out StringTypeHandlerBase,
|
| -// export that, then make StringTypeHandler be a subclass which is NOT
|
| -// exported.
|
| -// TODO(kenton): Now that StringSpaceUsedExcludingSelf() is in the lite
|
| -// library, this can be cleaned up.
|
| -class LIBPROTOBUF_EXPORT StringTypeHandlerBase {
|
| +class LIBPROTOBUF_EXPORT StringTypeHandler {
|
| public:
|
| typedef string Type;
|
|
|
| @@ -710,10 +713,6 @@ class LIBPROTOBUF_EXPORT StringTypeHandlerBase {
|
| static inline const Type& default_instance() {
|
| return ::google::protobuf::internal::GetEmptyString();
|
| }
|
| -};
|
| -
|
| -class StringTypeHandler : public StringTypeHandlerBase {
|
| - public:
|
| static int SpaceUsed(const string& value) {
|
| return static_cast<int>(sizeof(value)) + StringSpaceUsedExcludingSelf(value);
|
| }
|
| @@ -725,7 +724,7 @@ class StringTypeHandler : public StringTypeHandlerBase {
|
| // 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);
|
| @@ -744,6 +743,9 @@ class RepeatedPtrField : public internal::RepeatedPtrFieldBase {
|
| Element* Mutable(int index);
|
| Element* Add();
|
|
|
| + const Element& operator[](int index) const { return Get(index); }
|
| + Element& operator[](int index) { return *Mutable(index); }
|
| +
|
| // Remove the last element in the array.
|
| // Ownership of the element is retained by the array.
|
| void RemoveLast();
|
| @@ -861,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.
|
| @@ -946,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()
|
| @@ -999,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>
|
| @@ -1141,7 +1144,7 @@ inline void RepeatedField<Element>::Clear() {
|
|
|
| template <typename Element>
|
| inline void RepeatedField<Element>::MergeFrom(const RepeatedField& other) {
|
| - GOOGLE_CHECK_NE(&other, this);
|
| + GOOGLE_DCHECK_NE(&other, this);
|
| if (other.current_size_ != 0) {
|
| Reserve(current_size_ + other.current_size_);
|
| CopyArray(rep_->elements + current_size_,
|
| @@ -1267,13 +1270,12 @@ void RepeatedField<Element>::Reserve(int new_size) {
|
| (std::numeric_limits<size_t>::max() - kRepHeaderSize) /
|
| sizeof(Element))
|
| << "Requested size is too large to fit into size_t.";
|
| + size_t bytes = kRepHeaderSize + sizeof(Element) * new_size;
|
| if (arena == NULL) {
|
| - rep_ = reinterpret_cast<Rep*>(
|
| - new char[kRepHeaderSize + sizeof(Element) * new_size]);
|
| + rep_ = static_cast<Rep*>(::operator new(bytes));
|
| } else {
|
| rep_ = reinterpret_cast<Rep*>(
|
| - ::google::protobuf::Arena::CreateArray<char>(arena,
|
| - kRepHeaderSize + sizeof(Element) * new_size));
|
| + ::google::protobuf::Arena::CreateArray<char>(arena, bytes));
|
| }
|
| rep_->arena = arena;
|
| int old_total_size = total_size_;
|
| @@ -1290,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_);
|
| @@ -1359,13 +1361,18 @@ inline RepeatedPtrFieldBase::RepeatedPtrFieldBase(::google::protobuf::Arena* are
|
|
|
| template <typename TypeHandler>
|
| void RepeatedPtrFieldBase::Destroy() {
|
| - if (rep_ != NULL) {
|
| - for (int i = 0; i < rep_->allocated_size; i++) {
|
| - TypeHandler::Delete(cast<TypeHandler>(rep_->elements[i]), arena_);
|
| - }
|
| - if (arena_ == NULL) {
|
| - delete [] reinterpret_cast<char*>(rep_);
|
| + if (rep_ != NULL && arena_ == NULL) {
|
| + int n = rep_->allocated_size;
|
| + void* const* elements = rep_->elements;
|
| + for (int i = 0; i < n; i++) {
|
| + TypeHandler::Delete(cast<TypeHandler>(elements[i]), NULL);
|
| }
|
| +#if defined(__GXX_DELETE_WITH_SIZE__) || defined(__cpp_sized_deallocation)
|
| + const size_t size = total_size_ * sizeof(elements[0]) + kRepHeaderSize;
|
| + ::operator delete(static_cast<void*>(rep_), size);
|
| +#else
|
| + ::operator delete(static_cast<void*>(rep_));
|
| +#endif
|
| }
|
| rep_ = NULL;
|
| }
|
| @@ -1785,7 +1792,7 @@ template <typename Element>
|
| inline RepeatedPtrField<Element>::RepeatedPtrField(
|
| const RepeatedPtrField& other)
|
| : RepeatedPtrFieldBase() {
|
| - CopyFrom(other);
|
| + MergeFrom(other);
|
| }
|
|
|
| template <typename Element>
|
| @@ -2365,7 +2372,7 @@ template<typename T> class RepeatedPtrFieldBackInsertIterator
|
| RepeatedPtrField<T>* field_;
|
| };
|
|
|
| -// A back inserter for RepeatedPtrFields that inserts by transfering ownership
|
| +// A back inserter for RepeatedPtrFields that inserts by transferring ownership
|
| // of a pointer.
|
| template<typename T> class AllocatedRepeatedPtrFieldBackInsertIterator
|
| : public std::iterator<std::output_iterator_tag, T> {
|
| @@ -2462,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.
|
|
|