aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/google/protobuf/repeated_field.h
diff options
context:
space:
mode:
authorGravatar Feng Xiao <xfxyjwf@gmail.com>2015-08-22 18:25:48 -0700
committerGravatar Feng Xiao <xfxyjwf@gmail.com>2015-08-22 18:25:48 -0700
commiteee38b0c018b3279f77d03dff796f440f40d3516 (patch)
tree7ff0978e30238d493fc7899b75abeb6d66939f07 /src/google/protobuf/repeated_field.h
parentc3bc155aceda36ecb01cde2367a3b427f2d7ce40 (diff)
Down-integrate from google3.
Diffstat (limited to 'src/google/protobuf/repeated_field.h')
-rw-r--r--src/google/protobuf/repeated_field.h90
1 files changed, 48 insertions, 42 deletions
diff --git a/src/google/protobuf/repeated_field.h b/src/google/protobuf/repeated_field.h
index 14f46298..b42d4790 100644
--- a/src/google/protobuf/repeated_field.h
+++ b/src/google/protobuf/repeated_field.h
@@ -54,6 +54,7 @@
#include <string>
#include <iterator>
#include <google/protobuf/stubs/casts.h>
+#include <google/protobuf/stubs/logging.h>
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/stubs/type_traits.h>
#include <google/protobuf/arena.h>
@@ -361,7 +362,7 @@ class LIBPROTOBUF_EXPORT RepeatedPtrFieldBase {
// To parse directly into a proto2 generated class, the upb class GMR_Handlers
// needs to be able to modify a RepeatedPtrFieldBase directly.
- friend class LIBPROTOBUF_EXPORT upb::google_opensource::GMR_Handlers;
+ friend class upb::google_opensource::GMR_Handlers;
RepeatedPtrFieldBase();
explicit RepeatedPtrFieldBase(::google::protobuf::Arena* arena);
@@ -408,7 +409,7 @@ class LIBPROTOBUF_EXPORT RepeatedPtrFieldBase {
const typename TypeHandler::Type* const* data() const;
template <typename TypeHandler>
- inline void Swap(RepeatedPtrFieldBase* other) GOOGLE_ATTRIBUTE_ALWAYS_INLINE;
+ GOOGLE_ATTRIBUTE_ALWAYS_INLINE void Swap(RepeatedPtrFieldBase* other);
void SwapElements(int index1, int index2);
@@ -458,22 +459,20 @@ class LIBPROTOBUF_EXPORT RepeatedPtrFieldBase {
void AddAllocatedInternal(typename TypeHandler::Type* value,
google::protobuf::internal::false_type);
- template <typename TypeHandler>
+ template <typename TypeHandler> GOOGLE_ATTRIBUTE_NOINLINE
void AddAllocatedSlowWithCopy(typename TypeHandler::Type* value,
Arena* value_arena,
- Arena* my_arena)
- GOOGLE_ATTRIBUTE_NOINLINE;
- template <typename TypeHandler>
- void AddAllocatedSlowWithoutCopy(typename TypeHandler::Type* value)
- GOOGLE_ATTRIBUTE_NOINLINE;
+ Arena* my_arena);
+ template <typename TypeHandler> GOOGLE_ATTRIBUTE_NOINLINE
+ void AddAllocatedSlowWithoutCopy(typename TypeHandler::Type* value);
template <typename TypeHandler>
typename TypeHandler::Type* ReleaseLastInternal(google::protobuf::internal::true_type);
template <typename TypeHandler>
typename TypeHandler::Type* ReleaseLastInternal(google::protobuf::internal::false_type);
- template<typename TypeHandler>
- inline void SwapFallback(RepeatedPtrFieldBase* other) GOOGLE_ATTRIBUTE_NOINLINE;
+ template<typename TypeHandler> GOOGLE_ATTRIBUTE_NOINLINE
+ void SwapFallback(RepeatedPtrFieldBase* other);
inline Arena* GetArenaNoVirtual() const {
return arena_;
@@ -542,20 +541,10 @@ class GenericTypeHandler {
}
// 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. Note that the GOOGLE_ATTRIBUTE_NOINLINE macro
- // requires the 'inline' storage class here, which is somewhat confusing, but
- // the compiler does the right thing.
- static inline GenericType* NewFromPrototype(const GenericType* prototype,
- ::google::protobuf::Arena* arena = NULL)
- GOOGLE_ATTRIBUTE_NOINLINE {
- return New(arena);
- }
- static inline void Delete(GenericType* value, Arena* arena)
- GOOGLE_ATTRIBUTE_NOINLINE {
- if (arena == NULL) {
- delete value;
- }
- }
+ // constructors and destructors.
+ 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 ::google::protobuf::Arena* GetArena(GenericType* value) {
return ::google::protobuf::Arena::GetArena<Type>(value);
}
@@ -564,10 +553,8 @@ class GenericTypeHandler {
}
static inline void Clear(GenericType* value) { value->Clear(); }
- static inline void Merge(const GenericType& from, GenericType* to)
- GOOGLE_ATTRIBUTE_NOINLINE {
- to->MergeFrom(from);
- }
+ GOOGLE_ATTRIBUTE_NOINLINE static void Merge(const GenericType& from,
+ GenericType* to);
static inline int SpaceUsed(const GenericType& value) {
return value.SpaceUsed();
}
@@ -576,11 +563,31 @@ class GenericTypeHandler {
}
};
-template<>
-inline MessageLite* GenericTypeHandler<MessageLite>::NewFromPrototype(
- const MessageLite* prototype, google::protobuf::Arena* arena) {
- return prototype->New(arena);
+template <typename GenericType>
+GenericType* GenericTypeHandler<GenericType>::NewFromPrototype(
+ const GenericType* prototype, ::google::protobuf::Arena* arena) {
+ 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);
+}
+
+// NewFromPrototype() and Merge() cannot be defined here; if they're declared
+// inline the compiler will complain about not matching GOOGLE_ATTRIBUTE_NOINLINE
+// above, and if not, compilation will result in multiple definitions. These
+// are therefore declared as specializations here and defined in
+// message_lite.cc.
+template<>
+MessageLite* GenericTypeHandler<MessageLite>::NewFromPrototype(
+ const MessageLite* prototype, google::protobuf::Arena* arena);
template<>
inline google::protobuf::Arena* GenericTypeHandler<MessageLite>::GetArena(
MessageLite* value) {
@@ -591,14 +598,9 @@ inline void* GenericTypeHandler<MessageLite>::GetMaybeArenaPointer(
MessageLite* value) {
return value->GetMaybeArenaPointer();
}
-
-// Implements GenericTypeHandler specialization required by RepeatedPtrFields
-// to work with MessageLite type.
template <>
-inline void GenericTypeHandler<MessageLite>::Merge(
- const MessageLite& from, MessageLite* to) {
- to->CheckTypeAndMergeFrom(from);
-}
+void GenericTypeHandler<MessageLite>::Merge(const MessageLite& from,
+ MessageLite* to);
// Declarations of the specialization as we cannot define them here, as the
// header that defines ProtocolMessage depends on types defined in this header.
@@ -1221,13 +1223,17 @@ void RepeatedField<Element>::Reserve(int new_size) {
Arena* arena = GetArenaNoVirtual();
new_size = max(google::protobuf::internal::kMinRepeatedFieldAllocationSize,
max(total_size_ * 2, new_size));
+ GOOGLE_CHECK_LE(new_size,
+ (std::numeric_limits<size_t>::max() - kRepHeaderSize) /
+ sizeof(Element))
+ << "Requested size is too large to fit into size_t.";
if (arena == NULL) {
rep_ = reinterpret_cast<Rep*>(
- new char[kRepHeaderSize + sizeof(Element)*new_size]);
+ new char[kRepHeaderSize + sizeof(Element) * new_size]);
} else {
rep_ = reinterpret_cast<Rep*>(
::google::protobuf::Arena::CreateArray<char>(arena,
- kRepHeaderSize + sizeof(Element)*new_size));
+ kRepHeaderSize + sizeof(Element) * new_size));
}
rep_->arena = arena;
int old_total_size = total_size_;
@@ -1342,7 +1348,7 @@ inline void RepeatedPtrFieldBase::Swap(RepeatedPtrFieldBase* other) {
}
template <typename TypeHandler>
-inline void RepeatedPtrFieldBase::SwapFallback(RepeatedPtrFieldBase* other) {
+void RepeatedPtrFieldBase::SwapFallback(RepeatedPtrFieldBase* other) {
GOOGLE_DCHECK(other->GetArenaNoVirtual() != GetArenaNoVirtual());
// Copy semantics in this case. We try to improve efficiency by placing the