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. |