diff options
author | Adam Cozzette <acozzette@google.com> | 2017-09-12 10:32:01 -0700 |
---|---|---|
committer | Adam Cozzette <acozzette@google.com> | 2017-09-14 10:03:57 -0700 |
commit | 13fd045dbb2b4dacea32be162a41d5a4b0d1802f (patch) | |
tree | c219e7eb18b82523e36c6748861c403a14ea66ae /src/google/protobuf/repeated_field.h | |
parent | d1bc27caef8377a710370189675cb0958443e8f1 (diff) |
Integrated internal changes from Google
Diffstat (limited to 'src/google/protobuf/repeated_field.h')
-rw-r--r-- | src/google/protobuf/repeated_field.h | 94 |
1 files changed, 86 insertions, 8 deletions
diff --git a/src/google/protobuf/repeated_field.h b/src/google/protobuf/repeated_field.h index d8003b8f..1910e362 100644 --- a/src/google/protobuf/repeated_field.h +++ b/src/google/protobuf/repeated_field.h @@ -60,6 +60,7 @@ #include <google/protobuf/stubs/type_traits.h> #include <google/protobuf/arena.h> #include <google/protobuf/message_lite.h> +#include <google/protobuf/stubs/port.h> // Forward-declare these so that we can make them friends. @@ -118,6 +119,11 @@ class RepeatedField PROTOBUF_FINAL { RepeatedField& operator=(const RepeatedField& other); +#if LANG_CXX11 + RepeatedField(RepeatedField&& other) noexcept; + RepeatedField& operator=(RepeatedField&& other) noexcept; +#endif + bool empty() const; int size() const; @@ -280,6 +286,10 @@ class RepeatedField PROTOBUF_FINAL { friend class Arena; typedef void InternalArenaConstructable_; + + // Move the contents of |from| into |to|, possibly clobbering |from| in the + // process. For primitive types this is just a memcpy(), but it could be + // specialized for non-primitive types to, say, swap each element instead. void MoveArray(Element* to, Element* from, int size); // Copy the elements of |from| into |to|. @@ -473,8 +483,8 @@ class LIBPROTOBUF_EXPORT RepeatedPtrFieldBase { template <typename TypeHandler> const typename TypeHandler::Type* const* data() const; - template <typename TypeHandler> - GOOGLE_ATTRIBUTE_ALWAYS_INLINE void Swap(RepeatedPtrFieldBase* other); + template <typename TypeHandler> GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE + void Swap(RepeatedPtrFieldBase* other); void SwapElements(int index1, int index2); @@ -524,11 +534,11 @@ class LIBPROTOBUF_EXPORT RepeatedPtrFieldBase { void AddAllocatedInternal(typename TypeHandler::Type* value, google::protobuf::internal::false_type); - template <typename TypeHandler> GOOGLE_ATTRIBUTE_NOINLINE + template <typename TypeHandler> GOOGLE_PROTOBUF_ATTRIBUTE_NOINLINE void AddAllocatedSlowWithCopy(typename TypeHandler::Type* value, Arena* value_arena, Arena* my_arena); - template <typename TypeHandler> GOOGLE_ATTRIBUTE_NOINLINE + template <typename TypeHandler> GOOGLE_PROTOBUF_ATTRIBUTE_NOINLINE void AddAllocatedSlowWithoutCopy(typename TypeHandler::Type* value); template <typename TypeHandler> @@ -536,7 +546,7 @@ class LIBPROTOBUF_EXPORT RepeatedPtrFieldBase { template <typename TypeHandler> typename TypeHandler::Type* ReleaseLastInternal(google::protobuf::internal::false_type); - template<typename TypeHandler> GOOGLE_ATTRIBUTE_NOINLINE + template<typename TypeHandler> GOOGLE_PROTOBUF_ATTRIBUTE_NOINLINE void SwapFallback(RepeatedPtrFieldBase* other); inline Arena* GetArenaNoVirtual() const { @@ -623,8 +633,8 @@ class GenericTypeHandler { } static inline void Clear(GenericType* value) { value->Clear(); } - GOOGLE_ATTRIBUTE_NOINLINE static void Merge(const GenericType& from, - GenericType* to); + GOOGLE_PROTOBUF_ATTRIBUTE_NOINLINE + static void Merge(const GenericType& from, GenericType* to); static inline size_t SpaceUsedLong(const GenericType& value) { return value.SpaceUsedLong(); } @@ -770,6 +780,11 @@ class RepeatedPtrField PROTOBUF_FINAL : public internal::RepeatedPtrFieldBase { RepeatedPtrField& operator=(const RepeatedPtrField& other); +#if LANG_CXX11 + RepeatedPtrField(RepeatedPtrField&& other) noexcept; + RepeatedPtrField& operator=(RepeatedPtrField&& other) noexcept; +#endif + bool empty() const; int size() const; @@ -1086,6 +1101,37 @@ RepeatedField<Element>::operator=(const RepeatedField& other) { return *this; } +#if LANG_CXX11 + +template <typename Element> +inline RepeatedField<Element>::RepeatedField(RepeatedField&& other) noexcept + : RepeatedField() { + // We don't just call Swap(&other) here because it would perform 3 copies if + // the two fields are on different arenas. + if (other.GetArenaNoVirtual()) { + CopyFrom(other); + } else { + InternalSwap(&other); + } +} + +template <typename Element> +inline RepeatedField<Element>& RepeatedField<Element>::operator=( + RepeatedField&& other) noexcept { + // We don't just call Swap(&other) here because it would perform 3 copies if + // the two fields are on different arenas. + if (this != &other) { + if (this->GetArenaNoVirtual() != other.GetArenaNoVirtual()) { + CopyFrom(other); + } else { + InternalSwap(&other); + } + } + return *this; +} + +#endif // LANG_CXX11 + template <typename Element> inline bool RepeatedField<Element>::empty() const { return current_size_ == 0; @@ -1900,6 +1946,38 @@ inline RepeatedPtrField<Element>& RepeatedPtrField<Element>::operator=( return *this; } +#if LANG_CXX11 + +template <typename Element> +inline RepeatedPtrField<Element>::RepeatedPtrField( + RepeatedPtrField&& other) noexcept + : RepeatedPtrField() { + // We don't just call Swap(&other) here because it would perform 3 copies if + // the two fields are on different arenas. + if (other.GetArenaNoVirtual()) { + CopyFrom(other); + } else { + InternalSwap(&other); + } +} + +template <typename Element> +inline RepeatedPtrField<Element>& RepeatedPtrField<Element>::operator=( + RepeatedPtrField&& other) noexcept { + // We don't just call Swap(&other) here because it would perform 3 copies if + // the two fields are on different arenas. + if (this != &other) { + if (this->GetArenaNoVirtual() != other.GetArenaNoVirtual()) { + CopyFrom(other); + } else { + InternalSwap(&other); + } + } + return *this; +} + +#endif // LANG_CXX11 + template <typename Element> inline bool RepeatedPtrField<Element>::empty() const { return RepeatedPtrFieldBase::empty(); @@ -2184,7 +2262,7 @@ class RepeatedPtrIterator : it_(other.it_) { // Force a compiler error if the other type is not convertible to ours. if (false) { - implicit_cast<Element*, OtherElement*>(0); + implicit_cast<Element*>(static_cast<OtherElement*>(NULL)); } } |