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

Unified 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 side-by-side diff with in-line comments
Download patch
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.

Powered by Google App Engine
This is Rietveld 408576698