Coverage Report

Created: 2025-04-27 06:20

/src/LPM/external.protobuf/include/google/protobuf/repeated_field.h
Line
Count
Source (jump to first uncovered line)
1
// Protocol Buffers - Google's data interchange format
2
// Copyright 2008 Google Inc.  All rights reserved.
3
//
4
// Use of this source code is governed by a BSD-style
5
// license that can be found in the LICENSE file or at
6
// https://developers.google.com/open-source/licenses/bsd
7
8
// Author: kenton@google.com (Kenton Varda)
9
//  Based on original Protocol Buffers design by
10
//  Sanjay Ghemawat, Jeff Dean, and others.
11
//
12
// RepeatedField and RepeatedPtrField are used by generated protocol message
13
// classes to manipulate repeated fields.  These classes are very similar to
14
// STL's vector, but include a number of optimizations found to be useful
15
// specifically in the case of Protocol Buffers.  RepeatedPtrField is
16
// particularly different from STL vector as it manages ownership of the
17
// pointers that it contains.
18
//
19
// This header covers RepeatedField.
20
21
#ifndef GOOGLE_PROTOBUF_REPEATED_FIELD_H__
22
#define GOOGLE_PROTOBUF_REPEATED_FIELD_H__
23
24
#include <algorithm>
25
#include <cstddef>
26
#include <cstdint>
27
#include <cstring>
28
#include <iterator>
29
#include <limits>
30
#include <memory>
31
#include <type_traits>
32
#include <utility>
33
34
#include "absl/base/attributes.h"
35
#include "absl/base/dynamic_annotations.h"
36
#include "absl/base/optimization.h"
37
#include "absl/log/absl_check.h"
38
#include "absl/meta/type_traits.h"
39
#include "absl/strings/cord.h"
40
#include "google/protobuf/arena.h"
41
#include "google/protobuf/generated_enum_util.h"
42
#include "google/protobuf/internal_visibility.h"
43
#include "google/protobuf/message_lite.h"
44
#include "google/protobuf/port.h"
45
#include "google/protobuf/repeated_ptr_field.h"
46
47
// Must be included last.
48
#include "google/protobuf/port_def.inc"
49
50
#ifdef SWIG
51
#error "You cannot SWIG proto headers"
52
#endif
53
54
namespace google {
55
namespace protobuf {
56
57
class Message;
58
class UnknownField;  // For the allowlist
59
60
namespace internal {
61
62
template <typename T, int kHeapRepHeaderSize>
63
0
constexpr int RepeatedFieldLowerClampLimit() {
64
0
  // The header is padded to be at least `sizeof(T)` when it would be smaller
65
0
  // otherwise.
66
0
  static_assert(sizeof(T) <= kHeapRepHeaderSize, "");
67
0
  // We want to pad the minimum size to be a power of two bytes, including the
68
0
  // header.
69
0
  // The first allocation is kHeapRepHeaderSize bytes worth of elements for a
70
0
  // total of 2*kHeapRepHeaderSize bytes. For an 8-byte header, we allocate 8
71
0
  // bool, 2 ints, or 1 int64.
72
0
  return kHeapRepHeaderSize / sizeof(T);
73
0
}
Unexecuted instantiation: int google::protobuf::internal::RepeatedFieldLowerClampLimit<unsigned int, 8>()
Unexecuted instantiation: int google::protobuf::internal::RepeatedFieldLowerClampLimit<unsigned long, 8>()
Unexecuted instantiation: int google::protobuf::internal::RepeatedFieldLowerClampLimit<long, 8>()
Unexecuted instantiation: int google::protobuf::internal::RepeatedFieldLowerClampLimit<float, 8>()
Unexecuted instantiation: int google::protobuf::internal::RepeatedFieldLowerClampLimit<double, 8>()
Unexecuted instantiation: int google::protobuf::internal::RepeatedFieldLowerClampLimit<int, 8>()
Unexecuted instantiation: int google::protobuf::internal::RepeatedFieldLowerClampLimit<google::protobuf::UnknownField, 16>()
74
75
// kRepeatedFieldUpperClampLimit is the lowest signed integer value that
76
// overflows when multiplied by 2 (which is undefined behavior). Sizes above
77
// this will clamp to the maximum int value instead of following exponential
78
// growth when growing a repeated field.
79
#if defined(__cpp_inline_variables)
80
inline constexpr int kRepeatedFieldUpperClampLimit =
81
#else
82
constexpr int kRepeatedFieldUpperClampLimit =
83
#endif
84
    (std::numeric_limits<int>::max() / 2) + 1;
85
86
template <typename Element>
87
class RepeatedIterator;
88
89
// Sentinel base class.
90
struct RepeatedFieldBase {};
91
92
// We can't skip the destructor for, e.g., arena allocated RepeatedField<Cord>.
93
template <typename Element,
94
          bool Trivial = Arena::is_destructor_skippable<Element>::value>
95
struct RepeatedFieldDestructorSkippableBase : RepeatedFieldBase {};
96
97
template <typename Element>
98
struct RepeatedFieldDestructorSkippableBase<Element, true> : RepeatedFieldBase {
99
  using DestructorSkippable_ = void;
100
};
101
102
template <size_t kMinSize>
103
struct HeapRep {
104
  // Avoid 'implicitly deleted dtor' warnings on certain compilers.
105
  ~HeapRep() = delete;
106
107
0
  void* elements() { return this + 1; }
Unexecuted instantiation: google::protobuf::internal::HeapRep<8ul>::elements()
Unexecuted instantiation: google::protobuf::internal::HeapRep<16ul>::elements()
108
109
  // Align to 8 as sanitizers are picky on the alignment of containers to start
110
  // at 8 byte offsets even when compiling for 32 bit platforms.
111
  union {
112
    alignas(8) Arena* arena;
113
    // We pad the header to be at least `sizeof(Element)` so that we have
114
    // power-of-two sized allocations, which enables Arena optimizations.
115
    char padding[kMinSize];
116
  };
117
};
118
119
// We use small object optimization (SOO) to store elements inline when possible
120
// for small repeated fields. We do so in order to avoid memory indirections.
121
// Note that SOO is disabled on 32-bit platforms due to alignment limitations.
122
123
// SOO data is stored in the same space as the size/capacity ints.
124
enum { kSooCapacityBytes = 2 * sizeof(int) };
125
126
// Arena/elements pointers are aligned to at least kSooPtrAlignment bytes so we
127
// can use the lower bits to encode whether we're in SOO mode and if so, the
128
// SOO size. NOTE: we also tried using all kSooPtrMask bits to encode SOO size
129
// and use all ones as a sentinel value for non-SOO mode, but that was slower in
130
// benchmarks/loadtests.
131
enum { kSooPtrAlignment = 8 };
132
// The mask for the size bits in SOO mode, and also a sentinel value indicating
133
// that the field is not in SOO mode.
134
enum { kSooPtrMask = ~(kSooPtrAlignment - 1) };
135
// This bit is 0 when in SOO mode and 1 when in non-SOO mode.
136
enum { kNotSooBit = kSooPtrAlignment >> 1 };
137
// These bits are used to encode the size when in SOO mode (sizes are 0-3).
138
enum { kSooSizeMask = kNotSooBit - 1 };
139
140
// The number of elements that can be stored in the SOO rep. On 64-bit
141
// platforms, this is 1 for int64_t, 2 for int32_t, 3 for bool, and 0 for
142
// absl::Cord. We return 0 to disable SOO on 32-bit platforms.
143
0
constexpr int SooCapacityElements(size_t element_size) {
144
0
  if (sizeof(void*) < 8) return 0;
145
0
  return std::min<int>(kSooCapacityBytes / element_size, kSooSizeMask);
146
0
}
147
148
struct LongSooRep {
149
  // Returns char* rather than void* so callers can do pointer arithmetic.
150
0
  char* elements() const {
151
0
    auto ret = reinterpret_cast<char*>(elements_int & kSooPtrMask);
152
0
    ABSL_DCHECK_NE(ret, nullptr);
153
0
    return ret;
154
0
  }
155
156
  uintptr_t elements_int;
157
  int size;
158
  int capacity;
159
};
160
struct ShortSooRep {
161
  constexpr ShortSooRep() = default;
162
  explicit ShortSooRep(Arena* arena)
163
0
      : arena_and_size(reinterpret_cast<uintptr_t>(arena)) {
164
0
    ABSL_DCHECK_EQ(size(), 0);
165
0
  }
166
167
0
  int size() const { return arena_and_size & kSooSizeMask; }
168
0
  bool is_soo() const { return (arena_and_size & kNotSooBit) == 0; }
169
170
  uintptr_t arena_and_size = 0;
171
  union {
172
    char data[kSooCapacityBytes];
173
    // NOTE: in some language versions, we can't have a constexpr constructor
174
    // if we don't initialize all fields, but `data` doesn't need to be
175
    // initialized so initialize an empty dummy variable instead.
176
    std::true_type dummy = {};
177
  };
178
};
179
struct SooRep {
180
0
  constexpr SooRep() : short_rep() {}
181
0
  explicit SooRep(Arena* arena) : short_rep(arena) {}
182
183
0
  bool is_soo() const {
184
0
    static_assert(sizeof(LongSooRep) == sizeof(ShortSooRep), "");
185
0
    static_assert(offsetof(SooRep, long_rep) == offsetof(SooRep, short_rep),
186
0
                  "");
187
0
    static_assert(offsetof(LongSooRep, elements_int) ==
188
0
                      offsetof(ShortSooRep, arena_and_size),
189
0
                  "");
190
0
    return short_rep.is_soo();
191
0
  }
192
0
  Arena* soo_arena() const {
193
0
    ABSL_DCHECK(is_soo());
194
0
    return reinterpret_cast<Arena*>(short_rep.arena_and_size & kSooPtrMask);
195
0
  }
196
0
  int size(bool is_soo) const {
197
0
    ABSL_DCHECK_EQ(is_soo, this->is_soo());
198
0
#if !defined(__clang__) && defined(__GNUC__)
199
0
#pragma GCC diagnostic push
200
0
#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
201
0
#endif
202
0
    return is_soo ? short_rep.size() : long_rep.size;
203
0
#if !defined(__clang__) && defined(__GNUC__)
204
0
#pragma GCC diagnostic pop
205
0
#endif
206
0
  }
207
0
  void set_size(bool is_soo, int size) {
208
0
    ABSL_DCHECK_EQ(is_soo, this->is_soo());
209
0
    if (is_soo) {
210
0
      ABSL_DCHECK_LE(size, kSooSizeMask);
211
0
      short_rep.arena_and_size &= kSooPtrMask;
212
0
      short_rep.arena_and_size |= size;
213
0
    } else {
214
0
      long_rep.size = size;
215
0
    }
216
0
  }
217
  // Initializes the SooRep in non-SOO mode with the given capacity and heap
218
  // allocation.
219
0
  void set_non_soo(bool was_soo, int capacity, void* elements) {
220
0
    ABSL_DCHECK_EQ(was_soo, is_soo());
221
0
    ABSL_DCHECK_NE(elements, nullptr);
222
0
    ABSL_DCHECK_EQ(reinterpret_cast<uintptr_t>(elements) % kSooPtrAlignment,
223
0
                   uintptr_t{0});
224
0
    if (was_soo) long_rep.size = short_rep.size();
225
0
    long_rep.capacity = capacity;
226
0
    long_rep.elements_int = reinterpret_cast<uintptr_t>(elements) | kNotSooBit;
227
0
  }
228
229
  union {
230
    LongSooRep long_rep;
231
    ShortSooRep short_rep;
232
  };
233
};
234
235
}  // namespace internal
236
237
// RepeatedField is used to represent repeated fields of a primitive type (in
238
// other words, everything except strings and nested Messages).  Most users will
239
// not ever use a RepeatedField directly; they will use the get-by-index,
240
// set-by-index, and add accessors that are generated for all repeated fields.
241
// Actually, in addition to primitive types, we use RepeatedField for repeated
242
// Cords, because the Cord class is in fact just a reference-counted pointer.
243
// We have to specialize several methods in the Cord case to get the memory
244
// management right; e.g. swapping when appropriate, etc.
245
template <typename Element>
246
class RepeatedField final
247
    : private internal::RepeatedFieldDestructorSkippableBase<Element> {
248
  static_assert(
249
      alignof(Arena) >= alignof(Element),
250
      "We only support types that have an alignment smaller than Arena");
251
  static_assert(!std::is_const<Element>::value,
252
                "We do not support const value types.");
253
  static_assert(!std::is_volatile<Element>::value,
254
                "We do not support volatile value types.");
255
  static_assert(!std::is_pointer<Element>::value,
256
                "We do not support pointer value types.");
257
  static_assert(!std::is_reference<Element>::value,
258
                "We do not support reference value types.");
259
0
  static constexpr PROTOBUF_ALWAYS_INLINE void StaticValidityCheck() {
260
0
    static_assert(
261
0
        absl::disjunction<internal::is_supported_integral_type<Element>,
262
0
                          internal::is_supported_floating_point_type<Element>,
263
0
                          std::is_same<absl::Cord, Element>,
264
0
                          std::is_same<UnknownField, Element>,
265
0
                          is_proto_enum<Element>>::value,
266
0
        "We only support non-string scalars in RepeatedField.");
267
0
  }
268
269
 public:
270
  using value_type = Element;
271
  using size_type = int;
272
  using difference_type = ptrdiff_t;
273
  using reference = Element&;
274
  using const_reference = const Element&;
275
  using pointer = Element*;
276
  using const_pointer = const Element*;
277
  using iterator = internal::RepeatedIterator<Element>;
278
  using const_iterator = internal::RepeatedIterator<const Element>;
279
  using reverse_iterator = std::reverse_iterator<iterator>;
280
  using const_reverse_iterator = std::reverse_iterator<const_iterator>;
281
282
  constexpr RepeatedField();
283
  RepeatedField(const RepeatedField& rhs) : RepeatedField(nullptr, rhs) {}
284
285
  // TODO: make this constructor private
286
  explicit RepeatedField(Arena* arena);
287
288
  template <typename Iter,
289
            typename = typename std::enable_if<std::is_constructible<
290
                Element, decltype(*std::declval<Iter>())>::value>::type>
291
  RepeatedField(Iter begin, Iter end);
292
293
  // Arena enabled constructors: for internal use only.
294
  RepeatedField(internal::InternalVisibility, Arena* arena)
295
      : RepeatedField(arena) {}
296
  RepeatedField(internal::InternalVisibility, Arena* arena,
297
                const RepeatedField& rhs)
298
      : RepeatedField(arena, rhs) {}
299
300
  RepeatedField& operator=(const RepeatedField& other)
301
      ABSL_ATTRIBUTE_LIFETIME_BOUND;
302
303
  RepeatedField(RepeatedField&& rhs) noexcept
304
      : RepeatedField(nullptr, std::move(rhs)) {}
305
  RepeatedField& operator=(RepeatedField&& other) noexcept
306
      ABSL_ATTRIBUTE_LIFETIME_BOUND;
307
308
  ~RepeatedField();
309
310
  bool empty() const;
311
  int size() const;
312
313
  const_reference Get(int index) const ABSL_ATTRIBUTE_LIFETIME_BOUND;
314
  pointer Mutable(int index) ABSL_ATTRIBUTE_LIFETIME_BOUND;
315
316
0
  const_reference operator[](int index) const ABSL_ATTRIBUTE_LIFETIME_BOUND {
317
0
    return Get(index);
318
0
  }
319
0
  reference operator[](int index) ABSL_ATTRIBUTE_LIFETIME_BOUND {
320
0
    return *Mutable(index);
321
0
  }
322
323
  const_reference at(int index) const ABSL_ATTRIBUTE_LIFETIME_BOUND;
324
  reference at(int index) ABSL_ATTRIBUTE_LIFETIME_BOUND;
325
326
  void Set(int index, const Element& value);
327
  void Add(Element value);
328
329
  // Appends a new element and returns a pointer to it.
330
  // The new element is uninitialized if |Element| is a POD type.
331
  pointer Add() ABSL_ATTRIBUTE_LIFETIME_BOUND;
332
  // Appends elements in the range [begin, end) after reserving
333
  // the appropriate number of elements.
334
  template <typename Iter>
335
  void Add(Iter begin, Iter end);
336
337
  // Removes the last element in the array.
338
  void RemoveLast();
339
340
  // Extracts elements with indices in "[start .. start+num-1]".
341
  // Copies them into "elements[0 .. num-1]" if "elements" is not nullptr.
342
  // Caution: also moves elements with indices [start+num ..].
343
  // Calling this routine inside a loop can cause quadratic behavior.
344
  void ExtractSubrange(int start, int num, Element* elements);
345
346
  ABSL_ATTRIBUTE_REINITIALIZES void Clear();
347
348
  // Appends the elements from `other` after this instance.
349
  // The end result length will be `other.size() + this->size()`.
350
  void MergeFrom(const RepeatedField& other);
351
352
  // Replaces the contents with a copy of the elements from `other`.
353
  ABSL_ATTRIBUTE_REINITIALIZES void CopyFrom(const RepeatedField& other);
354
355
  // Replaces the contents with RepeatedField(begin, end).
356
  template <typename Iter>
357
  ABSL_ATTRIBUTE_REINITIALIZES void Assign(Iter begin, Iter end);
358
359
  // Reserves space to expand the field to at least the given size.  If the
360
  // array is grown, it will always be at least doubled in size.
361
  void Reserve(int new_size);
362
363
  // Resizes the RepeatedField to a new, smaller size.  This is O(1).
364
  // Except for RepeatedField<Cord>, for which it is O(size-new_size).
365
  void Truncate(int new_size);
366
367
  void AddAlreadyReserved(Element value);
368
  int Capacity() const;
369
370
  // Adds `n` elements to this instance asserting there is enough capacity.
371
  // The added elements are uninitialized if `Element` is trivial.
372
  pointer AddAlreadyReserved() ABSL_ATTRIBUTE_LIFETIME_BOUND;
373
  pointer AddNAlreadyReserved(int n) ABSL_ATTRIBUTE_LIFETIME_BOUND;
374
375
  // Like STL resize.  Uses value to fill appended elements.
376
  // Like Truncate() if new_size <= size(), otherwise this is
377
  // O(new_size - size()).
378
  void Resize(size_type new_size, const Element& value);
379
380
  // Gets the underlying array.  This pointer is possibly invalidated by
381
  // any add or remove operation.
382
  pointer mutable_data() ABSL_ATTRIBUTE_LIFETIME_BOUND;
383
  const_pointer data() const ABSL_ATTRIBUTE_LIFETIME_BOUND;
384
385
  // Swaps entire contents with "other". If they are separate arenas, then
386
  // copies data between each other.
387
  void Swap(RepeatedField* other);
388
389
  // Swaps two elements.
390
  void SwapElements(int index1, int index2);
391
392
  iterator begin() ABSL_ATTRIBUTE_LIFETIME_BOUND;
393
  const_iterator begin() const ABSL_ATTRIBUTE_LIFETIME_BOUND;
394
  const_iterator cbegin() const ABSL_ATTRIBUTE_LIFETIME_BOUND;
395
  iterator end() ABSL_ATTRIBUTE_LIFETIME_BOUND;
396
  const_iterator end() const ABSL_ATTRIBUTE_LIFETIME_BOUND;
397
  const_iterator cend() const ABSL_ATTRIBUTE_LIFETIME_BOUND;
398
399
  // Reverse iterator support
400
  reverse_iterator rbegin() ABSL_ATTRIBUTE_LIFETIME_BOUND {
401
    return reverse_iterator(end());
402
  }
403
  const_reverse_iterator rbegin() const ABSL_ATTRIBUTE_LIFETIME_BOUND {
404
    return const_reverse_iterator(end());
405
  }
406
  reverse_iterator rend() ABSL_ATTRIBUTE_LIFETIME_BOUND {
407
    return reverse_iterator(begin());
408
  }
409
  const_reverse_iterator rend() const ABSL_ATTRIBUTE_LIFETIME_BOUND {
410
    return const_reverse_iterator(begin());
411
  }
412
413
  // Returns the number of bytes used by the repeated field, excluding
414
  // sizeof(*this)
415
  size_t SpaceUsedExcludingSelfLong() const;
416
417
  int SpaceUsedExcludingSelf() const {
418
    return internal::ToIntSize(SpaceUsedExcludingSelfLong());
419
  }
420
421
  // Removes the element referenced by position.
422
  //
423
  // Returns an iterator to the element immediately following the removed
424
  // element.
425
  //
426
  // Invalidates all iterators at or after the removed element, including end().
427
  iterator erase(const_iterator position) ABSL_ATTRIBUTE_LIFETIME_BOUND;
428
429
  // Removes the elements in the range [first, last).
430
  //
431
  // Returns an iterator to the element immediately following the removed range.
432
  //
433
  // Invalidates all iterators at or after the removed range, including end().
434
  iterator erase(const_iterator first,
435
                 const_iterator last) ABSL_ATTRIBUTE_LIFETIME_BOUND;
436
437
  // Gets the Arena on which this RepeatedField stores its elements.
438
  // Note: this can be inaccurate for split default fields so we make this
439
  // function non-const.
440
0
  inline Arena* GetArena() { return GetArena(is_soo()); }
Unexecuted instantiation: google::protobuf::RepeatedField<unsigned int>::GetArena()
Unexecuted instantiation: google::protobuf::RepeatedField<unsigned long>::GetArena()
Unexecuted instantiation: google::protobuf::RepeatedField<long>::GetArena()
Unexecuted instantiation: google::protobuf::RepeatedField<float>::GetArena()
Unexecuted instantiation: google::protobuf::RepeatedField<double>::GetArena()
Unexecuted instantiation: google::protobuf::RepeatedField<int>::GetArena()
Unexecuted instantiation: google::protobuf::RepeatedField<google::protobuf::UnknownField>::GetArena()
441
442
  // For internal use only.
443
  //
444
  // This is public due to it being called by generated code.
445
  inline void InternalSwap(RepeatedField* other);
446
447
  static constexpr size_t InternalGetArenaOffset(internal::InternalVisibility) {
448
    return PROTOBUF_FIELD_OFFSET(RepeatedField, soo_rep_) +
449
           PROTOBUF_FIELD_OFFSET(internal::ShortSooRep, arena_and_size);
450
  }
451
452
 private:
453
  using InternalArenaConstructable_ = void;
454
  // We use std::max in order to share template instantiations between
455
  // different element types.
456
  using HeapRep = internal::HeapRep<std::max<size_t>(sizeof(Element), 8)>;
457
458
  template <typename T>
459
  friend class Arena::InternalHelper;
460
461
  friend class Arena;
462
463
  static constexpr int kSooCapacityElements =
464
      internal::SooCapacityElements(sizeof(Element));
465
466
  static constexpr int kInitialSize = 0;
467
  static PROTOBUF_CONSTEXPR const size_t kHeapRepHeaderSize = sizeof(HeapRep);
468
469
  RepeatedField(Arena* arena, const RepeatedField& rhs);
470
  RepeatedField(Arena* arena, RepeatedField&& rhs);
471
472
0
  inline Arena* GetArena(bool is_soo) const {
473
0
    return is_soo ? soo_rep_.soo_arena() : heap_rep()->arena;
474
0
  }
Unexecuted instantiation: google::protobuf::RepeatedField<unsigned int>::GetArena(bool) const
Unexecuted instantiation: google::protobuf::RepeatedField<unsigned long>::GetArena(bool) const
Unexecuted instantiation: google::protobuf::RepeatedField<long>::GetArena(bool) const
Unexecuted instantiation: google::protobuf::RepeatedField<float>::GetArena(bool) const
Unexecuted instantiation: google::protobuf::RepeatedField<double>::GetArena(bool) const
Unexecuted instantiation: google::protobuf::RepeatedField<int>::GetArena(bool) const
Unexecuted instantiation: google::protobuf::RepeatedField<google::protobuf::UnknownField>::GetArena(bool) const
475
476
0
  bool is_soo() const { return soo_rep_.is_soo(); }
Unexecuted instantiation: google::protobuf::RepeatedField<unsigned int>::is_soo() const
Unexecuted instantiation: google::protobuf::RepeatedField<unsigned long>::is_soo() const
Unexecuted instantiation: google::protobuf::RepeatedField<int>::is_soo() const
Unexecuted instantiation: google::protobuf::RepeatedField<long>::is_soo() const
Unexecuted instantiation: google::protobuf::RepeatedField<float>::is_soo() const
Unexecuted instantiation: google::protobuf::RepeatedField<double>::is_soo() const
Unexecuted instantiation: google::protobuf::RepeatedField<bool>::is_soo() const
Unexecuted instantiation: google::protobuf::RepeatedField<google::protobuf::UnknownField>::is_soo() const
477
0
  int size(bool is_soo) const { return soo_rep_.size(is_soo); }
Unexecuted instantiation: google::protobuf::RepeatedField<unsigned int>::size(bool) const
Unexecuted instantiation: google::protobuf::RepeatedField<unsigned long>::size(bool) const
Unexecuted instantiation: google::protobuf::RepeatedField<int>::size(bool) const
Unexecuted instantiation: google::protobuf::RepeatedField<long>::size(bool) const
Unexecuted instantiation: google::protobuf::RepeatedField<float>::size(bool) const
Unexecuted instantiation: google::protobuf::RepeatedField<double>::size(bool) const
Unexecuted instantiation: google::protobuf::RepeatedField<bool>::size(bool) const
Unexecuted instantiation: google::protobuf::RepeatedField<google::protobuf::UnknownField>::size(bool) const
478
0
  int Capacity(bool is_soo) const {
479
0
#if !defined(__clang__) && defined(__GNUC__)
480
0
#pragma GCC diagnostic push
481
0
#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
482
0
#endif
483
0
    return is_soo ? kSooCapacityElements : soo_rep_.long_rep.capacity;
484
0
#if !defined(__clang__) && defined(__GNUC__)
485
0
#pragma GCC diagnostic pop
486
0
#endif
487
0
  }
Unexecuted instantiation: google::protobuf::RepeatedField<unsigned int>::Capacity(bool) const
Unexecuted instantiation: google::protobuf::RepeatedField<unsigned long>::Capacity(bool) const
Unexecuted instantiation: google::protobuf::RepeatedField<int>::Capacity(bool) const
Unexecuted instantiation: google::protobuf::RepeatedField<long>::Capacity(bool) const
Unexecuted instantiation: google::protobuf::RepeatedField<float>::Capacity(bool) const
Unexecuted instantiation: google::protobuf::RepeatedField<double>::Capacity(bool) const
Unexecuted instantiation: google::protobuf::RepeatedField<google::protobuf::UnknownField>::Capacity(bool) const
488
0
  void set_size(bool is_soo, int size) {
489
0
    ABSL_DCHECK_LE(size, Capacity(is_soo));
490
0
    soo_rep_.set_size(is_soo, size);
491
0
  }
Unexecuted instantiation: google::protobuf::RepeatedField<unsigned int>::set_size(bool, int)
Unexecuted instantiation: google::protobuf::RepeatedField<unsigned long>::set_size(bool, int)
Unexecuted instantiation: google::protobuf::RepeatedField<int>::set_size(bool, int)
Unexecuted instantiation: google::protobuf::RepeatedField<long>::set_size(bool, int)
Unexecuted instantiation: google::protobuf::RepeatedField<float>::set_size(bool, int)
Unexecuted instantiation: google::protobuf::RepeatedField<double>::set_size(bool, int)
Unexecuted instantiation: google::protobuf::RepeatedField<google::protobuf::UnknownField>::set_size(bool, int)
492
493
  // Swaps entire contents with "other". Should be called only if the caller can
494
  // guarantee that both repeated fields are on the same arena or are on the
495
  // heap. Swapping between different arenas is disallowed and caught by a
496
  // ABSL_DCHECK (see API docs for details).
497
  void UnsafeArenaSwap(RepeatedField* other);
498
499
  // Copy constructs `n` instances in place into the array `dst`.
500
  // This function is identical to `std::uninitialized_copy_n(src, n, dst)`
501
  // except that we explicit declare the memory to not be aliased, which will
502
  // result in `memcpy` code generation instead of `memmove` for trivial types.
503
  static inline void UninitializedCopyN(const Element* PROTOBUF_RESTRICT src,
504
0
                                        int n, Element* PROTOBUF_RESTRICT dst) {
505
0
    std::uninitialized_copy_n(src, n, dst);
506
0
  }
507
508
  // Copy constructs `[begin, end)` instances in place into the array `dst`.
509
  // See above `UninitializedCopyN()` function comments for more information.
510
  template <typename Iter>
511
  static inline void UninitializedCopy(Iter begin, Iter end,
512
                                       Element* PROTOBUF_RESTRICT dst) {
513
    std::uninitialized_copy(begin, end, dst);
514
  }
515
516
  // Destroys all elements in [begin, end).
517
  // This function does nothing if `Element` is trivial.
518
0
  static void Destroy(const Element* begin, const Element* end) {
519
0
    if (!std::is_trivial<Element>::value) {
520
0
      std::for_each(begin, end, [&](const Element& e) { e.~Element(); });
521
0
    }
522
0
  }
Unexecuted instantiation: google::protobuf::RepeatedField<unsigned int>::Destroy(unsigned int const*, unsigned int const*)
Unexecuted instantiation: google::protobuf::RepeatedField<unsigned long>::Destroy(unsigned long const*, unsigned long const*)
Unexecuted instantiation: google::protobuf::RepeatedField<int>::Destroy(int const*, int const*)
Unexecuted instantiation: google::protobuf::RepeatedField<long>::Destroy(long const*, long const*)
Unexecuted instantiation: google::protobuf::RepeatedField<float>::Destroy(float const*, float const*)
Unexecuted instantiation: google::protobuf::RepeatedField<double>::Destroy(double const*, double const*)
Unexecuted instantiation: google::protobuf::RepeatedField<google::protobuf::UnknownField>::Destroy(google::protobuf::UnknownField const*, google::protobuf::UnknownField const*)
523
524
  template <typename Iter>
525
  void AddForwardIterator(Iter begin, Iter end);
526
527
  template <typename Iter>
528
  void AddInputIterator(Iter begin, Iter end);
529
530
  // Reserves space to expand the field to at least the given size.
531
  // If the array is grown, it will always be at least doubled in size.
532
  // If `annotate_size` is true (the default), then this function will annotate
533
  // the old container from `old_size` to `Capacity()` (unpoison memory)
534
  // directly before it is being released, and annotate the new container from
535
  // `Capacity()` to `old_size` (poison unused memory).
536
  void Grow(bool was_soo, int old_size, int new_size);
537
  void GrowNoAnnotate(bool was_soo, int old_size, int new_size);
538
539
  // Annotates a change in size of this instance. This function should be called
540
  // with (capacity, old_size) after new memory has been allocated and filled
541
  // from previous memory, and UnpoisonBuffer() should be called right before
542
  // (previously annotated) memory is released.
543
0
  void AnnotateSize(int old_size, int new_size) const {
544
0
    if (old_size != new_size) {
545
0
      ABSL_ATTRIBUTE_UNUSED const bool is_soo = this->is_soo();
546
0
      ABSL_ATTRIBUTE_UNUSED const Element* elem = unsafe_elements(is_soo);
547
0
      ABSL_ANNOTATE_CONTIGUOUS_CONTAINER(elem, elem + Capacity(is_soo),
548
0
                                         elem + old_size, elem + new_size);
549
0
      if (new_size < old_size) {
550
0
        ABSL_ANNOTATE_MEMORY_IS_UNINITIALIZED(
551
0
            elem + new_size, (old_size - new_size) * sizeof(Element));
552
0
      }
553
0
    }
554
0
  }
Unexecuted instantiation: google::protobuf::RepeatedField<unsigned int>::AnnotateSize(int, int) const
Unexecuted instantiation: google::protobuf::RepeatedField<unsigned long>::AnnotateSize(int, int) const
Unexecuted instantiation: google::protobuf::RepeatedField<int>::AnnotateSize(int, int) const
Unexecuted instantiation: google::protobuf::RepeatedField<long>::AnnotateSize(int, int) const
Unexecuted instantiation: google::protobuf::RepeatedField<float>::AnnotateSize(int, int) const
Unexecuted instantiation: google::protobuf::RepeatedField<double>::AnnotateSize(int, int) const
Unexecuted instantiation: google::protobuf::RepeatedField<google::protobuf::UnknownField>::AnnotateSize(int, int) const
555
556
  // Unpoisons the memory buffer.
557
0
  void UnpoisonBuffer() const {
558
0
    AnnotateSize(size(), Capacity());
559
0
    if (is_soo()) {
560
0
      // We need to manually unpoison the SOO buffer because in reflection for
561
0
      // split repeated fields, we poison the whole SOO buffer even when we
562
0
      // don't actually use the whole SOO buffer (e.g. for RepeatedField<bool>).
563
0
      PROTOBUF_UNPOISON_MEMORY_REGION(soo_rep_.short_rep.data,
564
0
                                      sizeof(soo_rep_.short_rep.data));
565
0
    }
566
0
  }
Unexecuted instantiation: google::protobuf::RepeatedField<unsigned int>::UnpoisonBuffer() const
Unexecuted instantiation: google::protobuf::RepeatedField<unsigned long>::UnpoisonBuffer() const
Unexecuted instantiation: google::protobuf::RepeatedField<long>::UnpoisonBuffer() const
Unexecuted instantiation: google::protobuf::RepeatedField<float>::UnpoisonBuffer() const
Unexecuted instantiation: google::protobuf::RepeatedField<double>::UnpoisonBuffer() const
Unexecuted instantiation: google::protobuf::RepeatedField<int>::UnpoisonBuffer() const
Unexecuted instantiation: google::protobuf::RepeatedField<google::protobuf::UnknownField>::UnpoisonBuffer() const
567
568
  // Replaces size with new_size and returns the previous value of
569
  // size. This function is intended to be the only place where
570
  // size is modified, with the exception of `AddInputIterator()`
571
  // where the size of added items is not known in advance.
572
0
  inline int ExchangeCurrentSize(bool is_soo, int new_size) {
573
0
    const int prev_size = size(is_soo);
574
0
    AnnotateSize(prev_size, new_size);
575
0
    set_size(is_soo, new_size);
576
0
    return prev_size;
577
0
  }
Unexecuted instantiation: google::protobuf::RepeatedField<unsigned int>::ExchangeCurrentSize(bool, int)
Unexecuted instantiation: google::protobuf::RepeatedField<unsigned long>::ExchangeCurrentSize(bool, int)
Unexecuted instantiation: google::protobuf::RepeatedField<int>::ExchangeCurrentSize(bool, int)
Unexecuted instantiation: google::protobuf::RepeatedField<long>::ExchangeCurrentSize(bool, int)
Unexecuted instantiation: google::protobuf::RepeatedField<float>::ExchangeCurrentSize(bool, int)
Unexecuted instantiation: google::protobuf::RepeatedField<double>::ExchangeCurrentSize(bool, int)
Unexecuted instantiation: google::protobuf::RepeatedField<google::protobuf::UnknownField>::ExchangeCurrentSize(bool, int)
578
579
  // Returns a pointer to elements array.
580
  // pre-condition: Capacity() > 0.
581
0
  Element* elements(bool is_soo) {
582
0
    ABSL_DCHECK_GT(Capacity(is_soo), 0);
583
0
    return unsafe_elements(is_soo);
584
0
  }
Unexecuted instantiation: google::protobuf::RepeatedField<unsigned int>::elements(bool)
Unexecuted instantiation: google::protobuf::RepeatedField<unsigned long>::elements(bool)
Unexecuted instantiation: google::protobuf::RepeatedField<int>::elements(bool)
Unexecuted instantiation: google::protobuf::RepeatedField<long>::elements(bool)
Unexecuted instantiation: google::protobuf::RepeatedField<float>::elements(bool)
Unexecuted instantiation: google::protobuf::RepeatedField<double>::elements(bool)
Unexecuted instantiation: google::protobuf::RepeatedField<google::protobuf::UnknownField>::elements(bool)
585
0
  const Element* elements(bool is_soo) const {
586
0
    return const_cast<RepeatedField*>(this)->elements(is_soo);
587
0
  }
Unexecuted instantiation: google::protobuf::RepeatedField<google::protobuf::UnknownField>::elements(bool) const
Unexecuted instantiation: google::protobuf::RepeatedField<int>::elements(bool) const
588
589
  // Returns a pointer to elements array if it exists; otherwise an invalid
590
  // pointer is returned. This only happens for empty repeated fields, where you
591
  // can't dereference this pointer anyway (it's empty).
592
0
  Element* unsafe_elements(bool is_soo) {
593
0
    return is_soo ? reinterpret_cast<Element*>(soo_rep_.short_rep.data)
594
0
                  : reinterpret_cast<Element*>(soo_rep_.long_rep.elements());
595
0
  }
Unexecuted instantiation: google::protobuf::RepeatedField<unsigned int>::unsafe_elements(bool)
Unexecuted instantiation: google::protobuf::RepeatedField<unsigned long>::unsafe_elements(bool)
Unexecuted instantiation: google::protobuf::RepeatedField<int>::unsafe_elements(bool)
Unexecuted instantiation: google::protobuf::RepeatedField<long>::unsafe_elements(bool)
Unexecuted instantiation: google::protobuf::RepeatedField<float>::unsafe_elements(bool)
Unexecuted instantiation: google::protobuf::RepeatedField<double>::unsafe_elements(bool)
Unexecuted instantiation: google::protobuf::RepeatedField<bool>::unsafe_elements(bool)
Unexecuted instantiation: google::protobuf::RepeatedField<google::protobuf::UnknownField>::unsafe_elements(bool)
596
0
  const Element* unsafe_elements(bool is_soo) const {
597
0
    return const_cast<RepeatedField*>(this)->unsafe_elements(is_soo);
598
0
  }
Unexecuted instantiation: google::protobuf::RepeatedField<unsigned int>::unsafe_elements(bool) const
Unexecuted instantiation: google::protobuf::RepeatedField<unsigned long>::unsafe_elements(bool) const
Unexecuted instantiation: google::protobuf::RepeatedField<int>::unsafe_elements(bool) const
Unexecuted instantiation: google::protobuf::RepeatedField<long>::unsafe_elements(bool) const
Unexecuted instantiation: google::protobuf::RepeatedField<float>::unsafe_elements(bool) const
Unexecuted instantiation: google::protobuf::RepeatedField<double>::unsafe_elements(bool) const
Unexecuted instantiation: google::protobuf::RepeatedField<bool>::unsafe_elements(bool) const
Unexecuted instantiation: google::protobuf::RepeatedField<google::protobuf::UnknownField>::unsafe_elements(bool) const
599
600
  // Returns a pointer to the HeapRep struct.
601
  // pre-condition: the HeapRep must have been allocated, ie !is_soo().
602
0
  HeapRep* heap_rep() const {
603
0
    ABSL_DCHECK(!is_soo());
604
0
    return reinterpret_cast<HeapRep*>(soo_rep_.long_rep.elements() -
605
0
                                      kHeapRepHeaderSize);
606
0
  }
Unexecuted instantiation: google::protobuf::RepeatedField<unsigned int>::heap_rep() const
Unexecuted instantiation: google::protobuf::RepeatedField<unsigned long>::heap_rep() const
Unexecuted instantiation: google::protobuf::RepeatedField<long>::heap_rep() const
Unexecuted instantiation: google::protobuf::RepeatedField<float>::heap_rep() const
Unexecuted instantiation: google::protobuf::RepeatedField<double>::heap_rep() const
Unexecuted instantiation: google::protobuf::RepeatedField<int>::heap_rep() const
Unexecuted instantiation: google::protobuf::RepeatedField<google::protobuf::UnknownField>::heap_rep() const
607
608
  // Internal helper to delete all elements and deallocate the storage.
609
  template <bool in_destructor = false>
610
0
  void InternalDeallocate() {
611
0
    ABSL_DCHECK(!is_soo());
612
0
    const size_t bytes = Capacity(false) * sizeof(Element) + kHeapRepHeaderSize;
613
0
    if (heap_rep()->arena == nullptr) {
614
0
      internal::SizedDelete(heap_rep(), bytes);
615
0
    } else if (!in_destructor) {
616
0
      // If we are in the destructor, we might be being destroyed as part of
617
0
      // the arena teardown. We can't try and return blocks to the arena then.
618
0
      heap_rep()->arena->ReturnArrayMemory(heap_rep(), bytes);
619
0
    }
620
0
  }
Unexecuted instantiation: void google::protobuf::RepeatedField<unsigned int>::InternalDeallocate<false>()
Unexecuted instantiation: void google::protobuf::RepeatedField<unsigned long>::InternalDeallocate<false>()
Unexecuted instantiation: void google::protobuf::RepeatedField<long>::InternalDeallocate<false>()
Unexecuted instantiation: void google::protobuf::RepeatedField<float>::InternalDeallocate<false>()
Unexecuted instantiation: void google::protobuf::RepeatedField<double>::InternalDeallocate<false>()
Unexecuted instantiation: void google::protobuf::RepeatedField<int>::InternalDeallocate<false>()
Unexecuted instantiation: void google::protobuf::RepeatedField<google::protobuf::UnknownField>::InternalDeallocate<true>()
Unexecuted instantiation: void google::protobuf::RepeatedField<google::protobuf::UnknownField>::InternalDeallocate<false>()
621
622
  // A note on the representation here (see also comment below for
623
  // RepeatedPtrFieldBase's struct HeapRep):
624
  //
625
  // We maintain the same sizeof(RepeatedField) as before we added arena support
626
  // so that we do not degrade performance by bloating memory usage. Directly
627
  // adding an arena_ element to RepeatedField is quite costly. By using
628
  // indirection in this way, we keep the same size when the RepeatedField is
629
  // empty (common case), and add only an 8-byte header to the elements array
630
  // when non-empty. We make sure to place the size fields directly in the
631
  // RepeatedField class to avoid costly cache misses due to the indirection.
632
  internal::SooRep soo_rep_{};
633
};
634
635
// implementation ====================================================
636
637
template <typename Element>
638
constexpr RepeatedField<Element>::RepeatedField() {
639
  StaticValidityCheck();
640
#ifdef __cpp_lib_is_constant_evaluated
641
  if (!std::is_constant_evaluated()) {
642
    AnnotateSize(kSooCapacityElements, 0);
643
  }
644
#endif  // __cpp_lib_is_constant_evaluated
645
}
646
647
template <typename Element>
648
inline RepeatedField<Element>::RepeatedField(Arena* arena) : soo_rep_(arena) {
649
  StaticValidityCheck();
650
  AnnotateSize(kSooCapacityElements, 0);
651
}
652
653
template <typename Element>
654
inline RepeatedField<Element>::RepeatedField(Arena* arena,
655
                                             const RepeatedField& rhs)
656
    : soo_rep_(arena) {
657
  StaticValidityCheck();
658
  AnnotateSize(kSooCapacityElements, 0);
659
  const bool rhs_is_soo = rhs.is_soo();
660
  if (auto size = rhs.size(rhs_is_soo)) {
661
    bool is_soo = true;
662
    if (size > kSooCapacityElements) {
663
      Grow(is_soo, 0, size);
664
      is_soo = false;
665
    }
666
    ExchangeCurrentSize(is_soo, size);
667
    UninitializedCopyN(rhs.elements(rhs_is_soo), size, unsafe_elements(is_soo));
668
  }
669
}
670
671
template <typename Element>
672
template <typename Iter, typename>
673
RepeatedField<Element>::RepeatedField(Iter begin, Iter end) {
674
  StaticValidityCheck();
675
  AnnotateSize(kSooCapacityElements, 0);
676
  Add(begin, end);
677
}
678
679
template <typename Element>
680
RepeatedField<Element>::~RepeatedField() {
681
  StaticValidityCheck();
682
  const bool is_soo = this->is_soo();
683
#ifndef NDEBUG
684
  // Try to trigger segfault / asan failure in non-opt builds if arena_
685
  // lifetime has ended before the destructor.
686
  auto arena = GetArena(is_soo);
687
  if (arena) (void)arena->SpaceAllocated();
688
#endif
689
  const int size = this->size(is_soo);
690
  if (size > 0) {
691
    Element* elem = unsafe_elements(is_soo);
692
    Destroy(elem, elem + size);
693
  }
694
  UnpoisonBuffer();
695
  if (!is_soo) InternalDeallocate<true>();
696
}
697
698
template <typename Element>
699
inline RepeatedField<Element>& RepeatedField<Element>::operator=(
700
    const RepeatedField& other) ABSL_ATTRIBUTE_LIFETIME_BOUND {
701
  if (this != &other) CopyFrom(other);
702
  return *this;
703
}
704
705
template <typename Element>
706
inline RepeatedField<Element>::RepeatedField(Arena* arena, RepeatedField&& rhs)
707
    : RepeatedField(arena) {
708
  if (internal::CanMoveWithInternalSwap(arena, rhs.GetArena())) {
709
    InternalSwap(&rhs);
710
  } else {
711
    // We don't just call Swap(&rhs) here because it would perform 3 copies if
712
    // rhs is on a different arena.
713
    CopyFrom(rhs);
714
  }
715
}
716
717
template <typename Element>
718
inline RepeatedField<Element>& RepeatedField<Element>::operator=(
719
    RepeatedField&& other) noexcept ABSL_ATTRIBUTE_LIFETIME_BOUND {
720
  // We don't just call Swap(&other) here because it would perform 3 copies if
721
  // the two fields are on different arenas.
722
  if (this != &other) {
723
    if (internal::CanMoveWithInternalSwap(GetArena(), other.GetArena())) {
724
      InternalSwap(&other);
725
    } else {
726
      CopyFrom(other);
727
    }
728
  }
729
  return *this;
730
}
731
732
template <typename Element>
733
0
inline bool RepeatedField<Element>::empty() const {
734
0
  return size() == 0;
735
0
}
736
737
template <typename Element>
738
0
inline int RepeatedField<Element>::size() const {
739
0
  return size(is_soo());
740
0
}
Unexecuted instantiation: google::protobuf::RepeatedField<unsigned int>::size() const
Unexecuted instantiation: google::protobuf::RepeatedField<unsigned long>::size() const
Unexecuted instantiation: google::protobuf::RepeatedField<long>::size() const
Unexecuted instantiation: google::protobuf::RepeatedField<float>::size() const
Unexecuted instantiation: google::protobuf::RepeatedField<double>::size() const
Unexecuted instantiation: google::protobuf::RepeatedField<bool>::size() const
Unexecuted instantiation: google::protobuf::RepeatedField<google::protobuf::UnknownField>::size() const
Unexecuted instantiation: google::protobuf::RepeatedField<int>::size() const
741
742
template <typename Element>
743
0
inline int RepeatedField<Element>::Capacity() const {
744
0
  return Capacity(is_soo());
745
0
}
Unexecuted instantiation: google::protobuf::RepeatedField<unsigned int>::Capacity() const
Unexecuted instantiation: google::protobuf::RepeatedField<unsigned long>::Capacity() const
Unexecuted instantiation: google::protobuf::RepeatedField<int>::Capacity() const
Unexecuted instantiation: google::protobuf::RepeatedField<long>::Capacity() const
Unexecuted instantiation: google::protobuf::RepeatedField<float>::Capacity() const
Unexecuted instantiation: google::protobuf::RepeatedField<double>::Capacity() const
Unexecuted instantiation: google::protobuf::RepeatedField<google::protobuf::UnknownField>::Capacity() const
746
747
template <typename Element>
748
0
inline void RepeatedField<Element>::AddAlreadyReserved(Element value) {
749
0
  const bool is_soo = this->is_soo();
750
0
  const int old_size = size(is_soo);
751
0
  ABSL_DCHECK_LT(old_size, Capacity(is_soo));
752
0
  void* p = elements(is_soo) + ExchangeCurrentSize(is_soo, old_size + 1);
753
0
  ::new (p) Element(std::move(value));
754
0
}
Unexecuted instantiation: google::protobuf::RepeatedField<unsigned int>::AddAlreadyReserved(unsigned int)
Unexecuted instantiation: google::protobuf::RepeatedField<unsigned long>::AddAlreadyReserved(unsigned long)
Unexecuted instantiation: google::protobuf::RepeatedField<int>::AddAlreadyReserved(int)
Unexecuted instantiation: google::protobuf::RepeatedField<long>::AddAlreadyReserved(long)
Unexecuted instantiation: google::protobuf::RepeatedField<float>::AddAlreadyReserved(float)
Unexecuted instantiation: google::protobuf::RepeatedField<double>::AddAlreadyReserved(double)
755
756
template <typename Element>
757
inline Element* RepeatedField<Element>::AddAlreadyReserved()
758
    ABSL_ATTRIBUTE_LIFETIME_BOUND {
759
  const bool is_soo = this->is_soo();
760
  const int old_size = size(is_soo);
761
  ABSL_DCHECK_LT(old_size, Capacity(is_soo));
762
  // new (p) <TrivialType> compiles into nothing: this is intentional as this
763
  // function is documented to return uninitialized data for trivial types.
764
  void* p = elements(is_soo) + ExchangeCurrentSize(is_soo, old_size + 1);
765
  return ::new (p) Element;
766
}
767
768
template <typename Element>
769
inline Element* RepeatedField<Element>::AddNAlreadyReserved(int n)
770
    ABSL_ATTRIBUTE_LIFETIME_BOUND {
771
  const bool is_soo = this->is_soo();
772
  const int old_size = size(is_soo);
773
  ABSL_ATTRIBUTE_UNUSED const int capacity = Capacity(is_soo);
774
  ABSL_DCHECK_GE(capacity - old_size, n) << capacity << ", " << old_size;
775
  Element* p =
776
      unsafe_elements(is_soo) + ExchangeCurrentSize(is_soo, old_size + n);
777
  for (Element *begin = p, *end = p + n; begin != end; ++begin) {
778
    new (static_cast<void*>(begin)) Element;
779
  }
780
  return p;
781
}
782
783
template <typename Element>
784
0
inline void RepeatedField<Element>::Resize(int new_size, const Element& value) {
785
0
  ABSL_DCHECK_GE(new_size, 0);
786
0
  bool is_soo = this->is_soo();
787
0
  const int old_size = size(is_soo);
788
0
  if (new_size > old_size) {
789
0
    if (new_size > Capacity(is_soo)) {
790
0
      Grow(is_soo, old_size, new_size);
791
0
      is_soo = false;
792
0
    }
793
0
    Element* elem = elements(is_soo);
794
0
    Element* first = elem + ExchangeCurrentSize(is_soo, new_size);
795
0
    std::uninitialized_fill(first, elem + new_size, value);
796
0
  } else if (new_size < old_size) {
797
0
    Element* elem = unsafe_elements(is_soo);
798
0
    Destroy(elem + new_size, elem + old_size);
799
0
    ExchangeCurrentSize(is_soo, new_size);
800
0
  }
801
0
}
Unexecuted instantiation: google::protobuf::RepeatedField<unsigned int>::Resize(int, unsigned int const&)
Unexecuted instantiation: google::protobuf::RepeatedField<unsigned long>::Resize(int, unsigned long const&)
Unexecuted instantiation: google::protobuf::RepeatedField<int>::Resize(int, int const&)
Unexecuted instantiation: google::protobuf::RepeatedField<long>::Resize(int, long const&)
Unexecuted instantiation: google::protobuf::RepeatedField<float>::Resize(int, float const&)
Unexecuted instantiation: google::protobuf::RepeatedField<double>::Resize(int, double const&)
802
803
template <typename Element>
804
inline const Element& RepeatedField<Element>::Get(int index) const
805
0
    ABSL_ATTRIBUTE_LIFETIME_BOUND {
806
0
  ABSL_DCHECK_GE(index, 0);
807
0
  ABSL_DCHECK_LT(index, size());
808
0
  return elements(is_soo())[index];
809
0
}
Unexecuted instantiation: google::protobuf::RepeatedField<google::protobuf::UnknownField>::Get(int) const
Unexecuted instantiation: google::protobuf::RepeatedField<int>::Get(int) const
810
811
template <typename Element>
812
inline const Element& RepeatedField<Element>::at(int index) const
813
    ABSL_ATTRIBUTE_LIFETIME_BOUND {
814
  ABSL_CHECK_GE(index, 0);
815
  ABSL_CHECK_LT(index, size());
816
  return elements(is_soo())[index];
817
}
818
819
template <typename Element>
820
inline Element& RepeatedField<Element>::at(int index)
821
    ABSL_ATTRIBUTE_LIFETIME_BOUND {
822
  ABSL_CHECK_GE(index, 0);
823
  ABSL_CHECK_LT(index, size());
824
  return elements(is_soo())[index];
825
}
826
827
template <typename Element>
828
inline Element* RepeatedField<Element>::Mutable(int index)
829
0
    ABSL_ATTRIBUTE_LIFETIME_BOUND {
830
0
  ABSL_DCHECK_GE(index, 0);
831
0
  ABSL_DCHECK_LT(index, size());
832
0
  return &elements(is_soo())[index];
833
0
}
Unexecuted instantiation: google::protobuf::RepeatedField<google::protobuf::UnknownField>::Mutable(int)
Unexecuted instantiation: google::protobuf::RepeatedField<int>::Mutable(int)
834
835
template <typename Element>
836
0
inline void RepeatedField<Element>::Set(int index, const Element& value) {
837
0
  *Mutable(index) = value;
838
0
}
839
840
template <typename Element>
841
0
inline void RepeatedField<Element>::Add(Element value) {
842
0
  bool is_soo = this->is_soo();
843
0
  const int old_size = size(is_soo);
844
0
  int capacity = Capacity(is_soo);
845
0
  Element* elem = unsafe_elements(is_soo);
846
0
  if (ABSL_PREDICT_FALSE(old_size == capacity)) {
847
0
    Grow(is_soo, old_size, old_size + 1);
848
0
    is_soo = false;
849
0
    capacity = Capacity(is_soo);
850
0
    elem = unsafe_elements(is_soo);
851
0
  }
852
0
  int new_size = old_size + 1;
853
0
  void* p = elem + ExchangeCurrentSize(is_soo, new_size);
854
0
  ::new (p) Element(std::move(value));
855
0
856
0
  // The below helps the compiler optimize dense loops.
857
0
  // Note: we can't call functions in PROTOBUF_ASSUME so use local variables.
858
0
  ABSL_ATTRIBUTE_UNUSED const bool final_is_soo = this->is_soo();
859
0
  PROTOBUF_ASSUME(is_soo == final_is_soo);
860
0
  ABSL_ATTRIBUTE_UNUSED const int final_size = size(is_soo);
861
0
  PROTOBUF_ASSUME(new_size == final_size);
862
0
  ABSL_ATTRIBUTE_UNUSED Element* const final_elements = unsafe_elements(is_soo);
863
0
  PROTOBUF_ASSUME(elem == final_elements);
864
0
  ABSL_ATTRIBUTE_UNUSED const int final_capacity = Capacity(is_soo);
865
0
  PROTOBUF_ASSUME(capacity == final_capacity);
866
0
}
Unexecuted instantiation: google::protobuf::RepeatedField<unsigned int>::Add(unsigned int)
Unexecuted instantiation: google::protobuf::RepeatedField<unsigned long>::Add(unsigned long)
Unexecuted instantiation: google::protobuf::RepeatedField<long>::Add(long)
Unexecuted instantiation: google::protobuf::RepeatedField<float>::Add(float)
Unexecuted instantiation: google::protobuf::RepeatedField<double>::Add(double)
Unexecuted instantiation: google::protobuf::RepeatedField<int>::Add(int)
867
868
template <typename Element>
869
inline Element* RepeatedField<Element>::Add() ABSL_ATTRIBUTE_LIFETIME_BOUND {
870
  bool is_soo = this->is_soo();
871
  const int old_size = size(is_soo);
872
  if (ABSL_PREDICT_FALSE(old_size == Capacity())) {
873
    Grow(is_soo, old_size, old_size + 1);
874
    is_soo = false;
875
  }
876
  void* p = unsafe_elements(is_soo) + ExchangeCurrentSize(is_soo, old_size + 1);
877
  return ::new (p) Element;
878
}
879
880
template <typename Element>
881
template <typename Iter>
882
inline void RepeatedField<Element>::AddForwardIterator(Iter begin, Iter end) {
883
  bool is_soo = this->is_soo();
884
  const int old_size = size(is_soo);
885
  int capacity = Capacity(is_soo);
886
  Element* elem = unsafe_elements(is_soo);
887
  int new_size = old_size + static_cast<int>(std::distance(begin, end));
888
  if (ABSL_PREDICT_FALSE(new_size > capacity)) {
889
    Grow(is_soo, old_size, new_size);
890
    is_soo = false;
891
    elem = unsafe_elements(is_soo);
892
    capacity = Capacity(is_soo);
893
  }
894
  UninitializedCopy(begin, end, elem + ExchangeCurrentSize(is_soo, new_size));
895
896
  // The below helps the compiler optimize dense loops.
897
  // Note: we can't call functions in PROTOBUF_ASSUME so use local variables.
898
  ABSL_ATTRIBUTE_UNUSED const bool final_is_soo = this->is_soo();
899
  PROTOBUF_ASSUME(is_soo == final_is_soo);
900
  ABSL_ATTRIBUTE_UNUSED const int final_size = size(is_soo);
901
  PROTOBUF_ASSUME(new_size == final_size);
902
  ABSL_ATTRIBUTE_UNUSED Element* const final_elements = unsafe_elements(is_soo);
903
  PROTOBUF_ASSUME(elem == final_elements);
904
  ABSL_ATTRIBUTE_UNUSED const int final_capacity = Capacity(is_soo);
905
  PROTOBUF_ASSUME(capacity == final_capacity);
906
}
907
908
template <typename Element>
909
template <typename Iter>
910
inline void RepeatedField<Element>::AddInputIterator(Iter begin, Iter end) {
911
  bool is_soo = this->is_soo();
912
  int size = this->size(is_soo);
913
  int capacity = Capacity(is_soo);
914
  Element* elem = unsafe_elements(is_soo);
915
  Element* first = elem + size;
916
  Element* last = elem + capacity;
917
  UnpoisonBuffer();
918
919
  while (begin != end) {
920
    if (ABSL_PREDICT_FALSE(first == last)) {
921
      size = first - elem;
922
      GrowNoAnnotate(is_soo, size, size + 1);
923
      is_soo = false;
924
      elem = unsafe_elements(is_soo);
925
      capacity = Capacity(is_soo);
926
      first = elem + size;
927
      last = elem + capacity;
928
    }
929
    ::new (static_cast<void*>(first)) Element(*begin);
930
    ++begin;
931
    ++first;
932
  }
933
934
  const int new_size = first - elem;
935
  set_size(is_soo, new_size);
936
  AnnotateSize(capacity, new_size);
937
}
938
939
template <typename Element>
940
template <typename Iter>
941
inline void RepeatedField<Element>::Add(Iter begin, Iter end) {
942
  if (std::is_base_of<
943
          std::forward_iterator_tag,
944
          typename std::iterator_traits<Iter>::iterator_category>::value) {
945
    AddForwardIterator(begin, end);
946
  } else {
947
    AddInputIterator(begin, end);
948
  }
949
}
950
951
template <typename Element>
952
inline void RepeatedField<Element>::RemoveLast() {
953
  const bool is_soo = this->is_soo();
954
  const int old_size = size(is_soo);
955
  ABSL_DCHECK_GT(old_size, 0);
956
  elements(is_soo)[old_size - 1].~Element();
957
  ExchangeCurrentSize(is_soo, old_size - 1);
958
}
959
960
template <typename Element>
961
void RepeatedField<Element>::ExtractSubrange(int start, int num,
962
                                             Element* elements) {
963
  ABSL_DCHECK_GE(start, 0);
964
  ABSL_DCHECK_GE(num, 0);
965
  const bool is_soo = this->is_soo();
966
  const int old_size = size(is_soo);
967
  ABSL_DCHECK_LE(start + num, old_size);
968
  Element* elem = unsafe_elements(is_soo);
969
970
  // Save the values of the removed elements if requested.
971
  if (elements != nullptr) {
972
    for (int i = 0; i < num; ++i) elements[i] = std::move(elem[i + start]);
973
  }
974
975
  // Slide remaining elements down to fill the gap.
976
  if (num > 0) {
977
    for (int i = start + num; i < old_size; ++i)
978
      elem[i - num] = std::move(elem[i]);
979
    Truncate(old_size - num);
980
  }
981
}
982
983
template <typename Element>
984
0
inline void RepeatedField<Element>::Clear() {
985
0
  const bool is_soo = this->is_soo();
986
0
  Element* elem = unsafe_elements(is_soo);
987
0
  Destroy(elem, elem + size(is_soo));
988
0
  ExchangeCurrentSize(is_soo, 0);
989
0
}
Unexecuted instantiation: google::protobuf::RepeatedField<google::protobuf::UnknownField>::Clear()
Unexecuted instantiation: google::protobuf::RepeatedField<int>::Clear()
990
991
template <typename Element>
992
0
inline void RepeatedField<Element>::MergeFrom(const RepeatedField& other) {
993
0
  ABSL_DCHECK_NE(&other, this);
994
0
  const bool other_is_soo = other.is_soo();
995
0
  if (auto other_size = other.size(other_is_soo)) {
996
0
    const int old_size = size();
997
0
    Reserve(old_size + other_size);
998
0
    const bool is_soo = this->is_soo();
999
0
    Element* dst =
1000
0
        elements(is_soo) + ExchangeCurrentSize(is_soo, old_size + other_size);
1001
0
    UninitializedCopyN(other.elements(other_is_soo), other_size, dst);
1002
0
  }
1003
0
}
1004
1005
template <typename Element>
1006
0
inline void RepeatedField<Element>::CopyFrom(const RepeatedField& other) {
1007
0
  if (&other == this) return;
1008
0
  Clear();
1009
0
  MergeFrom(other);
1010
0
}
1011
1012
template <typename Element>
1013
template <typename Iter>
1014
inline void RepeatedField<Element>::Assign(Iter begin, Iter end) {
1015
  Clear();
1016
  Add(begin, end);
1017
}
1018
1019
template <typename Element>
1020
inline typename RepeatedField<Element>::iterator RepeatedField<Element>::erase(
1021
    const_iterator position) ABSL_ATTRIBUTE_LIFETIME_BOUND {
1022
  return erase(position, position + 1);
1023
}
1024
1025
template <typename Element>
1026
inline typename RepeatedField<Element>::iterator RepeatedField<Element>::erase(
1027
    const_iterator first, const_iterator last) ABSL_ATTRIBUTE_LIFETIME_BOUND {
1028
  size_type first_offset = first - cbegin();
1029
  if (first != last) {
1030
    Truncate(std::copy(last, cend(), begin() + first_offset) - cbegin());
1031
  }
1032
  return begin() + first_offset;
1033
}
1034
1035
template <typename Element>
1036
inline Element* RepeatedField<Element>::mutable_data()
1037
0
    ABSL_ATTRIBUTE_LIFETIME_BOUND {
1038
0
  return unsafe_elements(is_soo());
1039
0
}
Unexecuted instantiation: google::protobuf::RepeatedField<unsigned int>::mutable_data()
Unexecuted instantiation: google::protobuf::RepeatedField<unsigned long>::mutable_data()
Unexecuted instantiation: google::protobuf::RepeatedField<int>::mutable_data()
Unexecuted instantiation: google::protobuf::RepeatedField<long>::mutable_data()
Unexecuted instantiation: google::protobuf::RepeatedField<float>::mutable_data()
Unexecuted instantiation: google::protobuf::RepeatedField<double>::mutable_data()
1040
1041
template <typename Element>
1042
inline const Element* RepeatedField<Element>::data() const
1043
0
    ABSL_ATTRIBUTE_LIFETIME_BOUND {
1044
0
  return unsafe_elements(is_soo());
1045
0
}
Unexecuted instantiation: google::protobuf::RepeatedField<int>::data() const
Unexecuted instantiation: google::protobuf::RepeatedField<long>::data() const
Unexecuted instantiation: google::protobuf::RepeatedField<unsigned int>::data() const
Unexecuted instantiation: google::protobuf::RepeatedField<unsigned long>::data() const
Unexecuted instantiation: google::protobuf::RepeatedField<float>::data() const
Unexecuted instantiation: google::protobuf::RepeatedField<double>::data() const
Unexecuted instantiation: google::protobuf::RepeatedField<bool>::data() const
1046
1047
template <typename Element>
1048
inline void RepeatedField<Element>::InternalSwap(
1049
0
    RepeatedField* PROTOBUF_RESTRICT other) {
1050
0
  ABSL_DCHECK(this != other);
1051
0
1052
0
  // We need to unpoison during the swap in case we're in SOO mode.
1053
0
  UnpoisonBuffer();
1054
0
  other->UnpoisonBuffer();
1055
0
1056
0
  internal::memswap<sizeof(internal::SooRep)>(
1057
0
      reinterpret_cast<char*>(&this->soo_rep_),
1058
0
      reinterpret_cast<char*>(&other->soo_rep_));
1059
0
1060
0
  AnnotateSize(Capacity(), size());
1061
0
  other->AnnotateSize(other->Capacity(), other->size());
1062
0
}
1063
1064
template <typename Element>
1065
0
void RepeatedField<Element>::Swap(RepeatedField* other) {
1066
0
  if (this == other) return;
1067
0
  Arena* arena = GetArena();
1068
0
  Arena* other_arena = other->GetArena();
1069
0
  if (internal::CanUseInternalSwap(arena, other_arena)) {
1070
0
    InternalSwap(other);
1071
0
  } else {
1072
0
    RepeatedField<Element> temp(other_arena);
1073
0
    temp.MergeFrom(*this);
1074
0
    CopyFrom(*other);
1075
0
    other->UnsafeArenaSwap(&temp);
1076
0
  }
1077
0
}
1078
1079
template <typename Element>
1080
0
void RepeatedField<Element>::UnsafeArenaSwap(RepeatedField* other) {
1081
0
  if (this == other) return;
1082
0
  ABSL_DCHECK_EQ(GetArena(), other->GetArena());
1083
0
  InternalSwap(other);
1084
0
}
1085
1086
template <typename Element>
1087
void RepeatedField<Element>::SwapElements(int index1, int index2) {
1088
  Element* elem = elements(is_soo());
1089
  using std::swap;  // enable ADL with fallback
1090
  swap(elem[index1], elem[index2]);
1091
}
1092
1093
template <typename Element>
1094
inline typename RepeatedField<Element>::iterator RepeatedField<Element>::begin()
1095
    ABSL_ATTRIBUTE_LIFETIME_BOUND {
1096
  return iterator(unsafe_elements(is_soo()));
1097
}
1098
template <typename Element>
1099
inline typename RepeatedField<Element>::const_iterator
1100
RepeatedField<Element>::begin() const ABSL_ATTRIBUTE_LIFETIME_BOUND {
1101
  return const_iterator(unsafe_elements(is_soo()));
1102
}
1103
template <typename Element>
1104
inline typename RepeatedField<Element>::const_iterator
1105
RepeatedField<Element>::cbegin() const ABSL_ATTRIBUTE_LIFETIME_BOUND {
1106
  return const_iterator(unsafe_elements(is_soo()));
1107
}
1108
template <typename Element>
1109
inline typename RepeatedField<Element>::iterator RepeatedField<Element>::end()
1110
    ABSL_ATTRIBUTE_LIFETIME_BOUND {
1111
  const bool is_soo = this->is_soo();
1112
  return iterator(unsafe_elements(is_soo) + size(is_soo));
1113
}
1114
template <typename Element>
1115
inline typename RepeatedField<Element>::const_iterator
1116
RepeatedField<Element>::end() const ABSL_ATTRIBUTE_LIFETIME_BOUND {
1117
  const bool is_soo = this->is_soo();
1118
  return const_iterator(unsafe_elements(is_soo) + size(is_soo));
1119
}
1120
template <typename Element>
1121
inline typename RepeatedField<Element>::const_iterator
1122
RepeatedField<Element>::cend() const ABSL_ATTRIBUTE_LIFETIME_BOUND {
1123
  const bool is_soo = this->is_soo();
1124
  return const_iterator(unsafe_elements(is_soo) + size(is_soo));
1125
}
1126
1127
template <typename Element>
1128
inline size_t RepeatedField<Element>::SpaceUsedExcludingSelfLong() const {
1129
  const int capacity = Capacity();
1130
  return capacity > kSooCapacityElements
1131
             ? capacity * sizeof(Element) + kHeapRepHeaderSize
1132
             : 0;
1133
}
1134
1135
namespace internal {
1136
// Returns the new size for a reserved field based on its 'capacity' and the
1137
// requested 'new_size'. The result is clamped to the closed interval:
1138
//   [internal::kMinRepeatedFieldAllocationSize,
1139
//    std::numeric_limits<int>::max()]
1140
// Requires: new_size > capacity
1141
template <typename T, int kHeapRepHeaderSize>
1142
0
inline int CalculateReserveSize(int capacity, int new_size) {
1143
0
  constexpr int lower_limit =
1144
0
      RepeatedFieldLowerClampLimit<T, kHeapRepHeaderSize>();
1145
0
  if (new_size < lower_limit) {
1146
0
    // Clamp to smallest allowed size.
1147
0
    return lower_limit;
1148
0
  }
1149
0
  constexpr int kMaxSizeBeforeClamp =
1150
0
      (std::numeric_limits<int>::max() - kHeapRepHeaderSize) / 2;
1151
0
  if (PROTOBUF_PREDICT_FALSE(capacity > kMaxSizeBeforeClamp)) {
1152
0
    return std::numeric_limits<int>::max();
1153
0
  }
1154
0
  constexpr int kSooCapacityElements = SooCapacityElements(sizeof(T));
1155
0
  if (kSooCapacityElements > 0 && kSooCapacityElements < lower_limit) {
1156
0
    // In this case, we need to set capacity to 0 here to ensure power-of-two
1157
0
    // sized allocations.
1158
0
    if (capacity < lower_limit) capacity = 0;
1159
0
  } else {
1160
0
    ABSL_DCHECK(capacity == 0 || capacity >= lower_limit)
1161
0
        << capacity << " " << lower_limit;
1162
0
  }
1163
0
  // We want to double the number of bytes, not the number of elements, to try
1164
0
  // to stay within power-of-two allocations.
1165
0
  // The allocation has kHeapRepHeaderSize + sizeof(T) * capacity.
1166
0
  int doubled_size = 2 * capacity + kHeapRepHeaderSize / sizeof(T);
1167
0
  return std::max(doubled_size, new_size);
1168
0
}
Unexecuted instantiation: int google::protobuf::internal::CalculateReserveSize<unsigned int, 8>(int, int)
Unexecuted instantiation: int google::protobuf::internal::CalculateReserveSize<unsigned long, 8>(int, int)
Unexecuted instantiation: int google::protobuf::internal::CalculateReserveSize<long, 8>(int, int)
Unexecuted instantiation: int google::protobuf::internal::CalculateReserveSize<float, 8>(int, int)
Unexecuted instantiation: int google::protobuf::internal::CalculateReserveSize<double, 8>(int, int)
Unexecuted instantiation: int google::protobuf::internal::CalculateReserveSize<int, 8>(int, int)
Unexecuted instantiation: int google::protobuf::internal::CalculateReserveSize<google::protobuf::UnknownField, 16>(int, int)
1169
}  // namespace internal
1170
1171
template <typename Element>
1172
0
void RepeatedField<Element>::Reserve(int new_size) {
1173
0
  const bool was_soo = is_soo();
1174
0
  if (ABSL_PREDICT_FALSE(new_size > Capacity(was_soo))) {
1175
0
    Grow(was_soo, size(was_soo), new_size);
1176
0
  }
1177
0
}
1178
1179
// Avoid inlining of Reserve(): new, copy, and delete[] lead to a significant
1180
// amount of code bloat.
1181
template <typename Element>
1182
PROTOBUF_NOINLINE void RepeatedField<Element>::GrowNoAnnotate(bool was_soo,
1183
                                                              int old_size,
1184
0
                                                              int new_size) {
1185
0
  const int old_capacity = Capacity(was_soo);
1186
0
  ABSL_DCHECK_GT(new_size, old_capacity);
1187
0
  HeapRep* new_rep;
1188
0
  Arena* arena = GetArena();
1189
0
1190
0
  new_size = internal::CalculateReserveSize<Element, kHeapRepHeaderSize>(
1191
0
      old_capacity, new_size);
1192
0
1193
0
  ABSL_DCHECK_LE(static_cast<size_t>(new_size),
1194
0
                 (std::numeric_limits<size_t>::max() - kHeapRepHeaderSize) /
1195
0
                     sizeof(Element))
1196
0
      << "Requested size is too large to fit into size_t.";
1197
0
  size_t bytes =
1198
0
      kHeapRepHeaderSize + sizeof(Element) * static_cast<size_t>(new_size);
1199
0
  if (arena == nullptr) {
1200
0
    ABSL_DCHECK_LE((bytes - kHeapRepHeaderSize) / sizeof(Element),
1201
0
                   static_cast<size_t>(std::numeric_limits<int>::max()))
1202
0
        << "Requested size is too large to fit element count into int.";
1203
0
    internal::SizedPtr res = internal::AllocateAtLeast(bytes);
1204
0
    size_t num_available =
1205
0
        std::min((res.n - kHeapRepHeaderSize) / sizeof(Element),
1206
0
                 static_cast<size_t>(std::numeric_limits<int>::max()));
1207
0
    new_size = static_cast<int>(num_available);
1208
0
    new_rep = static_cast<HeapRep*>(res.p);
1209
0
  } else {
1210
0
    new_rep =
1211
0
        reinterpret_cast<HeapRep*>(Arena::CreateArray<char>(arena, bytes));
1212
0
  }
1213
0
  new_rep->arena = arena;
1214
0
1215
0
  if (old_size > 0) {
1216
0
    Element* pnew = static_cast<Element*>(new_rep->elements());
1217
0
    Element* pold = elements(was_soo);
1218
0
    // TODO: add absl::is_trivially_relocatable<Element>
1219
0
    if (std::is_trivial<Element>::value) {
1220
0
      memcpy(static_cast<void*>(pnew), pold, old_size * sizeof(Element));
1221
0
    } else {
1222
0
      for (Element* end = pnew + old_size; pnew != end; ++pnew, ++pold) {
1223
0
        ::new (static_cast<void*>(pnew)) Element(std::move(*pold));
1224
0
        pold->~Element();
1225
0
      }
1226
0
    }
1227
0
  }
1228
0
  if (!was_soo) InternalDeallocate();
1229
0
1230
0
  soo_rep_.set_non_soo(was_soo, new_size, new_rep->elements());
1231
0
}
Unexecuted instantiation: google::protobuf::RepeatedField<unsigned int>::GrowNoAnnotate(bool, int, int)
Unexecuted instantiation: google::protobuf::RepeatedField<unsigned long>::GrowNoAnnotate(bool, int, int)
Unexecuted instantiation: google::protobuf::RepeatedField<long>::GrowNoAnnotate(bool, int, int)
Unexecuted instantiation: google::protobuf::RepeatedField<float>::GrowNoAnnotate(bool, int, int)
Unexecuted instantiation: google::protobuf::RepeatedField<double>::GrowNoAnnotate(bool, int, int)
Unexecuted instantiation: google::protobuf::RepeatedField<int>::GrowNoAnnotate(bool, int, int)
Unexecuted instantiation: google::protobuf::RepeatedField<google::protobuf::UnknownField>::GrowNoAnnotate(bool, int, int)
1232
1233
// Ideally we would be able to use:
1234
//   template <bool annotate_size = true>
1235
//   void Grow();
1236
// However, as explained in b/266411038#comment9, this causes issues
1237
// in shared libraries for Youtube (and possibly elsewhere).
1238
template <typename Element>
1239
PROTOBUF_NOINLINE void RepeatedField<Element>::Grow(bool was_soo, int old_size,
1240
0
                                                    int new_size) {
1241
0
  UnpoisonBuffer();
1242
0
  GrowNoAnnotate(was_soo, old_size, new_size);
1243
0
  AnnotateSize(Capacity(), old_size);
1244
0
}
Unexecuted instantiation: google::protobuf::RepeatedField<unsigned int>::Grow(bool, int, int)
Unexecuted instantiation: google::protobuf::RepeatedField<unsigned long>::Grow(bool, int, int)
Unexecuted instantiation: google::protobuf::RepeatedField<long>::Grow(bool, int, int)
Unexecuted instantiation: google::protobuf::RepeatedField<float>::Grow(bool, int, int)
Unexecuted instantiation: google::protobuf::RepeatedField<double>::Grow(bool, int, int)
Unexecuted instantiation: google::protobuf::RepeatedField<int>::Grow(bool, int, int)
Unexecuted instantiation: google::protobuf::RepeatedField<google::protobuf::UnknownField>::Grow(bool, int, int)
1245
1246
template <typename Element>
1247
0
inline void RepeatedField<Element>::Truncate(int new_size) {
1248
0
  const bool is_soo = this->is_soo();
1249
0
  const int old_size = size(is_soo);
1250
0
  ABSL_DCHECK_LE(new_size, old_size);
1251
0
  if (new_size < old_size) {
1252
0
    Element* elem = unsafe_elements(is_soo);
1253
0
    Destroy(elem + new_size, elem + old_size);
1254
0
    ExchangeCurrentSize(is_soo, new_size);
1255
0
  }
1256
0
}
Unexecuted instantiation: google::protobuf::RepeatedField<unsigned int>::Truncate(int)
Unexecuted instantiation: google::protobuf::RepeatedField<unsigned long>::Truncate(int)
Unexecuted instantiation: google::protobuf::RepeatedField<int>::Truncate(int)
Unexecuted instantiation: google::protobuf::RepeatedField<long>::Truncate(int)
Unexecuted instantiation: google::protobuf::RepeatedField<float>::Truncate(int)
Unexecuted instantiation: google::protobuf::RepeatedField<double>::Truncate(int)
1257
1258
template <>
1259
PROTOBUF_EXPORT size_t
1260
RepeatedField<absl::Cord>::SpaceUsedExcludingSelfLong() const;
1261
1262
1263
// -------------------------------------------------------------------
1264
1265
// Iterators and helper functions that follow the spirit of the STL
1266
// std::back_insert_iterator and std::back_inserter but are tailor-made
1267
// for RepeatedField and RepeatedPtrField. Typical usage would be:
1268
//
1269
//   std::copy(some_sequence.begin(), some_sequence.end(),
1270
//             RepeatedFieldBackInserter(proto.mutable_sequence()));
1271
//
1272
// Ported by johannes from util/gtl/proto-array-iterators.h
1273
1274
namespace internal {
1275
1276
// STL-like iterator implementation for RepeatedField.  You should not
1277
// refer to this class directly; use RepeatedField<T>::iterator instead.
1278
//
1279
// Note: All of the iterator operators *must* be inlined to avoid performance
1280
// regressions.  This is caused by the extern template declarations below (which
1281
// are required because of the RepeatedField extern template declarations).  If
1282
// any of these functions aren't explicitly inlined (e.g. defined in the class),
1283
// the compiler isn't allowed to inline them.
1284
template <typename Element>
1285
class RepeatedIterator {
1286
 private:
1287
  using traits =
1288
      std::iterator_traits<typename std::remove_const<Element>::type*>;
1289
1290
 public:
1291
  // Note: value_type is never cv-qualified.
1292
  using value_type = typename traits::value_type;
1293
  using difference_type = typename traits::difference_type;
1294
  using pointer = Element*;
1295
  using reference = Element&;
1296
  using iterator_category = typename traits::iterator_category;
1297
  using iterator_concept = typename IteratorConceptSupport<traits>::tag;
1298
1299
  constexpr RepeatedIterator() noexcept : it_(nullptr) {}
1300
1301
  // Allows "upcasting" from RepeatedIterator<T**> to
1302
  // RepeatedIterator<const T*const*>.
1303
  template <typename OtherElement,
1304
            typename std::enable_if<std::is_convertible<
1305
                OtherElement*, pointer>::value>::type* = nullptr>
1306
  constexpr RepeatedIterator(
1307
      const RepeatedIterator<OtherElement>& other) noexcept
1308
      : it_(other.it_) {}
1309
1310
  // dereferenceable
1311
  constexpr reference operator*() const noexcept { return *it_; }
1312
  constexpr pointer operator->() const noexcept { return it_; }
1313
1314
 private:
1315
  // Helper alias to hide the internal type.
1316
  using iterator = RepeatedIterator<Element>;
1317
1318
 public:
1319
  // {inc,dec}rementable
1320
  iterator& operator++() noexcept {
1321
    ++it_;
1322
    return *this;
1323
  }
1324
  iterator operator++(int) noexcept { return iterator(it_++); }
1325
  iterator& operator--() noexcept {
1326
    --it_;
1327
    return *this;
1328
  }
1329
  iterator operator--(int) noexcept { return iterator(it_--); }
1330
1331
  // equality_comparable
1332
  friend constexpr bool operator==(const iterator& x,
1333
                                   const iterator& y) noexcept {
1334
    return x.it_ == y.it_;
1335
  }
1336
  friend constexpr bool operator!=(const iterator& x,
1337
                                   const iterator& y) noexcept {
1338
    return x.it_ != y.it_;
1339
  }
1340
1341
  // less_than_comparable
1342
  friend constexpr bool operator<(const iterator& x,
1343
                                  const iterator& y) noexcept {
1344
    return x.it_ < y.it_;
1345
  }
1346
  friend constexpr bool operator<=(const iterator& x,
1347
                                   const iterator& y) noexcept {
1348
    return x.it_ <= y.it_;
1349
  }
1350
  friend constexpr bool operator>(const iterator& x,
1351
                                  const iterator& y) noexcept {
1352
    return x.it_ > y.it_;
1353
  }
1354
  friend constexpr bool operator>=(const iterator& x,
1355
                                   const iterator& y) noexcept {
1356
    return x.it_ >= y.it_;
1357
  }
1358
1359
  // addable, subtractable
1360
  iterator& operator+=(difference_type d) noexcept {
1361
    it_ += d;
1362
    return *this;
1363
  }
1364
  constexpr iterator operator+(difference_type d) const noexcept {
1365
    return iterator(it_ + d);
1366
  }
1367
  friend constexpr iterator operator+(const difference_type d,
1368
                                      iterator it) noexcept {
1369
    return it + d;
1370
  }
1371
1372
  iterator& operator-=(difference_type d) noexcept {
1373
    it_ -= d;
1374
    return *this;
1375
  }
1376
  iterator constexpr operator-(difference_type d) const noexcept {
1377
    return iterator(it_ - d);
1378
  }
1379
1380
  // indexable
1381
  constexpr reference operator[](difference_type d) const noexcept {
1382
    return it_[d];
1383
  }
1384
1385
  // random access iterator
1386
  friend constexpr difference_type operator-(iterator it1,
1387
                                             iterator it2) noexcept {
1388
    return it1.it_ - it2.it_;
1389
  }
1390
1391
 private:
1392
  template <typename OtherElement>
1393
  friend class RepeatedIterator;
1394
1395
  // Allow construction from RepeatedField.
1396
  friend class RepeatedField<value_type>;
1397
  explicit RepeatedIterator(pointer it) noexcept : it_(it) {}
1398
1399
  // The internal iterator.
1400
  pointer it_;
1401
};
1402
1403
// A back inserter for RepeatedField objects.
1404
template <typename T>
1405
class RepeatedFieldBackInsertIterator {
1406
 public:
1407
  using iterator_category = std::output_iterator_tag;
1408
  using value_type = T;
1409
  using pointer = void;
1410
  using reference = void;
1411
  using difference_type = std::ptrdiff_t;
1412
1413
  explicit RepeatedFieldBackInsertIterator(
1414
      RepeatedField<T>* const mutable_field)
1415
      : field_(mutable_field) {}
1416
  RepeatedFieldBackInsertIterator<T>& operator=(const T& value) {
1417
    field_->Add(value);
1418
    return *this;
1419
  }
1420
  RepeatedFieldBackInsertIterator<T>& operator*() { return *this; }
1421
  RepeatedFieldBackInsertIterator<T>& operator++() { return *this; }
1422
  RepeatedFieldBackInsertIterator<T>& operator++(int /* unused */) {
1423
    return *this;
1424
  }
1425
1426
 private:
1427
  RepeatedField<T>* field_;
1428
};
1429
1430
}  // namespace internal
1431
1432
// Provides a back insert iterator for RepeatedField instances,
1433
// similar to std::back_inserter().
1434
template <typename T>
1435
internal::RepeatedFieldBackInsertIterator<T> RepeatedFieldBackInserter(
1436
    RepeatedField<T>* const mutable_field) {
1437
  return internal::RepeatedFieldBackInsertIterator<T>(mutable_field);
1438
}
1439
1440
1441
}  // namespace protobuf
1442
}  // namespace google
1443
1444
#include "google/protobuf/port_undef.inc"
1445
1446
#endif  // GOOGLE_PROTOBUF_REPEATED_FIELD_H__