File indexing completed on 2025-01-31 10:12:26
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021 #ifndef GOOGLE_PROTOBUF_REPEATED_PTR_FIELD_H__
0022 #define GOOGLE_PROTOBUF_REPEATED_PTR_FIELD_H__
0023
0024 #include <algorithm>
0025 #include <cstddef>
0026 #include <cstdint>
0027 #include <iterator>
0028 #include <limits>
0029 #include <string>
0030 #include <tuple>
0031 #include <type_traits>
0032 #include <utility>
0033
0034 #include "absl/base/attributes.h"
0035 #include "absl/base/prefetch.h"
0036 #include "absl/log/absl_check.h"
0037 #include "absl/meta/type_traits.h"
0038 #include "google/protobuf/arena.h"
0039 #include "google/protobuf/internal_visibility.h"
0040 #include "google/protobuf/message_lite.h"
0041 #include "google/protobuf/port.h"
0042
0043
0044
0045 #include "google/protobuf/port_def.inc"
0046
0047 #ifdef SWIG
0048 #error "You cannot SWIG proto headers"
0049 #endif
0050
0051 namespace google {
0052 namespace protobuf {
0053
0054 class Message;
0055 class Reflection;
0056
0057 template <typename T>
0058 struct WeakRepeatedPtrField;
0059
0060 namespace internal {
0061
0062 class MergePartialFromCodedStreamHelper;
0063 class SwapFieldHelper;
0064
0065
0066 }
0067
0068 namespace internal {
0069 template <typename It>
0070 class RepeatedPtrIterator;
0071 template <typename It, typename VoidPtr>
0072 class RepeatedPtrOverPtrsIterator;
0073 }
0074
0075 namespace internal {
0076
0077
0078 template <size_t N>
0079 inline void memswap(char* PROTOBUF_RESTRICT a, char* PROTOBUF_RESTRICT b) {
0080
0081
0082 std::swap_ranges(a, a + N, b);
0083 }
0084
0085 template <typename T>
0086 struct IsMovable
0087 : std::integral_constant<bool, std::is_move_constructible<T>::value &&
0088 std::is_move_assignable<T>::value> {};
0089
0090
0091
0092
0093 template <typename T>
0094 struct ArenaOffsetHelper {
0095 constexpr static size_t value = offsetof(T, arena_);
0096 };
0097
0098
0099
0100
0101
0102
0103
0104
0105
0106
0107
0108
0109
0110
0111
0112
0113
0114
0115
0116 class PROTOBUF_EXPORT RepeatedPtrFieldBase {
0117 template <typename Handler>
0118 using Value = typename Handler::Type;
0119
0120 static constexpr int kSSOCapacity = 1;
0121
0122 using ElementFactory = void* (*)(Arena*);
0123
0124 protected:
0125
0126
0127 template <typename Handler>
0128 using CommonHandler = typename std::conditional<
0129 std::is_base_of<MessageLite, Value<Handler>>::value,
0130 internal::GenericTypeHandler<MessageLite>, Handler>::type;
0131
0132 constexpr RepeatedPtrFieldBase()
0133 : tagged_rep_or_elem_(nullptr),
0134 current_size_(0),
0135 capacity_proxy_(0),
0136 arena_(nullptr) {}
0137 explicit RepeatedPtrFieldBase(Arena* arena)
0138 : tagged_rep_or_elem_(nullptr),
0139 current_size_(0),
0140 capacity_proxy_(0),
0141 arena_(arena) {}
0142
0143 RepeatedPtrFieldBase(const RepeatedPtrFieldBase&) = delete;
0144 RepeatedPtrFieldBase& operator=(const RepeatedPtrFieldBase&) = delete;
0145
0146 ~RepeatedPtrFieldBase() {
0147 #ifndef NDEBUG
0148
0149
0150 if (arena_) (void)arena_->SpaceAllocated();
0151 #endif
0152 }
0153
0154 bool empty() const { return current_size_ == 0; }
0155 int size() const { return current_size_; }
0156
0157
0158
0159
0160
0161
0162 int Capacity() const { return capacity_proxy_ + kSSOCapacity; }
0163
0164 template <typename TypeHandler>
0165 const Value<TypeHandler>& at(int index) const {
0166 ABSL_CHECK_GE(index, 0);
0167 ABSL_CHECK_LT(index, current_size_);
0168 return *cast<TypeHandler>(element_at(index));
0169 }
0170
0171 template <typename TypeHandler>
0172 Value<TypeHandler>& at(int index) {
0173 ABSL_CHECK_GE(index, 0);
0174 ABSL_CHECK_LT(index, current_size_);
0175 return *cast<TypeHandler>(element_at(index));
0176 }
0177
0178 template <typename TypeHandler>
0179 Value<TypeHandler>* Mutable(int index) {
0180 ABSL_DCHECK_GE(index, 0);
0181 ABSL_DCHECK_LT(index, current_size_);
0182 return cast<TypeHandler>(element_at(index));
0183 }
0184
0185 template <typename Handler>
0186 Value<Handler>* Add() {
0187 if (std::is_same<Value<Handler>, std::string>{}) {
0188 return cast<Handler>(AddString());
0189 }
0190 return cast<Handler>(AddMessageLite(Handler::GetNewFunc()));
0191 }
0192
0193 template <
0194 typename TypeHandler,
0195 typename std::enable_if<TypeHandler::Movable::value>::type* = nullptr>
0196 inline void Add(Value<TypeHandler>&& value) {
0197 if (current_size_ < allocated_size()) {
0198 *cast<TypeHandler>(element_at(ExchangeCurrentSize(current_size_ + 1))) =
0199 std::move(value);
0200 return;
0201 }
0202 MaybeExtend();
0203 if (!using_sso()) ++rep()->allocated_size;
0204 auto* result = TypeHandler::New(arena_, std::move(value));
0205 element_at(ExchangeCurrentSize(current_size_ + 1)) = result;
0206 }
0207
0208
0209
0210
0211 template <typename TypeHandler>
0212 void Destroy() {
0213 ABSL_DCHECK(NeedsDestroy());
0214
0215
0216
0217 if (PROTOBUF_PREDICT_FALSE(arena_ != nullptr)) return;
0218
0219 using H = CommonHandler<TypeHandler>;
0220 int n = allocated_size();
0221 void** elems = elements();
0222 for (int i = 0; i < n; i++) {
0223 Delete<H>(elems[i], nullptr);
0224 }
0225 if (!using_sso()) {
0226 internal::SizedDelete(rep(),
0227 Capacity() * sizeof(elems[0]) + kRepHeaderSize);
0228 }
0229 }
0230
0231 inline bool NeedsDestroy() const {
0232
0233
0234 return tagged_rep_or_elem_ != nullptr;
0235 }
0236 void DestroyProtos();
0237
0238 public:
0239
0240
0241
0242
0243 template <typename TypeHandler>
0244 const Value<TypeHandler>& Get(int index) const {
0245 ABSL_DCHECK_GE(index, 0);
0246 ABSL_DCHECK_LT(index, current_size_);
0247 return *cast<TypeHandler>(element_at(index));
0248 }
0249
0250
0251
0252
0253
0254 MessageLite* AddMessage(const MessageLite* prototype);
0255
0256 template <typename TypeHandler>
0257 void Clear() {
0258 const int n = current_size_;
0259 ABSL_DCHECK_GE(n, 0);
0260 if (n > 0) {
0261 using H = CommonHandler<TypeHandler>;
0262 ClearNonEmpty<H>();
0263 }
0264 }
0265
0266
0267 template <typename T>
0268 void MergeFrom(const RepeatedPtrFieldBase& from) {
0269 static_assert(std::is_base_of<MessageLite, T>::value, "");
0270 #ifdef __cpp_if_constexpr
0271 if constexpr (!std::is_base_of<Message, T>::value) {
0272
0273 return MergeFrom<MessageLite>(from);
0274 }
0275 #endif
0276 MergeFromConcreteMessage(from, Arena::CopyConstruct<T>);
0277 }
0278
0279 inline void InternalSwap(RepeatedPtrFieldBase* PROTOBUF_RESTRICT rhs) {
0280 ABSL_DCHECK(this != rhs);
0281
0282
0283 internal::memswap<ArenaOffsetHelper<RepeatedPtrFieldBase>::value>(
0284 reinterpret_cast<char*>(this), reinterpret_cast<char*>(rhs));
0285 }
0286
0287
0288 bool PrepareForParse() { return allocated_size() == current_size_; }
0289
0290
0291
0292
0293 void AddAllocatedForParse(void* value) {
0294 ABSL_DCHECK(PrepareForParse());
0295 if (PROTOBUF_PREDICT_FALSE(SizeAtCapacity())) {
0296 *InternalExtend(1) = value;
0297 ++rep()->allocated_size;
0298 } else {
0299 if (using_sso()) {
0300 tagged_rep_or_elem_ = value;
0301 } else {
0302 rep()->elements[current_size_] = value;
0303 ++rep()->allocated_size;
0304 }
0305 }
0306 ExchangeCurrentSize(current_size_ + 1);
0307 }
0308
0309 protected:
0310 template <typename TypeHandler>
0311 void RemoveLast() {
0312 ABSL_DCHECK_GT(current_size_, 0);
0313 ExchangeCurrentSize(current_size_ - 1);
0314 using H = CommonHandler<TypeHandler>;
0315 H::Clear(cast<H>(element_at(current_size_)));
0316 }
0317
0318 template <typename TypeHandler>
0319 void CopyFrom(const RepeatedPtrFieldBase& other) {
0320 if (&other == this) return;
0321 RepeatedPtrFieldBase::Clear<TypeHandler>();
0322 if (other.empty()) return;
0323 RepeatedPtrFieldBase::MergeFrom<typename TypeHandler::Type>(other);
0324 }
0325
0326 void CloseGap(int start, int num);
0327
0328 void Reserve(int capacity);
0329
0330 template <typename TypeHandler>
0331 static inline Value<TypeHandler>* copy(const Value<TypeHandler>* value) {
0332 using H = CommonHandler<TypeHandler>;
0333 auto* new_value = H::NewFromPrototype(value, nullptr);
0334 H::Merge(*value, new_value);
0335 return cast<TypeHandler>(new_value);
0336 }
0337
0338
0339 void* const* raw_data() const { return elements(); }
0340 void** raw_mutable_data() { return elements(); }
0341
0342 template <typename TypeHandler>
0343 Value<TypeHandler>** mutable_data() {
0344
0345
0346 return reinterpret_cast<Value<TypeHandler>**>(raw_mutable_data());
0347 }
0348
0349 template <typename TypeHandler>
0350 const Value<TypeHandler>* const* data() const {
0351
0352
0353 return reinterpret_cast<const Value<TypeHandler>* const*>(raw_data());
0354 }
0355
0356 template <typename TypeHandler>
0357 PROTOBUF_NDEBUG_INLINE void Swap(RepeatedPtrFieldBase* other) {
0358 #ifdef PROTOBUF_FORCE_COPY_IN_SWAP
0359 if (GetArena() != nullptr && GetArena() == other->GetArena())
0360 #else
0361 if (GetArena() == other->GetArena())
0362 #endif
0363 {
0364 InternalSwap(other);
0365 } else {
0366 SwapFallback<TypeHandler>(other);
0367 }
0368 }
0369
0370 void SwapElements(int index1, int index2) {
0371 using std::swap;
0372 swap(element_at(index1), element_at(index2));
0373 }
0374
0375 template <typename TypeHandler>
0376 PROTOBUF_NOINLINE size_t SpaceUsedExcludingSelfLong() const {
0377 size_t allocated_bytes =
0378 using_sso()
0379 ? 0
0380 : static_cast<size_t>(Capacity()) * sizeof(void*) + kRepHeaderSize;
0381 const int n = allocated_size();
0382 void* const* elems = elements();
0383 for (int i = 0; i < n; ++i) {
0384 allocated_bytes +=
0385 TypeHandler::SpaceUsedLong(*cast<TypeHandler>(elems[i]));
0386 }
0387 return allocated_bytes;
0388 }
0389
0390
0391
0392
0393 template <typename TypeHandler>
0394 Value<TypeHandler>* AddFromCleared() {
0395 if (current_size_ < allocated_size()) {
0396 return cast<TypeHandler>(
0397 element_at(ExchangeCurrentSize(current_size_ + 1)));
0398 } else {
0399 return nullptr;
0400 }
0401 }
0402
0403 template <typename TypeHandler>
0404 void AddAllocated(Value<TypeHandler>* value) {
0405 ABSL_DCHECK_NE(value, nullptr);
0406 Arena* element_arena = TypeHandler::GetArena(value);
0407 Arena* arena = GetArena();
0408 if (arena != element_arena || AllocatedSizeAtCapacity()) {
0409 AddAllocatedSlowWithCopy<TypeHandler>(value, element_arena, arena);
0410 return;
0411 }
0412
0413
0414
0415 void** elems = elements();
0416 if (current_size_ < allocated_size()) {
0417
0418
0419 elems[allocated_size()] = elems[current_size_];
0420 }
0421 elems[ExchangeCurrentSize(current_size_ + 1)] = value;
0422 if (!using_sso()) ++rep()->allocated_size;
0423 }
0424
0425 template <typename TypeHandler>
0426 void UnsafeArenaAddAllocated(Value<TypeHandler>* value) {
0427 ABSL_DCHECK_NE(value, nullptr);
0428
0429 if (SizeAtCapacity()) {
0430
0431 InternalExtend(1);
0432 ++rep()->allocated_size;
0433 } else if (AllocatedSizeAtCapacity()) {
0434
0435
0436
0437
0438 using H = CommonHandler<TypeHandler>;
0439 Delete<H>(element_at(current_size_), arena_);
0440 } else if (current_size_ < allocated_size()) {
0441
0442
0443 element_at(allocated_size()) = element_at(current_size_);
0444 ++rep()->allocated_size;
0445 } else {
0446
0447 if (!using_sso()) ++rep()->allocated_size;
0448 }
0449
0450 element_at(ExchangeCurrentSize(current_size_ + 1)) = value;
0451 }
0452
0453 template <typename TypeHandler>
0454 PROTOBUF_NODISCARD Value<TypeHandler>* ReleaseLast() {
0455 Value<TypeHandler>* result = UnsafeArenaReleaseLast<TypeHandler>();
0456
0457 Arena* arena = GetArena();
0458
0459 #ifdef PROTOBUF_FORCE_COPY_IN_RELEASE
0460 auto* new_result = copy<TypeHandler>(result);
0461 if (arena == nullptr) delete result;
0462 #else
0463 auto* new_result = (arena == nullptr) ? result : copy<TypeHandler>(result);
0464 #endif
0465 return new_result;
0466 }
0467
0468
0469
0470
0471 template <typename TypeHandler>
0472 Value<TypeHandler>* UnsafeArenaReleaseLast() {
0473 ABSL_DCHECK_GT(current_size_, 0);
0474 ExchangeCurrentSize(current_size_ - 1);
0475 auto* result = cast<TypeHandler>(element_at(current_size_));
0476 if (using_sso()) {
0477 tagged_rep_or_elem_ = nullptr;
0478 } else {
0479 --rep()->allocated_size;
0480 if (current_size_ < allocated_size()) {
0481
0482
0483 element_at(current_size_) = element_at(allocated_size());
0484 }
0485 }
0486 return result;
0487 }
0488
0489 int ClearedCount() const { return allocated_size() - current_size_; }
0490
0491
0492 template <typename TypeHandler>
0493 PROTOBUF_NOINLINE void AddAllocatedSlowWithCopy(
0494
0495
0496 Value<TypeHandler>* value, Arena* value_arena, Arena* my_arena) {
0497 using H = CommonHandler<TypeHandler>;
0498
0499
0500
0501 if (my_arena != nullptr && value_arena == nullptr) {
0502 my_arena->Own(value);
0503 } else if (my_arena != value_arena) {
0504 ABSL_DCHECK(value_arena != nullptr);
0505 auto* new_value = TypeHandler::NewFromPrototype(value, my_arena);
0506 H::Merge(*value, new_value);
0507 value = new_value;
0508 }
0509
0510 UnsafeArenaAddAllocated<H>(value);
0511 }
0512
0513 template <typename TypeHandler>
0514 PROTOBUF_NOINLINE void SwapFallback(RepeatedPtrFieldBase* other) {
0515 #ifdef PROTOBUF_FORCE_COPY_IN_SWAP
0516 ABSL_DCHECK(GetArena() == nullptr || other->GetArena() != GetArena());
0517 #else
0518 ABSL_DCHECK(other->GetArena() != GetArena());
0519 #endif
0520
0521
0522
0523
0524 RepeatedPtrFieldBase temp(other->GetArena());
0525 if (!this->empty()) {
0526 temp.MergeFrom<typename TypeHandler::Type>(*this);
0527 }
0528 this->CopyFrom<TypeHandler>(*other);
0529 other->InternalSwap(&temp);
0530 if (temp.NeedsDestroy()) {
0531 temp.Destroy<TypeHandler>();
0532 }
0533 }
0534
0535
0536 inline Arena* GetArena() const { return arena_; }
0537
0538 private:
0539 using InternalArenaConstructable_ = void;
0540 using DestructorSkippable_ = void;
0541
0542 template <typename T>
0543 friend class Arena::InternalHelper;
0544
0545
0546
0547
0548
0549
0550 friend class ExtensionSet;
0551
0552
0553
0554
0555 friend class MapFieldBase;
0556 friend struct MapFieldTestPeer;
0557
0558
0559
0560 friend class MergePartialFromCodedStreamHelper;
0561
0562 friend class AccessorHelper;
0563
0564 template <typename T>
0565 friend struct google::protobuf::WeakRepeatedPtrField;
0566
0567 friend class internal::TcParser;
0568
0569
0570
0571 template <typename T>
0572 friend struct ArenaOffsetHelper;
0573
0574
0575
0576
0577 friend class google::protobuf::Reflection;
0578 friend class internal::SwapFieldHelper;
0579
0580
0581
0582
0583
0584 using CopyFn = void* (*)(Arena*, const void*);
0585
0586 struct Rep {
0587 int allocated_size;
0588
0589
0590 void* elements[(std::numeric_limits<int>::max() - 2 * sizeof(int)) /
0591 sizeof(void*)];
0592 };
0593
0594 static constexpr size_t kRepHeaderSize = offsetof(Rep, elements);
0595
0596
0597
0598
0599 inline int ExchangeCurrentSize(int new_size) {
0600 return std::exchange(current_size_, new_size);
0601 }
0602 inline bool SizeAtCapacity() const {
0603
0604 ABSL_DCHECK_LE(size(), allocated_size());
0605 ABSL_DCHECK_LE(allocated_size(), Capacity());
0606
0607
0608
0609
0610 return current_size_ >= Capacity();
0611 }
0612 inline bool AllocatedSizeAtCapacity() const {
0613
0614 ABSL_DCHECK_LE(size(), allocated_size());
0615 ABSL_DCHECK_LE(allocated_size(), Capacity());
0616
0617
0618 return using_sso() ? (tagged_rep_or_elem_ != nullptr)
0619 : rep()->allocated_size >= Capacity();
0620 }
0621
0622 void* const* elements() const {
0623 return using_sso() ? &tagged_rep_or_elem_ : +rep()->elements;
0624 }
0625 void** elements() {
0626 return using_sso() ? &tagged_rep_or_elem_ : +rep()->elements;
0627 }
0628
0629 void*& element_at(int index) {
0630 if (using_sso()) {
0631 ABSL_DCHECK_EQ(index, 0);
0632 return tagged_rep_or_elem_;
0633 }
0634 return rep()->elements[index];
0635 }
0636 const void* element_at(int index) const {
0637 return const_cast<RepeatedPtrFieldBase*>(this)->element_at(index);
0638 }
0639
0640 int allocated_size() const {
0641 return using_sso() ? (tagged_rep_or_elem_ != nullptr ? 1 : 0)
0642 : rep()->allocated_size;
0643 }
0644 Rep* rep() {
0645 ABSL_DCHECK(!using_sso());
0646 return reinterpret_cast<Rep*>(
0647 reinterpret_cast<uintptr_t>(tagged_rep_or_elem_) - 1);
0648 }
0649 const Rep* rep() const {
0650 return const_cast<RepeatedPtrFieldBase*>(this)->rep();
0651 }
0652
0653 bool using_sso() const {
0654 return (reinterpret_cast<uintptr_t>(tagged_rep_or_elem_) & 1) == 0;
0655 }
0656
0657 template <typename TypeHandler>
0658 static inline Value<TypeHandler>* cast(void* element) {
0659 return reinterpret_cast<Value<TypeHandler>*>(element);
0660 }
0661 template <typename TypeHandler>
0662 static inline const Value<TypeHandler>* cast(const void* element) {
0663 return reinterpret_cast<const Value<TypeHandler>*>(element);
0664 }
0665 template <typename TypeHandler>
0666 static inline void Delete(void* obj, Arena* arena) {
0667 TypeHandler::Delete(cast<TypeHandler>(obj), arena);
0668 }
0669
0670
0671
0672 template <typename TypeHandler>
0673 PROTOBUF_NOINLINE void ClearNonEmpty() {
0674 const int n = current_size_;
0675 void* const* elems = elements();
0676 int i = 0;
0677 ABSL_DCHECK_GT(n, 0);
0678
0679 do {
0680 TypeHandler::Clear(cast<TypeHandler>(elems[i++]));
0681 } while (i < n);
0682 ExchangeCurrentSize(0);
0683 }
0684
0685
0686
0687
0688
0689
0690
0691
0692 int MergeIntoClearedMessages(const RepeatedPtrFieldBase& from);
0693
0694
0695
0696 void MergeFromConcreteMessage(const RepeatedPtrFieldBase& from,
0697 CopyFn copy_fn);
0698
0699
0700
0701
0702 void** InternalExtend(int extend_amount);
0703
0704
0705 inline void MaybeExtend() {
0706 if (AllocatedSizeAtCapacity()) {
0707 ABSL_DCHECK_EQ(allocated_size(), Capacity());
0708 InternalExtend(1);
0709 } else {
0710 ABSL_DCHECK_NE(allocated_size(), Capacity());
0711 }
0712 }
0713
0714
0715
0716 inline void** InternalReserve(int n) {
0717 if (n <= Capacity()) {
0718 void** elements = using_sso() ? &tagged_rep_or_elem_ : rep()->elements;
0719 return elements + current_size_;
0720 }
0721 return InternalExtend(n - Capacity());
0722 }
0723
0724
0725 void* AddMessageLite(ElementFactory factory);
0726 void* AddString();
0727
0728
0729
0730
0731
0732
0733
0734
0735 template <typename Factory>
0736 void* AddInternal(Factory factory);
0737
0738
0739
0740
0741
0742
0743
0744
0745
0746
0747
0748
0749 void* tagged_rep_or_elem_;
0750 int current_size_;
0751 int capacity_proxy_;
0752 Arena* arena_;
0753 };
0754
0755
0756
0757
0758 template <>
0759 void RepeatedPtrFieldBase::MergeFrom<MessageLite>(
0760 const RepeatedPtrFieldBase& from);
0761
0762 template <>
0763 inline void RepeatedPtrFieldBase::MergeFrom<Message>(
0764 const RepeatedPtrFieldBase& from) {
0765 return MergeFrom<MessageLite>(from);
0766 }
0767
0768
0769 template <>
0770 void RepeatedPtrFieldBase::MergeFrom<std::string>(
0771 const RepeatedPtrFieldBase& from);
0772
0773
0774 template <typename F>
0775 void* RepeatedPtrFieldBase::AddInternal(F factory) {
0776 Arena* const arena = GetArena();
0777 if (tagged_rep_or_elem_ == nullptr) {
0778 ExchangeCurrentSize(1);
0779 tagged_rep_or_elem_ = factory(arena);
0780 return tagged_rep_or_elem_;
0781 }
0782 absl::PrefetchToLocalCache(tagged_rep_or_elem_);
0783 if (using_sso()) {
0784 if (current_size_ == 0) {
0785 ExchangeCurrentSize(1);
0786 return tagged_rep_or_elem_;
0787 }
0788 void*& result = *InternalExtend(1);
0789 result = factory(arena);
0790 Rep* r = rep();
0791 r->allocated_size = 2;
0792 ExchangeCurrentSize(2);
0793 return result;
0794 }
0795 Rep* r = rep();
0796 if (PROTOBUF_PREDICT_FALSE(SizeAtCapacity())) {
0797 InternalExtend(1);
0798 r = rep();
0799 } else {
0800 if (current_size_ != r->allocated_size) {
0801 return r->elements[ExchangeCurrentSize(current_size_ + 1)];
0802 }
0803 }
0804 ++r->allocated_size;
0805 void*& result = r->elements[ExchangeCurrentSize(current_size_ + 1)];
0806 result = factory(arena);
0807 return result;
0808 }
0809
0810 PROTOBUF_EXPORT void InternalOutOfLineDeleteMessageLite(MessageLite* message);
0811
0812 template <typename GenericType>
0813 class GenericTypeHandler {
0814 public:
0815 typedef GenericType Type;
0816 using Movable = IsMovable<GenericType>;
0817
0818 static constexpr auto GetNewFunc() { return Arena::DefaultConstruct<Type>; }
0819
0820 static inline GenericType* New(Arena* arena) {
0821 return static_cast<GenericType*>(Arena::DefaultConstruct<Type>(arena));
0822 }
0823 static inline GenericType* New(Arena* arena, GenericType&& value) {
0824 return Arena::Create<GenericType>(arena, std::move(value));
0825 }
0826 static inline GenericType* NewFromPrototype(const GenericType* ,
0827 Arena* arena = nullptr) {
0828 return New(arena);
0829 }
0830 static inline void Delete(GenericType* value, Arena* arena) {
0831 if (arena != nullptr) return;
0832 #ifdef __cpp_if_constexpr
0833 if constexpr (std::is_base_of<MessageLite, GenericType>::value) {
0834
0835
0836 InternalOutOfLineDeleteMessageLite(value);
0837 } else {
0838 delete value;
0839 }
0840 #else
0841 delete value;
0842 #endif
0843 }
0844 static inline Arena* GetArena(GenericType* value) {
0845 return Arena::InternalGetArena(value);
0846 }
0847
0848 static inline void Clear(GenericType* value) { value->Clear(); }
0849 static void Merge(const GenericType& from, GenericType* to);
0850 static inline size_t SpaceUsedLong(const GenericType& value) {
0851 return value.SpaceUsedLong();
0852 }
0853 };
0854
0855
0856
0857
0858 PROTOBUF_EXPORT MessageLite* NewFromPrototypeHelper(
0859 const MessageLite* prototype, Arena* arena);
0860
0861 template <>
0862 inline MessageLite* GenericTypeHandler<MessageLite>::NewFromPrototype(
0863 const MessageLite* prototype, Arena* arena) {
0864 return NewFromPrototypeHelper(prototype, arena);
0865 }
0866 template <>
0867 inline Arena* GenericTypeHandler<MessageLite>::GetArena(MessageLite* value) {
0868 return value->GetArena();
0869 }
0870
0871 template <typename GenericType>
0872 PROTOBUF_NOINLINE inline void GenericTypeHandler<GenericType>::Merge(
0873 const GenericType& from, GenericType* to) {
0874 to->MergeFrom(from);
0875 }
0876 template <>
0877 PROTOBUF_EXPORT void GenericTypeHandler<MessageLite>::Merge(
0878 const MessageLite& from, MessageLite* to);
0879
0880
0881
0882
0883 template <>
0884 PROTOBUF_EXPORT Message* GenericTypeHandler<Message>::NewFromPrototype(
0885 const Message* prototype, Arena* arena);
0886 template <>
0887 PROTOBUF_EXPORT Arena* GenericTypeHandler<Message>::GetArena(Message* value);
0888
0889 PROTOBUF_EXPORT void* NewStringElement(Arena* arena);
0890
0891 template <>
0892 class GenericTypeHandler<std::string> {
0893 public:
0894 typedef std::string Type;
0895 using Movable = IsMovable<Type>;
0896
0897 static constexpr auto GetNewFunc() { return NewStringElement; }
0898
0899 static PROTOBUF_NOINLINE std::string* New(Arena* arena) {
0900 return Arena::Create<std::string>(arena);
0901 }
0902 static PROTOBUF_NOINLINE std::string* New(Arena* arena, std::string&& value) {
0903 return Arena::Create<std::string>(arena, std::move(value));
0904 }
0905 static inline std::string* NewFromPrototype(const std::string*,
0906 Arena* arena) {
0907 return New(arena);
0908 }
0909 static inline Arena* GetArena(std::string*) { return nullptr; }
0910 static inline void Delete(std::string* value, Arena* arena) {
0911 if (arena == nullptr) {
0912 delete value;
0913 }
0914 }
0915 static inline void Clear(std::string* value) { value->clear(); }
0916 static inline void Merge(const std::string& from, std::string* to) {
0917 *to = from;
0918 }
0919 static size_t SpaceUsedLong(const std::string& value) {
0920 return sizeof(value) + StringSpaceUsedExcludingSelfLong(value);
0921 }
0922 };
0923
0924 }
0925
0926
0927
0928 template <typename Element>
0929 class RepeatedPtrField final : private internal::RepeatedPtrFieldBase {
0930 static_assert(!std::is_const<Element>::value,
0931 "We do not support const value types.");
0932 static_assert(!std::is_volatile<Element>::value,
0933 "We do not support volatile value types.");
0934 static_assert(!std::is_pointer<Element>::value,
0935 "We do not support pointer value types.");
0936 static_assert(!std::is_reference<Element>::value,
0937 "We do not support reference value types.");
0938 static constexpr PROTOBUF_ALWAYS_INLINE void StaticValidityCheck() {
0939 static_assert(
0940 absl::disjunction<
0941 internal::is_supported_string_type<Element>,
0942 internal::is_supported_message_type<Element>>::value,
0943 "We only support string and Message types in RepeatedPtrField.");
0944 }
0945
0946 public:
0947 using value_type = Element;
0948 using size_type = int;
0949 using difference_type = ptrdiff_t;
0950 using reference = Element&;
0951 using const_reference = const Element&;
0952 using pointer = Element*;
0953 using const_pointer = const Element*;
0954 using iterator = internal::RepeatedPtrIterator<Element>;
0955 using const_iterator = internal::RepeatedPtrIterator<const Element>;
0956 using reverse_iterator = std::reverse_iterator<iterator>;
0957 using const_reverse_iterator = std::reverse_iterator<const_iterator>;
0958
0959
0960 using pointer_iterator =
0961 internal::RepeatedPtrOverPtrsIterator<Element*, void*>;
0962 using const_pointer_iterator =
0963 internal::RepeatedPtrOverPtrsIterator<const Element* const,
0964 const void* const>;
0965
0966 constexpr RepeatedPtrField();
0967
0968
0969 RepeatedPtrField(internal::InternalVisibility, Arena* arena)
0970 : RepeatedPtrField(arena) {}
0971 RepeatedPtrField(internal::InternalVisibility, Arena* arena,
0972 const RepeatedPtrField& rhs)
0973 : RepeatedPtrField(arena, rhs) {}
0974
0975
0976 explicit RepeatedPtrField(Arena* arena);
0977
0978 template <typename Iter,
0979 typename = typename std::enable_if<std::is_constructible<
0980 Element, decltype(*std::declval<Iter>())>::value>::type>
0981 RepeatedPtrField(Iter begin, Iter end);
0982
0983 RepeatedPtrField(const RepeatedPtrField& rhs)
0984 : RepeatedPtrField(nullptr, rhs) {}
0985 RepeatedPtrField& operator=(const RepeatedPtrField& other)
0986 ABSL_ATTRIBUTE_LIFETIME_BOUND;
0987
0988 RepeatedPtrField(RepeatedPtrField&& rhs) noexcept
0989 : RepeatedPtrField(nullptr, std::move(rhs)) {}
0990 RepeatedPtrField& operator=(RepeatedPtrField&& other) noexcept
0991 ABSL_ATTRIBUTE_LIFETIME_BOUND;
0992
0993 ~RepeatedPtrField();
0994
0995 bool empty() const;
0996 int size() const;
0997
0998 const_reference Get(int index) const ABSL_ATTRIBUTE_LIFETIME_BOUND;
0999 pointer Mutable(int index) ABSL_ATTRIBUTE_LIFETIME_BOUND;
1000
1001
1002
1003
1004
1005 pointer Add() ABSL_ATTRIBUTE_LIFETIME_BOUND;
1006
1007
1008
1009
1010
1011
1012 void Add(Element&& value);
1013
1014
1015
1016
1017
1018
1019
1020 void Add(const Element& value) = delete;
1021
1022
1023
1024 template <typename Iter>
1025 void Add(Iter begin, Iter end);
1026
1027 const_reference operator[](int index) const ABSL_ATTRIBUTE_LIFETIME_BOUND {
1028 return Get(index);
1029 }
1030 reference operator[](int index) ABSL_ATTRIBUTE_LIFETIME_BOUND {
1031 return *Mutable(index);
1032 }
1033
1034 const_reference at(int index) const ABSL_ATTRIBUTE_LIFETIME_BOUND;
1035 reference at(int index) ABSL_ATTRIBUTE_LIFETIME_BOUND;
1036
1037
1038
1039 void RemoveLast();
1040
1041
1042
1043
1044 void DeleteSubrange(int start, int num);
1045
1046 ABSL_ATTRIBUTE_REINITIALIZES void Clear();
1047 void MergeFrom(const RepeatedPtrField& other);
1048 ABSL_ATTRIBUTE_REINITIALIZES void CopyFrom(const RepeatedPtrField& other);
1049
1050
1051 template <typename Iter>
1052 ABSL_ATTRIBUTE_REINITIALIZES void Assign(Iter begin, Iter end);
1053
1054
1055
1056
1057 void Reserve(int new_size);
1058
1059 int Capacity() const;
1060
1061
1062
1063 Element**
1064 mutable_data() ABSL_ATTRIBUTE_LIFETIME_BOUND;
1065 const Element* const* data() const ABSL_ATTRIBUTE_LIFETIME_BOUND;
1066
1067
1068
1069 void Swap(RepeatedPtrField* other);
1070
1071
1072
1073
1074
1075 void UnsafeArenaSwap(RepeatedPtrField* other);
1076
1077
1078 void SwapElements(int index1, int index2);
1079
1080 iterator begin() ABSL_ATTRIBUTE_LIFETIME_BOUND;
1081 const_iterator begin() const ABSL_ATTRIBUTE_LIFETIME_BOUND;
1082 const_iterator cbegin() const ABSL_ATTRIBUTE_LIFETIME_BOUND;
1083 iterator end() ABSL_ATTRIBUTE_LIFETIME_BOUND;
1084 const_iterator end() const ABSL_ATTRIBUTE_LIFETIME_BOUND;
1085 const_iterator cend() const ABSL_ATTRIBUTE_LIFETIME_BOUND;
1086
1087 reverse_iterator rbegin() ABSL_ATTRIBUTE_LIFETIME_BOUND {
1088 return reverse_iterator(end());
1089 }
1090 const_reverse_iterator rbegin() const ABSL_ATTRIBUTE_LIFETIME_BOUND {
1091 return const_reverse_iterator(end());
1092 }
1093 reverse_iterator rend() ABSL_ATTRIBUTE_LIFETIME_BOUND {
1094 return reverse_iterator(begin());
1095 }
1096 const_reverse_iterator rend() const ABSL_ATTRIBUTE_LIFETIME_BOUND {
1097 return const_reverse_iterator(begin());
1098 }
1099
1100 pointer_iterator pointer_begin() ABSL_ATTRIBUTE_LIFETIME_BOUND;
1101 const_pointer_iterator pointer_begin() const ABSL_ATTRIBUTE_LIFETIME_BOUND;
1102 pointer_iterator pointer_end() ABSL_ATTRIBUTE_LIFETIME_BOUND;
1103 const_pointer_iterator pointer_end() const ABSL_ATTRIBUTE_LIFETIME_BOUND;
1104
1105
1106
1107 size_t SpaceUsedExcludingSelfLong() const;
1108
1109 int SpaceUsedExcludingSelf() const {
1110 return internal::ToIntSize(SpaceUsedExcludingSelfLong());
1111 }
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129 void AddAllocated(Element* value);
1130
1131
1132
1133
1134
1135
1136
1137 PROTOBUF_NODISCARD Element* ReleaseLast();
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152 void UnsafeArenaAddAllocated(Element* value);
1153
1154
1155
1156
1157
1158 pointer UnsafeArenaReleaseLast();
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175 void ExtractSubrange(int start, int num, Element** elements);
1176
1177
1178
1179
1180
1181 void UnsafeArenaExtractSubrange(int start, int num, Element** elements);
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193 ABSL_DEPRECATED("This will be removed in a future release")
1194 int ClearedCount() const;
1195
1196
1197
1198
1199
1200
1201
1202 iterator erase(const_iterator position) ABSL_ATTRIBUTE_LIFETIME_BOUND;
1203
1204
1205
1206
1207
1208
1209 iterator erase(const_iterator first,
1210 const_iterator last) ABSL_ATTRIBUTE_LIFETIME_BOUND;
1211
1212
1213 inline Arena* GetArena();
1214
1215
1216
1217
1218 void InternalSwap(RepeatedPtrField* PROTOBUF_RESTRICT other) {
1219 internal::RepeatedPtrFieldBase::InternalSwap(other);
1220 }
1221
1222
1223 private:
1224 using InternalArenaConstructable_ = void;
1225 using DestructorSkippable_ = void;
1226
1227 friend class Arena;
1228
1229 friend class internal::TcParser;
1230
1231 template <typename T>
1232 friend struct WeakRepeatedPtrField;
1233
1234
1235 using TypeHandler = internal::GenericTypeHandler<Element>;
1236
1237 RepeatedPtrField(Arena* arena, const RepeatedPtrField& rhs);
1238 RepeatedPtrField(Arena* arena, RepeatedPtrField&& rhs);
1239
1240
1241 void AddAllocatedForParse(Element* p) {
1242 return RepeatedPtrFieldBase::AddAllocatedForParse(p);
1243 }
1244 };
1245
1246
1247
1248 template <typename Element>
1249 constexpr RepeatedPtrField<Element>::RepeatedPtrField()
1250 : RepeatedPtrFieldBase() {
1251 StaticValidityCheck();
1252 }
1253
1254 template <typename Element>
1255 inline RepeatedPtrField<Element>::RepeatedPtrField(Arena* arena)
1256 : RepeatedPtrFieldBase(arena) {
1257
1258
1259
1260 }
1261
1262 template <typename Element>
1263 inline RepeatedPtrField<Element>::RepeatedPtrField(Arena* arena,
1264 const RepeatedPtrField& rhs)
1265 : RepeatedPtrFieldBase(arena) {
1266 StaticValidityCheck();
1267 MergeFrom(rhs);
1268 }
1269
1270 template <typename Element>
1271 template <typename Iter, typename>
1272 inline RepeatedPtrField<Element>::RepeatedPtrField(Iter begin, Iter end) {
1273 StaticValidityCheck();
1274 Add(begin, end);
1275 }
1276
1277 template <typename Element>
1278 RepeatedPtrField<Element>::~RepeatedPtrField() {
1279 StaticValidityCheck();
1280 if (!NeedsDestroy()) return;
1281 #ifdef __cpp_if_constexpr
1282 if constexpr (std::is_base_of<MessageLite, Element>::value) {
1283 #else
1284 if (std::is_base_of<MessageLite, Element>::value) {
1285 #endif
1286 DestroyProtos();
1287 } else {
1288 Destroy<TypeHandler>();
1289 }
1290 }
1291
1292 template <typename Element>
1293 inline RepeatedPtrField<Element>& RepeatedPtrField<Element>::operator=(
1294 const RepeatedPtrField& other) ABSL_ATTRIBUTE_LIFETIME_BOUND {
1295 if (this != &other) CopyFrom(other);
1296 return *this;
1297 }
1298
1299 template <typename Element>
1300 inline RepeatedPtrField<Element>::RepeatedPtrField(Arena* arena,
1301 RepeatedPtrField&& rhs)
1302 : RepeatedPtrField(arena) {
1303 #ifdef PROTOBUF_FORCE_COPY_IN_MOVE
1304 CopyFrom(rhs);
1305 #else
1306
1307
1308 if (arena != rhs.GetArena()) {
1309 CopyFrom(rhs);
1310 } else {
1311 InternalSwap(&rhs);
1312 }
1313 #endif
1314 }
1315
1316 template <typename Element>
1317 inline RepeatedPtrField<Element>& RepeatedPtrField<Element>::operator=(
1318 RepeatedPtrField&& other) noexcept ABSL_ATTRIBUTE_LIFETIME_BOUND {
1319
1320
1321 if (this != &other) {
1322 if (GetArena() != other.GetArena()
1323 #ifdef PROTOBUF_FORCE_COPY_IN_MOVE
1324 || GetArena() == nullptr
1325 #endif
1326 ) {
1327 CopyFrom(other);
1328 } else {
1329 InternalSwap(&other);
1330 }
1331 }
1332 return *this;
1333 }
1334
1335 template <typename Element>
1336 inline bool RepeatedPtrField<Element>::empty() const {
1337 return RepeatedPtrFieldBase::empty();
1338 }
1339
1340 template <typename Element>
1341 inline int RepeatedPtrField<Element>::size() const {
1342 return RepeatedPtrFieldBase::size();
1343 }
1344
1345 template <typename Element>
1346 inline const Element& RepeatedPtrField<Element>::Get(int index) const
1347 ABSL_ATTRIBUTE_LIFETIME_BOUND {
1348 return RepeatedPtrFieldBase::Get<TypeHandler>(index);
1349 }
1350
1351 template <typename Element>
1352 inline const Element& RepeatedPtrField<Element>::at(int index) const
1353 ABSL_ATTRIBUTE_LIFETIME_BOUND {
1354 return RepeatedPtrFieldBase::at<TypeHandler>(index);
1355 }
1356
1357 template <typename Element>
1358 inline Element& RepeatedPtrField<Element>::at(int index)
1359 ABSL_ATTRIBUTE_LIFETIME_BOUND {
1360 return RepeatedPtrFieldBase::at<TypeHandler>(index);
1361 }
1362
1363
1364 template <typename Element>
1365 inline Element* RepeatedPtrField<Element>::Mutable(int index)
1366 ABSL_ATTRIBUTE_LIFETIME_BOUND {
1367 return RepeatedPtrFieldBase::Mutable<TypeHandler>(index);
1368 }
1369
1370 template <typename Element>
1371 inline Element* RepeatedPtrField<Element>::Add() ABSL_ATTRIBUTE_LIFETIME_BOUND {
1372 return RepeatedPtrFieldBase::Add<TypeHandler>();
1373 }
1374
1375 template <typename Element>
1376 inline void RepeatedPtrField<Element>::Add(Element&& value) {
1377 RepeatedPtrFieldBase::Add<TypeHandler>(std::move(value));
1378 }
1379
1380 template <typename Element>
1381 template <typename Iter>
1382 inline void RepeatedPtrField<Element>::Add(Iter begin, Iter end) {
1383 if (std::is_base_of<
1384 std::forward_iterator_tag,
1385 typename std::iterator_traits<Iter>::iterator_category>::value) {
1386 int reserve = static_cast<int>(std::distance(begin, end));
1387 Reserve(size() + reserve);
1388 }
1389 for (; begin != end; ++begin) {
1390 *Add() = *begin;
1391 }
1392 }
1393
1394 template <typename Element>
1395 inline void RepeatedPtrField<Element>::RemoveLast() {
1396 RepeatedPtrFieldBase::RemoveLast<TypeHandler>();
1397 }
1398
1399 template <typename Element>
1400 inline void RepeatedPtrField<Element>::DeleteSubrange(int start, int num) {
1401 ABSL_DCHECK_GE(start, 0);
1402 ABSL_DCHECK_GE(num, 0);
1403 ABSL_DCHECK_LE(start + num, size());
1404 void** subrange = raw_mutable_data() + start;
1405 Arena* arena = GetArena();
1406 for (int i = 0; i < num; ++i) {
1407 using H = CommonHandler<TypeHandler>;
1408 H::Delete(static_cast<Element*>(subrange[i]), arena);
1409 }
1410 UnsafeArenaExtractSubrange(start, num, nullptr);
1411 }
1412
1413 template <typename Element>
1414 inline void RepeatedPtrField<Element>::ExtractSubrange(int start, int num,
1415 Element** elements) {
1416 ABSL_DCHECK_GE(start, 0);
1417 ABSL_DCHECK_GE(num, 0);
1418 ABSL_DCHECK_LE(start + num, size());
1419
1420 if (num == 0) return;
1421
1422 ABSL_DCHECK_NE(elements, nullptr)
1423 << "Releasing elements without transferring ownership is an unsafe "
1424 "operation. Use UnsafeArenaExtractSubrange.";
1425 if (elements != nullptr) {
1426 Arena* arena = GetArena();
1427 auto* extracted = data() + start;
1428 #ifdef PROTOBUF_FORCE_COPY_IN_RELEASE
1429
1430 for (int i = 0; i < num; ++i) {
1431 elements[i] = copy<TypeHandler>(extracted[i]);
1432 }
1433 if (arena == nullptr) {
1434 for (int i = 0; i < num; ++i) {
1435 delete extracted[i];
1436 }
1437 }
1438 #else
1439
1440
1441 if (arena != nullptr) {
1442 for (int i = 0; i < num; ++i) {
1443 elements[i] = copy<TypeHandler>(extracted[i]);
1444 }
1445 } else {
1446 memcpy(elements, extracted, num * sizeof(Element*));
1447 }
1448 #endif
1449 }
1450 CloseGap(start, num);
1451 }
1452
1453 template <typename Element>
1454 inline void RepeatedPtrField<Element>::UnsafeArenaExtractSubrange(
1455 int start, int num, Element** elements) {
1456 ABSL_DCHECK_GE(start, 0);
1457 ABSL_DCHECK_GE(num, 0);
1458 ABSL_DCHECK_LE(start + num, size());
1459
1460 if (num > 0) {
1461
1462 if (elements != nullptr) {
1463 memcpy(elements, data() + start, num * sizeof(Element*));
1464 }
1465 CloseGap(start, num);
1466 }
1467 }
1468
1469 template <typename Element>
1470 inline void RepeatedPtrField<Element>::Clear() {
1471 RepeatedPtrFieldBase::Clear<TypeHandler>();
1472 }
1473
1474 template <typename Element>
1475 inline void RepeatedPtrField<Element>::MergeFrom(
1476 const RepeatedPtrField& other) {
1477 if (other.empty()) return;
1478 RepeatedPtrFieldBase::MergeFrom<Element>(other);
1479 }
1480
1481 template <typename Element>
1482 inline void RepeatedPtrField<Element>::CopyFrom(const RepeatedPtrField& other) {
1483 RepeatedPtrFieldBase::CopyFrom<TypeHandler>(other);
1484 }
1485
1486 template <typename Element>
1487 template <typename Iter>
1488 inline void RepeatedPtrField<Element>::Assign(Iter begin, Iter end) {
1489 Clear();
1490 Add(begin, end);
1491 }
1492
1493 template <typename Element>
1494 inline typename RepeatedPtrField<Element>::iterator
1495 RepeatedPtrField<Element>::erase(const_iterator position)
1496 ABSL_ATTRIBUTE_LIFETIME_BOUND {
1497 return erase(position, position + 1);
1498 }
1499
1500 template <typename Element>
1501 inline typename RepeatedPtrField<Element>::iterator
1502 RepeatedPtrField<Element>::erase(const_iterator first, const_iterator last)
1503 ABSL_ATTRIBUTE_LIFETIME_BOUND {
1504 size_type pos_offset = static_cast<size_type>(std::distance(cbegin(), first));
1505 size_type last_offset = static_cast<size_type>(std::distance(cbegin(), last));
1506 DeleteSubrange(pos_offset, last_offset - pos_offset);
1507 return begin() + pos_offset;
1508 }
1509
1510 template <typename Element>
1511 inline Element** RepeatedPtrField<Element>::mutable_data()
1512 ABSL_ATTRIBUTE_LIFETIME_BOUND {
1513 return RepeatedPtrFieldBase::mutable_data<TypeHandler>();
1514 }
1515
1516 template <typename Element>
1517 inline const Element* const* RepeatedPtrField<Element>::data() const
1518 ABSL_ATTRIBUTE_LIFETIME_BOUND {
1519 return RepeatedPtrFieldBase::data<TypeHandler>();
1520 }
1521
1522 template <typename Element>
1523 inline void RepeatedPtrField<Element>::Swap(RepeatedPtrField* other) {
1524 if (this == other) return;
1525 RepeatedPtrFieldBase::Swap<TypeHandler>(other);
1526 }
1527
1528 template <typename Element>
1529 inline void RepeatedPtrField<Element>::UnsafeArenaSwap(
1530 RepeatedPtrField* other) {
1531 if (this == other) return;
1532 ABSL_DCHECK_EQ(GetArena(), other->GetArena());
1533 RepeatedPtrFieldBase::InternalSwap(other);
1534 }
1535
1536 template <typename Element>
1537 inline void RepeatedPtrField<Element>::SwapElements(int index1, int index2) {
1538 RepeatedPtrFieldBase::SwapElements(index1, index2);
1539 }
1540
1541 template <typename Element>
1542 inline Arena* RepeatedPtrField<Element>::GetArena() {
1543 return RepeatedPtrFieldBase::GetArena();
1544 }
1545
1546 template <typename Element>
1547 inline size_t RepeatedPtrField<Element>::SpaceUsedExcludingSelfLong() const {
1548
1549
1550
1551 using H = typename std::conditional<std::is_base_of<Message, Element>::value,
1552 internal::GenericTypeHandler<Message>,
1553 TypeHandler>::type;
1554 return RepeatedPtrFieldBase::SpaceUsedExcludingSelfLong<H>();
1555 }
1556
1557 template <typename Element>
1558 inline void RepeatedPtrField<Element>::AddAllocated(Element* value) {
1559 RepeatedPtrFieldBase::AddAllocated<TypeHandler>(value);
1560 }
1561
1562 template <typename Element>
1563 inline void RepeatedPtrField<Element>::UnsafeArenaAddAllocated(Element* value) {
1564 RepeatedPtrFieldBase::UnsafeArenaAddAllocated<TypeHandler>(value);
1565 }
1566
1567 template <typename Element>
1568 inline Element* RepeatedPtrField<Element>::ReleaseLast() {
1569 return RepeatedPtrFieldBase::ReleaseLast<TypeHandler>();
1570 }
1571
1572 template <typename Element>
1573 inline Element* RepeatedPtrField<Element>::UnsafeArenaReleaseLast() {
1574 return RepeatedPtrFieldBase::UnsafeArenaReleaseLast<TypeHandler>();
1575 }
1576
1577 template <typename Element>
1578 inline int RepeatedPtrField<Element>::ClearedCount() const {
1579 return RepeatedPtrFieldBase::ClearedCount();
1580 }
1581
1582 template <typename Element>
1583 inline void RepeatedPtrField<Element>::Reserve(int new_size) {
1584 return RepeatedPtrFieldBase::Reserve(new_size);
1585 }
1586
1587 template <typename Element>
1588 inline int RepeatedPtrField<Element>::Capacity() const {
1589 return RepeatedPtrFieldBase::Capacity();
1590 }
1591
1592
1593
1594 namespace internal {
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607 template <typename Element>
1608 class RepeatedPtrIterator {
1609 public:
1610 using iterator = RepeatedPtrIterator<Element>;
1611 using iterator_category = std::random_access_iterator_tag;
1612 using value_type = typename std::remove_const<Element>::type;
1613 using difference_type = std::ptrdiff_t;
1614 using pointer = Element*;
1615 using reference = Element&;
1616
1617 RepeatedPtrIterator() : it_(nullptr) {}
1618 explicit RepeatedPtrIterator(void* const* it) : it_(it) {}
1619
1620
1621
1622 template <typename OtherElement,
1623 typename std::enable_if<std::is_convertible<
1624 OtherElement*, pointer>::value>::type* = nullptr>
1625 RepeatedPtrIterator(const RepeatedPtrIterator<OtherElement>& other)
1626 : it_(other.it_) {}
1627
1628
1629 reference operator*() const { return *reinterpret_cast<Element*>(*it_); }
1630 pointer operator->() const { return &(operator*()); }
1631
1632
1633 iterator& operator++() {
1634 ++it_;
1635 return *this;
1636 }
1637 iterator operator++(int) { return iterator(it_++); }
1638 iterator& operator--() {
1639 --it_;
1640 return *this;
1641 }
1642 iterator operator--(int) { return iterator(it_--); }
1643
1644
1645 friend bool operator==(const iterator& x, const iterator& y) {
1646 return x.it_ == y.it_;
1647 }
1648 friend bool operator!=(const iterator& x, const iterator& y) {
1649 return x.it_ != y.it_;
1650 }
1651
1652
1653 friend bool operator<(const iterator& x, const iterator& y) {
1654 return x.it_ < y.it_;
1655 }
1656 friend bool operator<=(const iterator& x, const iterator& y) {
1657 return x.it_ <= y.it_;
1658 }
1659 friend bool operator>(const iterator& x, const iterator& y) {
1660 return x.it_ > y.it_;
1661 }
1662 friend bool operator>=(const iterator& x, const iterator& y) {
1663 return x.it_ >= y.it_;
1664 }
1665
1666
1667 iterator& operator+=(difference_type d) {
1668 it_ += d;
1669 return *this;
1670 }
1671 friend iterator operator+(iterator it, const difference_type d) {
1672 it += d;
1673 return it;
1674 }
1675 friend iterator operator+(const difference_type d, iterator it) {
1676 it += d;
1677 return it;
1678 }
1679 iterator& operator-=(difference_type d) {
1680 it_ -= d;
1681 return *this;
1682 }
1683 friend iterator operator-(iterator it, difference_type d) {
1684 it -= d;
1685 return it;
1686 }
1687
1688
1689 reference operator[](difference_type d) const { return *(*this + d); }
1690
1691
1692 friend difference_type operator-(iterator it1, iterator it2) {
1693 return it1.it_ - it2.it_;
1694 }
1695
1696 private:
1697 template <typename OtherElement>
1698 friend class RepeatedPtrIterator;
1699
1700
1701 void* const* it_;
1702 };
1703
1704 template <typename Traits, typename = void>
1705 struct IteratorConceptSupport {
1706 using tag = typename Traits::iterator_category;
1707 };
1708
1709 template <typename Traits>
1710 struct IteratorConceptSupport<Traits,
1711 absl::void_t<typename Traits::iterator_concept>> {
1712 using tag = typename Traits::iterator_concept;
1713 };
1714
1715
1716
1717
1718
1719
1720
1721
1722 template <typename Element, typename VoidPtr>
1723 class RepeatedPtrOverPtrsIterator {
1724 private:
1725 using traits =
1726 std::iterator_traits<typename std::remove_const<Element>::type*>;
1727
1728 public:
1729 using value_type = typename traits::value_type;
1730 using difference_type = typename traits::difference_type;
1731 using pointer = Element*;
1732 using reference = Element&;
1733 using iterator_category = typename traits::iterator_category;
1734 using iterator_concept = typename IteratorConceptSupport<traits>::tag;
1735
1736 using iterator = RepeatedPtrOverPtrsIterator<Element, VoidPtr>;
1737
1738 RepeatedPtrOverPtrsIterator() : it_(nullptr) {}
1739 explicit RepeatedPtrOverPtrsIterator(VoidPtr* it) : it_(it) {}
1740
1741
1742
1743 template <
1744 typename OtherElement, typename OtherVoidPtr,
1745 typename std::enable_if<
1746 std::is_convertible<OtherElement*, pointer>::value &&
1747 std::is_convertible<OtherVoidPtr*, VoidPtr>::value>::type* = nullptr>
1748 RepeatedPtrOverPtrsIterator(
1749 const RepeatedPtrOverPtrsIterator<OtherElement, OtherVoidPtr>& other)
1750 : it_(other.it_) {}
1751
1752
1753 reference operator*() const { return *reinterpret_cast<Element*>(it_); }
1754 pointer operator->() const { return reinterpret_cast<Element*>(it_); }
1755
1756
1757 iterator& operator++() {
1758 ++it_;
1759 return *this;
1760 }
1761 iterator operator++(int) { return iterator(it_++); }
1762 iterator& operator--() {
1763 --it_;
1764 return *this;
1765 }
1766 iterator operator--(int) { return iterator(it_--); }
1767
1768
1769 friend bool operator==(const iterator& x, const iterator& y) {
1770 return x.it_ == y.it_;
1771 }
1772 friend bool operator!=(const iterator& x, const iterator& y) {
1773 return x.it_ != y.it_;
1774 }
1775
1776
1777 friend bool operator<(const iterator& x, const iterator& y) {
1778 return x.it_ < y.it_;
1779 }
1780 friend bool operator<=(const iterator& x, const iterator& y) {
1781 return x.it_ <= y.it_;
1782 }
1783 friend bool operator>(const iterator& x, const iterator& y) {
1784 return x.it_ > y.it_;
1785 }
1786 friend bool operator>=(const iterator& x, const iterator& y) {
1787 return x.it_ >= y.it_;
1788 }
1789
1790
1791 iterator& operator+=(difference_type d) {
1792 it_ += d;
1793 return *this;
1794 }
1795 friend iterator operator+(iterator it, difference_type d) {
1796 it += d;
1797 return it;
1798 }
1799 friend iterator operator+(difference_type d, iterator it) {
1800 it += d;
1801 return it;
1802 }
1803 iterator& operator-=(difference_type d) {
1804 it_ -= d;
1805 return *this;
1806 }
1807 friend iterator operator-(iterator it, difference_type d) {
1808 it -= d;
1809 return it;
1810 }
1811
1812
1813 reference operator[](difference_type d) const { return *(*this + d); }
1814
1815
1816 friend difference_type operator-(iterator it1, iterator it2) {
1817 return it1.it_ - it2.it_;
1818 }
1819
1820 private:
1821 template <typename OtherElement, typename OtherVoidPtr>
1822 friend class RepeatedPtrOverPtrsIterator;
1823
1824
1825 VoidPtr* it_;
1826 };
1827
1828 }
1829
1830 template <typename Element>
1831 inline typename RepeatedPtrField<Element>::iterator
1832 RepeatedPtrField<Element>::begin() ABSL_ATTRIBUTE_LIFETIME_BOUND {
1833 return iterator(raw_data());
1834 }
1835 template <typename Element>
1836 inline typename RepeatedPtrField<Element>::const_iterator
1837 RepeatedPtrField<Element>::begin() const ABSL_ATTRIBUTE_LIFETIME_BOUND {
1838 return iterator(raw_data());
1839 }
1840 template <typename Element>
1841 inline typename RepeatedPtrField<Element>::const_iterator
1842 RepeatedPtrField<Element>::cbegin() const ABSL_ATTRIBUTE_LIFETIME_BOUND {
1843 return begin();
1844 }
1845 template <typename Element>
1846 inline typename RepeatedPtrField<Element>::iterator
1847 RepeatedPtrField<Element>::end() ABSL_ATTRIBUTE_LIFETIME_BOUND {
1848 return iterator(raw_data() + size());
1849 }
1850 template <typename Element>
1851 inline typename RepeatedPtrField<Element>::const_iterator
1852 RepeatedPtrField<Element>::end() const ABSL_ATTRIBUTE_LIFETIME_BOUND {
1853 return iterator(raw_data() + size());
1854 }
1855 template <typename Element>
1856 inline typename RepeatedPtrField<Element>::const_iterator
1857 RepeatedPtrField<Element>::cend() const ABSL_ATTRIBUTE_LIFETIME_BOUND {
1858 return end();
1859 }
1860
1861 template <typename Element>
1862 inline typename RepeatedPtrField<Element>::pointer_iterator
1863 RepeatedPtrField<Element>::pointer_begin() ABSL_ATTRIBUTE_LIFETIME_BOUND {
1864 return pointer_iterator(raw_mutable_data());
1865 }
1866 template <typename Element>
1867 inline typename RepeatedPtrField<Element>::const_pointer_iterator
1868 RepeatedPtrField<Element>::pointer_begin() const ABSL_ATTRIBUTE_LIFETIME_BOUND {
1869 return const_pointer_iterator(const_cast<const void* const*>(raw_data()));
1870 }
1871 template <typename Element>
1872 inline typename RepeatedPtrField<Element>::pointer_iterator
1873 RepeatedPtrField<Element>::pointer_end() ABSL_ATTRIBUTE_LIFETIME_BOUND {
1874 return pointer_iterator(raw_mutable_data() + size());
1875 }
1876 template <typename Element>
1877 inline typename RepeatedPtrField<Element>::const_pointer_iterator
1878 RepeatedPtrField<Element>::pointer_end() const ABSL_ATTRIBUTE_LIFETIME_BOUND {
1879 return const_pointer_iterator(
1880 const_cast<const void* const*>(raw_data() + size()));
1881 }
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892 namespace internal {
1893
1894
1895 template <typename T>
1896 class RepeatedPtrFieldBackInsertIterator {
1897 public:
1898 using iterator_category = std::output_iterator_tag;
1899 using value_type = T;
1900 using pointer = void;
1901 using reference = void;
1902 using difference_type = std::ptrdiff_t;
1903
1904 RepeatedPtrFieldBackInsertIterator(RepeatedPtrField<T>* const mutable_field)
1905 : field_(mutable_field) {}
1906 RepeatedPtrFieldBackInsertIterator<T>& operator=(const T& value) {
1907 *field_->Add() = value;
1908 return *this;
1909 }
1910 RepeatedPtrFieldBackInsertIterator<T>& operator=(
1911 const T* const ptr_to_value) {
1912 *field_->Add() = *ptr_to_value;
1913 return *this;
1914 }
1915 RepeatedPtrFieldBackInsertIterator<T>& operator=(T&& value) {
1916 *field_->Add() = std::move(value);
1917 return *this;
1918 }
1919 RepeatedPtrFieldBackInsertIterator<T>& operator*() { return *this; }
1920 RepeatedPtrFieldBackInsertIterator<T>& operator++() { return *this; }
1921 RepeatedPtrFieldBackInsertIterator<T>& operator++(int ) {
1922 return *this;
1923 }
1924
1925 private:
1926 RepeatedPtrField<T>* field_;
1927 };
1928
1929
1930
1931 template <typename T>
1932 class AllocatedRepeatedPtrFieldBackInsertIterator {
1933 public:
1934 using iterator_category = std::output_iterator_tag;
1935 using value_type = T;
1936 using pointer = void;
1937 using reference = void;
1938 using difference_type = std::ptrdiff_t;
1939
1940 explicit AllocatedRepeatedPtrFieldBackInsertIterator(
1941 RepeatedPtrField<T>* const mutable_field)
1942 : field_(mutable_field) {}
1943 AllocatedRepeatedPtrFieldBackInsertIterator<T>& operator=(
1944 T* const ptr_to_value) {
1945 field_->AddAllocated(ptr_to_value);
1946 return *this;
1947 }
1948 AllocatedRepeatedPtrFieldBackInsertIterator<T>& operator*() { return *this; }
1949 AllocatedRepeatedPtrFieldBackInsertIterator<T>& operator++() { return *this; }
1950 AllocatedRepeatedPtrFieldBackInsertIterator<T>& operator++(int ) {
1951 return *this;
1952 }
1953
1954 private:
1955 RepeatedPtrField<T>* field_;
1956 };
1957
1958
1959
1960 template <typename T>
1961 class UnsafeArenaAllocatedRepeatedPtrFieldBackInsertIterator {
1962 public:
1963 using iterator_category = std::output_iterator_tag;
1964 using value_type = T;
1965 using pointer = void;
1966 using reference = void;
1967 using difference_type = std::ptrdiff_t;
1968
1969 explicit UnsafeArenaAllocatedRepeatedPtrFieldBackInsertIterator(
1970 RepeatedPtrField<T>* const mutable_field)
1971 : field_(mutable_field) {}
1972 UnsafeArenaAllocatedRepeatedPtrFieldBackInsertIterator<T>& operator=(
1973 T const* const ptr_to_value) {
1974 field_->UnsafeArenaAddAllocated(const_cast<T*>(ptr_to_value));
1975 return *this;
1976 }
1977 UnsafeArenaAllocatedRepeatedPtrFieldBackInsertIterator<T>& operator*() {
1978 return *this;
1979 }
1980 UnsafeArenaAllocatedRepeatedPtrFieldBackInsertIterator<T>& operator++() {
1981 return *this;
1982 }
1983 UnsafeArenaAllocatedRepeatedPtrFieldBackInsertIterator<T>& operator++(
1984 int ) {
1985 return *this;
1986 }
1987
1988 private:
1989 RepeatedPtrField<T>* field_;
1990 };
1991
1992 }
1993
1994
1995
1996 template <typename T>
1997 internal::RepeatedPtrFieldBackInsertIterator<T> RepeatedPtrFieldBackInserter(
1998 RepeatedPtrField<T>* const mutable_field) {
1999 return internal::RepeatedPtrFieldBackInsertIterator<T>(mutable_field);
2000 }
2001
2002
2003
2004
2005 template <typename T>
2006 internal::RepeatedPtrFieldBackInsertIterator<T> RepeatedFieldBackInserter(
2007 RepeatedPtrField<T>* const mutable_field) {
2008 return internal::RepeatedPtrFieldBackInsertIterator<T>(mutable_field);
2009 }
2010
2011
2012
2013
2014 template <typename T>
2015 internal::AllocatedRepeatedPtrFieldBackInsertIterator<T>
2016 AllocatedRepeatedPtrFieldBackInserter(
2017 RepeatedPtrField<T>* const mutable_field) {
2018 return internal::AllocatedRepeatedPtrFieldBackInsertIterator<T>(
2019 mutable_field);
2020 }
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033 template <typename T>
2034 internal::UnsafeArenaAllocatedRepeatedPtrFieldBackInsertIterator<T>
2035 UnsafeArenaAllocatedRepeatedPtrFieldBackInserter(
2036 RepeatedPtrField<T>* const mutable_field) {
2037 return internal::UnsafeArenaAllocatedRepeatedPtrFieldBackInsertIterator<T>(
2038 mutable_field);
2039 }
2040
2041
2042 namespace internal {
2043
2044
2045 extern template PROTOBUF_EXPORT_TEMPLATE_DECLARE void
2046 memswap<ArenaOffsetHelper<RepeatedPtrFieldBase>::value>(
2047 char* PROTOBUF_RESTRICT, char* PROTOBUF_RESTRICT);
2048 }
2049
2050 }
2051 }
2052
2053 #include "google/protobuf/port_undef.inc"
2054
2055 #endif