Coverage Report

Created: 2023-06-07 07:09

/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
// https://developers.google.com/protocol-buffers/
4
//
5
// Redistribution and use in source and binary forms, with or without
6
// modification, are permitted provided that the following conditions are
7
// met:
8
//
9
//     * Redistributions of source code must retain the above copyright
10
// notice, this list of conditions and the following disclaimer.
11
//     * Redistributions in binary form must reproduce the above
12
// copyright notice, this list of conditions and the following disclaimer
13
// in the documentation and/or other materials provided with the
14
// distribution.
15
//     * Neither the name of Google Inc. nor the names of its
16
// contributors may be used to endorse or promote products derived from
17
// this software without specific prior written permission.
18
//
19
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
31
// Author: kenton@google.com (Kenton Varda)
32
//  Based on original Protocol Buffers design by
33
//  Sanjay Ghemawat, Jeff Dean, and others.
34
//
35
// RepeatedField and RepeatedPtrField are used by generated protocol message
36
// classes to manipulate repeated fields.  These classes are very similar to
37
// STL's vector, but include a number of optimizations found to be useful
38
// specifically in the case of Protocol Buffers.  RepeatedPtrField is
39
// particularly different from STL vector as it manages ownership of the
40
// pointers that it contains.
41
//
42
// This header covers RepeatedField.
43
44
#ifndef GOOGLE_PROTOBUF_REPEATED_FIELD_H__
45
#define GOOGLE_PROTOBUF_REPEATED_FIELD_H__
46
47
#include <algorithm>
48
#include <iterator>
49
#include <limits>
50
#include <memory>
51
#include <string>
52
#include <type_traits>
53
#include <utility>
54
55
#include "google/protobuf/arena.h"
56
#include "google/protobuf/port.h"
57
#include "absl/base/dynamic_annotations.h"
58
#include "absl/log/absl_check.h"
59
#include "absl/meta/type_traits.h"
60
#include "absl/strings/cord.h"
61
#include "google/protobuf/generated_enum_util.h"
62
#include "google/protobuf/message_lite.h"
63
#include "google/protobuf/port.h"
64
#include "google/protobuf/repeated_ptr_field.h"
65
66
67
// Must be included last.
68
#include "google/protobuf/port_def.inc"
69
70
#ifdef SWIG
71
#error "You cannot SWIG proto headers"
72
#endif
73
74
namespace google {
75
namespace protobuf {
76
77
class Message;
78
79
namespace internal {
80
81
template <typename T, int kRepHeaderSize>
82
0
constexpr int RepeatedFieldLowerClampLimit() {
83
0
  // The header is padded to be at least `sizeof(T)` when it would be smaller
84
0
  // otherwise.
85
0
  static_assert(sizeof(T) <= kRepHeaderSize, "");
86
0
  // We want to pad the minimum size to be a power of two bytes, including the
87
0
  // header.
88
0
  // The first allocation is kRepHeaderSize bytes worth of elements for a total
89
0
  // of 2*kRepHeaderSize bytes.
90
0
  // For an 8-byte header, we allocate 8 bool, 2 ints, or 1 int64.
91
0
  return kRepHeaderSize / sizeof(T);
92
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>()
93
94
// kRepeatedFieldUpperClampLimit is the lowest signed integer value that
95
// overflows when multiplied by 2 (which is undefined behavior). Sizes above
96
// this will clamp to the maximum int value instead of following exponential
97
// growth when growing a repeated field.
98
constexpr int kRepeatedFieldUpperClampLimit =
99
    (std::numeric_limits<int>::max() / 2) + 1;
100
101
// Swaps two blocks of memory of size kSize:
102
template <size_t kSize>
103
0
void memswap(char* a, char* b) {
104
0
#if __SIZEOF_INT128__
105
0
  using Buffer = __uint128_t;
106
#else
107
  using Buffer = uint64_t;
108
#endif
109
110
0
  constexpr size_t kBlockSize = sizeof(Buffer);
111
0
  Buffer buf;
112
0
  for (size_t i = 0; i < kSize / kBlockSize; ++i) {
113
0
    memcpy(&buf, a, kBlockSize);
114
0
    memcpy(a, b, kBlockSize);
115
0
    memcpy(b, &buf, kBlockSize);
116
0
    a += kBlockSize;
117
0
    b += kBlockSize;
118
0
  }
119
120
#if defined(__GNUC__) && !defined(__clang__)
121
  // Workaround GCC bug: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99578
122
#pragma GCC diagnostic push
123
#pragma GCC diagnostic ignored "-Wpragmas"
124
#pragma GCC diagnostic ignored "-Wstringop-overflow"
125
#endif  // __GNUC__
126
127
  // Swap the leftover bytes, could be zero.
128
0
  memcpy(&buf, a, kSize % kBlockSize);
129
0
  memcpy(a, b, kSize % kBlockSize);
130
0
  memcpy(b, &buf, kSize % kBlockSize);
131
132
#if defined(__GNUC__) && !defined(__clang__)
133
#pragma GCC diagnostic pop
134
#endif  // GCC
135
0
}
Unexecuted instantiation: void google::protobuf::internal::memswap<20ul>(char*, char*)
Unexecuted instantiation: void google::protobuf::internal::memswap<24ul>(char*, char*)
Unexecuted instantiation: void google::protobuf::internal::memswap<12ul>(char*, char*)
Unexecuted instantiation: void google::protobuf::internal::memswap<8ul>(char*, char*)
136
137
template <typename Element>
138
class RepeatedIterator;
139
140
}  // namespace internal
141
142
// RepeatedField is used to represent repeated fields of a primitive type (in
143
// other words, everything except strings and nested Messages).  Most users will
144
// not ever use a RepeatedField directly; they will use the get-by-index,
145
// set-by-index, and add accessors that are generated for all repeated fields.
146
// Actually, in addition to primitive types, we use RepeatedField for repeated
147
// Cords, because the Cord class is in fact just a reference-counted pointer.
148
// We have to specialize several methods in the Cord case to get the memory
149
// management right; e.g. swapping when appropriate, etc.
150
template <typename Element>
151
class RepeatedField final {
152
  static_assert(
153
      alignof(Arena) >= alignof(Element),
154
      "We only support types that have an alignment smaller than Arena");
155
  static_assert(!std::is_const<Element>::value,
156
                "We do not support const value types.");
157
  static_assert(!std::is_volatile<Element>::value,
158
                "We do not support volatile value types.");
159
  static_assert(!std::is_pointer<Element>::value,
160
                "We do not support pointer value types.");
161
  static_assert(!std::is_reference<Element>::value,
162
                "We do not support reference value types.");
163
  static constexpr PROTOBUF_ALWAYS_INLINE void StaticValidityCheck() {
164
    static_assert(
165
        absl::disjunction<internal::is_supported_integral_type<Element>,
166
                          internal::is_supported_floating_point_type<Element>,
167
                          std::is_same<absl::Cord, Element>,
168
                          is_proto_enum<Element>>::value,
169
        "We only support non-string scalars in RepeatedField.");
170
  }
171
172
 public:
173
  constexpr RepeatedField();
174
  explicit RepeatedField(Arena* arena);
175
176
  RepeatedField(const RepeatedField& rhs);
177
178
  template <typename Iter,
179
            typename = typename std::enable_if<std::is_constructible<
180
                Element, decltype(*std::declval<Iter>())>::value>::type>
181
  RepeatedField(Iter begin, Iter end);
182
183
  ~RepeatedField();
184
185
  RepeatedField& operator=(const RepeatedField& other);
186
187
  RepeatedField(RepeatedField&& other) noexcept;
188
  RepeatedField& operator=(RepeatedField&& other) noexcept;
189
190
  bool empty() const;
191
  int size() const;
192
193
  const Element& Get(int index) const;
194
  Element* Mutable(int index);
195
196
  const Element& operator[](int index) const { return Get(index); }
197
  Element& operator[](int index) { return *Mutable(index); }
198
199
  const Element& at(int index) const;
200
  Element& at(int index);
201
202
  void Set(int index, const Element& value);
203
  void Add(Element value);
204
205
  // Appends a new element and returns a pointer to it.
206
  // The new element is uninitialized if |Element| is a POD type.
207
  Element* Add();
208
  // Appends elements in the range [begin, end) after reserving
209
  // the appropriate number of elements.
210
  template <typename Iter>
211
  void Add(Iter begin, Iter end);
212
213
  // Removes the last element in the array.
214
  void RemoveLast();
215
216
  // Extracts elements with indices in "[start .. start+num-1]".
217
  // Copies them into "elements[0 .. num-1]" if "elements" is not nullptr.
218
  // Caution: also moves elements with indices [start+num ..].
219
  // Calling this routine inside a loop can cause quadratic behavior.
220
  void ExtractSubrange(int start, int num, Element* elements);
221
222
  PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear();
223
  void MergeFrom(const RepeatedField& other);
224
  PROTOBUF_ATTRIBUTE_REINITIALIZES void CopyFrom(const RepeatedField& other);
225
226
  // Replaces the contents with RepeatedField(begin, end).
227
  template <typename Iter>
228
  PROTOBUF_ATTRIBUTE_REINITIALIZES void Assign(Iter begin, Iter end);
229
230
  // Reserves space to expand the field to at least the given size.  If the
231
  // array is grown, it will always be at least doubled in size.
232
  void Reserve(int new_size);
233
234
  // Resizes the RepeatedField to a new, smaller size.  This is O(1).
235
  // Except for RepeatedField<Cord>, for which it is O(size-new_size).
236
  void Truncate(int new_size);
237
238
  void AddAlreadyReserved(Element value);
239
  int Capacity() const;
240
241
  // Adds `n` elements to this instance asserting there is enough capacity.
242
  // The added elements are uninitialized if `Element` is trivial.
243
  Element* AddAlreadyReserved();
244
  Element* AddNAlreadyReserved(int n);
245
246
  // Like STL resize.  Uses value to fill appended elements.
247
  // Like Truncate() if new_size <= size(), otherwise this is
248
  // O(new_size - size()).
249
  void Resize(int new_size, const Element& value);
250
251
  // Gets the underlying array.  This pointer is possibly invalidated by
252
  // any add or remove operation.
253
  Element* mutable_data();
254
  const Element* data() const;
255
256
  // Swaps entire contents with "other". If they are separate arenas, then
257
  // copies data between each other.
258
  void Swap(RepeatedField* other);
259
260
  // Swaps two elements.
261
  void SwapElements(int index1, int index2);
262
263
  // STL-like iterator support
264
  typedef internal::RepeatedIterator<Element> iterator;
265
  typedef internal::RepeatedIterator<const Element> const_iterator;
266
  typedef Element value_type;
267
  typedef value_type& reference;
268
  typedef const value_type& const_reference;
269
  typedef value_type* pointer;
270
  typedef const value_type* const_pointer;
271
  typedef int size_type;
272
  typedef ptrdiff_t difference_type;
273
274
  iterator begin();
275
  const_iterator begin() const;
276
  const_iterator cbegin() const;
277
  iterator end();
278
  const_iterator end() const;
279
  const_iterator cend() const;
280
281
  // Reverse iterator support
282
  typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
283
  typedef std::reverse_iterator<iterator> reverse_iterator;
284
  reverse_iterator rbegin() { return reverse_iterator(end()); }
285
  const_reverse_iterator rbegin() const {
286
    return const_reverse_iterator(end());
287
  }
288
  reverse_iterator rend() { return reverse_iterator(begin()); }
289
  const_reverse_iterator rend() const {
290
    return const_reverse_iterator(begin());
291
  }
292
293
  // Returns the number of bytes used by the repeated field, excluding
294
  // sizeof(*this)
295
  size_t SpaceUsedExcludingSelfLong() const;
296
297
  int SpaceUsedExcludingSelf() const {
298
    return internal::ToIntSize(SpaceUsedExcludingSelfLong());
299
  }
300
301
  // Removes the element referenced by position.
302
  //
303
  // Returns an iterator to the element immediately following the removed
304
  // element.
305
  //
306
  // Invalidates all iterators at or after the removed element, including end().
307
  iterator erase(const_iterator position);
308
309
  // Removes the elements in the range [first, last).
310
  //
311
  // Returns an iterator to the element immediately following the removed range.
312
  //
313
  // Invalidates all iterators at or after the removed range, including end().
314
  iterator erase(const_iterator first, const_iterator last);
315
316
  // Gets the Arena on which this RepeatedField stores its elements.
317
  // Note: this can be inaccurate for split default fields so we make this
318
  // function non-const.
319
  inline Arena* GetArena() { return GetOwningArena(); }
320
321
  // For internal use only.
322
  //
323
  // This is public due to it being called by generated code.
324
  inline void InternalSwap(RepeatedField* other);
325
326
 private:
327
  template <typename T> friend class Arena::InternalHelper;
328
329
  // Gets the Arena on which this RepeatedField stores its elements.
330
0
  inline Arena* GetOwningArena() const {
331
0
    return (total_size_ == 0) ? static_cast<Arena*>(arena_or_elements_)
332
0
                              : rep()->arena;
333
0
  }
Unexecuted instantiation: google::protobuf::RepeatedField<unsigned int>::GetOwningArena() const
Unexecuted instantiation: google::protobuf::RepeatedField<unsigned long>::GetOwningArena() const
Unexecuted instantiation: google::protobuf::RepeatedField<long>::GetOwningArena() const
Unexecuted instantiation: google::protobuf::RepeatedField<float>::GetOwningArena() const
Unexecuted instantiation: google::protobuf::RepeatedField<double>::GetOwningArena() const
Unexecuted instantiation: google::protobuf::RepeatedField<int>::GetOwningArena() const
334
335
  // Swaps entire contents with "other". Should be called only if the caller can
336
  // guarantee that both repeated fields are on the same arena or are on the
337
  // heap. Swapping between different arenas is disallowed and caught by a
338
  // ABSL_DCHECK (see API docs for details).
339
  void UnsafeArenaSwap(RepeatedField* other);
340
341
  // Copy constructs `n` instances in place into the array `dst`.
342
  // This function is identical to `std::uninitialized_copy_n(src, n, dst)`
343
  // except that we explicit declare the memory to not be aliased, which will
344
  // result in `memcpy` code generation instead of `memmove` for trivial types.
345
  static inline void UninitializedCopyN(const Element* PROTOBUF_RESTRICT src,
346
                                        int n, Element* PROTOBUF_RESTRICT dst) {
347
    std::uninitialized_copy_n(src, n, dst);
348
  }
349
350
  // Copy constructs `[begin, end)` instances in place into the array `dst`.
351
  // See above `UninitializedCopyN()` function comments for more information.
352
  template <typename Iter>
353
  static inline void UninitializedCopy(Iter begin, Iter end,
354
                                       Element* PROTOBUF_RESTRICT dst) {
355
    std::uninitialized_copy(begin, end, dst);
356
  }
357
358
  template <typename Iter>
359
  void AddForwardIterator(Iter begin, Iter end);
360
361
  template <typename Iter>
362
  void AddInputIterator(Iter begin, Iter end);
363
364
  // Reserves space to expand the field to at least the given size.
365
  // If the array is grown, it will always be at least doubled in size.
366
  // If `annotate_size` is true (the default), then this function will annotate
367
  // the old container from `current_size` to `total_size_` (unpoison memory)
368
  // directly before it is being released, and annotate the new container from
369
  // `total_size_` to `current_size` (poison unused memory).
370
  void Grow(int current_size, int new_size);
371
  void GrowNoAnnotate(int current_size, int new_size);
372
373
  static constexpr int kInitialSize = 0;
374
  // A note on the representation here (see also comment below for
375
  // RepeatedPtrFieldBase's struct Rep):
376
  //
377
  // We maintain the same sizeof(RepeatedField) as before we added arena support
378
  // so that we do not degrade performance by bloating memory usage. Directly
379
  // adding an arena_ element to RepeatedField is quite costly. By using
380
  // indirection in this way, we keep the same size when the RepeatedField is
381
  // empty (common case), and add only an 8-byte header to the elements array
382
  // when non-empty. We make sure to place the size fields directly in the
383
  // RepeatedField class to avoid costly cache misses due to the indirection.
384
  int current_size_;
385
  int total_size_;
386
387
  // Annotates a change in size of this instance. This function should be called
388
  // with (total_size, current_size) after new memory has been allocated and
389
  // filled from previous memory), and called with (current_size, total_size)
390
  // right before (previously annotated) memory is released.
391
0
  void AnnotateSize(int old_size, int new_size) const {
392
0
    if (old_size != new_size) {
393
0
      ABSL_ANNOTATE_CONTIGUOUS_CONTAINER(
394
0
          unsafe_elements(), unsafe_elements() + total_size_,
395
0
          unsafe_elements() + old_size, unsafe_elements() + new_size);
396
0
      if (new_size < old_size) {
397
0
        ABSL_ANNOTATE_MEMORY_IS_UNINITIALIZED(
398
0
            unsafe_elements() + new_size,
399
0
            (old_size - new_size) * sizeof(Element));
400
0
      }
401
0
    }
402
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
403
404
  // Replaces current_size_ with new_size and returns the previous value of
405
  // current_size_. This function is intended to be the only place where
406
  // current_size_ is modified, with the exception of `AddInputIterator()`
407
  // where the size of added items is not known in advance.
408
0
  inline int ExchangeCurrentSize(int new_size) {
409
0
    const int prev_size = current_size_;
410
0
    AnnotateSize(prev_size, new_size);
411
0
    current_size_ = new_size;
412
0
    return prev_size;
413
0
  }
Unexecuted instantiation: google::protobuf::RepeatedField<unsigned int>::ExchangeCurrentSize(int)
Unexecuted instantiation: google::protobuf::RepeatedField<unsigned long>::ExchangeCurrentSize(int)
Unexecuted instantiation: google::protobuf::RepeatedField<int>::ExchangeCurrentSize(int)
Unexecuted instantiation: google::protobuf::RepeatedField<long>::ExchangeCurrentSize(int)
Unexecuted instantiation: google::protobuf::RepeatedField<float>::ExchangeCurrentSize(int)
Unexecuted instantiation: google::protobuf::RepeatedField<double>::ExchangeCurrentSize(int)
414
415
  // Pad the Rep after arena allow for power-of-two byte sizes when
416
  // sizeof(Element) > sizeof(Arena*). eg for 16-byte objects.
417
  static PROTOBUF_CONSTEXPR const size_t kRepHeaderSize =
418
      sizeof(Arena*) < sizeof(Element) ? sizeof(Element) : sizeof(Arena*);
419
  struct Rep {
420
    Arena* arena;
421
0
    Element* elements() {
422
0
      return reinterpret_cast<Element*>(reinterpret_cast<char*>(this) +
423
0
                                        kRepHeaderSize);
424
0
    }
Unexecuted instantiation: google::protobuf::RepeatedField<unsigned int>::Rep::elements()
Unexecuted instantiation: google::protobuf::RepeatedField<unsigned long>::Rep::elements()
Unexecuted instantiation: google::protobuf::RepeatedField<long>::Rep::elements()
Unexecuted instantiation: google::protobuf::RepeatedField<float>::Rep::elements()
Unexecuted instantiation: google::protobuf::RepeatedField<double>::Rep::elements()
Unexecuted instantiation: google::protobuf::RepeatedField<int>::Rep::elements()
425
  };
426
427
  // If total_size_ == 0 this points to an Arena otherwise it points to the
428
  // elements member of a Rep struct. Using this invariant allows the storage of
429
  // the arena pointer without an extra allocation in the constructor.
430
  void* arena_or_elements_;
431
432
  // Returns a pointer to elements array.
433
  // pre-condition: the array must have been allocated.
434
0
  Element* elements() const {
435
0
    ABSL_DCHECK_GT(total_size_, 0);
436
0
    // Because of above pre-condition this cast is safe.
437
0
    return unsafe_elements();
438
0
  }
Unexecuted instantiation: google::protobuf::RepeatedField<unsigned int>::elements() const
Unexecuted instantiation: google::protobuf::RepeatedField<unsigned long>::elements() const
Unexecuted instantiation: google::protobuf::RepeatedField<int>::elements() const
Unexecuted instantiation: google::protobuf::RepeatedField<long>::elements() const
Unexecuted instantiation: google::protobuf::RepeatedField<float>::elements() const
Unexecuted instantiation: google::protobuf::RepeatedField<double>::elements() const
439
440
  // Returns a pointer to elements array if it exists; otherwise either null or
441
  // an invalid pointer is returned. This only happens for empty repeated
442
  // fields, where you can't dereference this pointer anyway (it's empty).
443
0
  Element* unsafe_elements() const {
444
0
    return static_cast<Element*>(arena_or_elements_);
445
0
  }
Unexecuted instantiation: google::protobuf::RepeatedField<unsigned int>::unsafe_elements() const
Unexecuted instantiation: google::protobuf::RepeatedField<unsigned long>::unsafe_elements() const
Unexecuted instantiation: google::protobuf::RepeatedField<int>::unsafe_elements() const
Unexecuted instantiation: google::protobuf::RepeatedField<long>::unsafe_elements() const
Unexecuted instantiation: google::protobuf::RepeatedField<float>::unsafe_elements() const
Unexecuted instantiation: google::protobuf::RepeatedField<double>::unsafe_elements() const
Unexecuted instantiation: google::protobuf::RepeatedField<bool>::unsafe_elements() const
446
447
  // Returns a pointer to the Rep struct.
448
  // pre-condition: the Rep must have been allocated, ie elements() is safe.
449
0
  Rep* rep() const {
450
0
    return reinterpret_cast<Rep*>(reinterpret_cast<char*>(elements()) -
451
0
                                  kRepHeaderSize);
452
0
  }
Unexecuted instantiation: google::protobuf::RepeatedField<unsigned int>::rep() const
Unexecuted instantiation: google::protobuf::RepeatedField<unsigned long>::rep() const
Unexecuted instantiation: google::protobuf::RepeatedField<long>::rep() const
Unexecuted instantiation: google::protobuf::RepeatedField<float>::rep() const
Unexecuted instantiation: google::protobuf::RepeatedField<double>::rep() const
Unexecuted instantiation: google::protobuf::RepeatedField<int>::rep() const
453
454
  friend class Arena;
455
  typedef void InternalArenaConstructable_;
456
457
  // Destroys all elements in [begin, end).
458
  // This function does nothing if `Element` is trivial.
459
0
  static void Destroy(const Element* begin, const Element* end) {
460
0
    if (!std::is_trivial<Element>::value) {
461
0
      std::for_each(begin, end, [&](const Element& e) { e.~Element(); });
462
0
    }
463
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*)
464
465
  // Internal helper to delete all elements and deallocate the storage.
466
  template <bool in_destructor = false>
467
0
  void InternalDeallocate() {
468
0
    const size_t bytes = total_size_ * sizeof(Element) + kRepHeaderSize;
469
0
    if (rep()->arena == nullptr) {
470
0
      internal::SizedDelete(rep(), bytes);
471
0
    } else if (!in_destructor) {
472
0
      // If we are in the destructor, we might be being destroyed as part of
473
0
      // the arena teardown. We can't try and return blocks to the arena then.
474
0
      rep()->arena->ReturnArrayMemory(rep(), bytes);
475
0
    }
476
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>()
477
};
478
479
// implementation ====================================================
480
481
template <typename Element>
482
constexpr RepeatedField<Element>::RepeatedField()
483
    : current_size_(0), total_size_(0), arena_or_elements_(nullptr) {
484
  StaticValidityCheck();
485
}
486
487
template <typename Element>
488
inline RepeatedField<Element>::RepeatedField(Arena* arena)
489
    : current_size_(0), total_size_(0), arena_or_elements_(arena) {
490
  StaticValidityCheck();
491
}
492
493
template <typename Element>
494
inline RepeatedField<Element>::RepeatedField(const RepeatedField& rhs)
495
    : current_size_(0), total_size_(0), arena_or_elements_(nullptr) {
496
  StaticValidityCheck();
497
  if (size_t size = rhs.current_size_) {
498
    Grow(0, size);
499
    ExchangeCurrentSize(size);
500
    UninitializedCopyN(rhs.elements(), size, unsafe_elements());
501
  }
502
}
503
504
template <typename Element>
505
template <typename Iter, typename>
506
RepeatedField<Element>::RepeatedField(Iter begin, Iter end)
507
    : current_size_(0), total_size_(0), arena_or_elements_(nullptr) {
508
  StaticValidityCheck();
509
  Add(begin, end);
510
}
511
512
template <typename Element>
513
RepeatedField<Element>::~RepeatedField() {
514
  StaticValidityCheck();
515
#ifndef NDEBUG
516
  // Try to trigger segfault / asan failure in non-opt builds if arena_
517
  // lifetime has ended before the destructor.
518
  auto arena = GetOwningArena();
519
  if (arena) (void)arena->SpaceAllocated();
520
#endif
521
  if (total_size_ > 0) {
522
    Destroy(unsafe_elements(), unsafe_elements() + current_size_);
523
    InternalDeallocate<true>();
524
  }
525
}
526
527
template <typename Element>
528
inline RepeatedField<Element>& RepeatedField<Element>::operator=(
529
    const RepeatedField& other) {
530
  if (this != &other) CopyFrom(other);
531
  return *this;
532
}
533
534
template <typename Element>
535
inline RepeatedField<Element>::RepeatedField(RepeatedField&& other) noexcept
536
    : RepeatedField() {
537
#ifdef PROTOBUF_FORCE_COPY_IN_MOVE
538
  CopyFrom(other);
539
#else   // PROTOBUF_FORCE_COPY_IN_MOVE
540
  // We don't just call Swap(&other) here because it would perform 3 copies if
541
  // other is on an arena. This field can't be on an arena because arena
542
  // construction always uses the Arena* accepting constructor.
543
  if (other.GetOwningArena()) {
544
    CopyFrom(other);
545
  } else {
546
    InternalSwap(&other);
547
  }
548
#endif  // !PROTOBUF_FORCE_COPY_IN_MOVE
549
}
550
551
template <typename Element>
552
inline RepeatedField<Element>& RepeatedField<Element>::operator=(
553
    RepeatedField&& other) noexcept {
554
  // We don't just call Swap(&other) here because it would perform 3 copies if
555
  // the two fields are on different arenas.
556
  if (this != &other) {
557
    if (GetOwningArena() != other.GetOwningArena()
558
#ifdef PROTOBUF_FORCE_COPY_IN_MOVE
559
        || GetOwningArena() == nullptr
560
#endif  // !PROTOBUF_FORCE_COPY_IN_MOVE
561
    ) {
562
      CopyFrom(other);
563
    } else {
564
      InternalSwap(&other);
565
    }
566
  }
567
  return *this;
568
}
569
570
template <typename Element>
571
inline bool RepeatedField<Element>::empty() const {
572
  return current_size_ == 0;
573
}
574
575
template <typename Element>
576
0
inline int RepeatedField<Element>::size() const {
577
0
  return current_size_;
578
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<int>::size() const
579
580
template <typename Element>
581
0
inline int RepeatedField<Element>::Capacity() const {
582
0
  return total_size_;
583
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
584
585
template <typename Element>
586
0
inline void RepeatedField<Element>::AddAlreadyReserved(Element value) {
587
0
  ABSL_DCHECK_LT(current_size_, total_size_);
588
0
  void* p = elements() + ExchangeCurrentSize(current_size_ + 1);
589
0
  ::new (p) Element(std::move(value));
590
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)
591
592
template <typename Element>
593
inline Element* RepeatedField<Element>::AddAlreadyReserved() {
594
  ABSL_DCHECK_LT(current_size_, total_size_);
595
  // new (p) <TrivialType> compiles into nothing: this is intentional as this
596
  // function is documented to return uninitialized data for trivial types.
597
  void* p = elements() + ExchangeCurrentSize(current_size_ + 1);
598
  return ::new (p) Element;
599
}
600
601
template <typename Element>
602
inline Element* RepeatedField<Element>::AddNAlreadyReserved(int n) {
603
  ABSL_DCHECK_GE(total_size_ - current_size_, n)
604
      << total_size_ << ", " << current_size_;
605
  Element* p = unsafe_elements() + ExchangeCurrentSize(current_size_ + n);
606
  for (Element *begin = p, *end = p + n; begin != end; ++begin) {
607
    new (static_cast<void*>(begin)) Element;
608
  }
609
  return p;
610
}
611
612
template <typename Element>
613
0
inline void RepeatedField<Element>::Resize(int new_size, const Element& value) {
614
0
  ABSL_DCHECK_GE(new_size, 0);
615
0
  if (new_size > current_size_) {
616
0
    if (new_size > total_size_) Grow(current_size_, new_size);
617
0
    Element* first = elements() + ExchangeCurrentSize(new_size);
618
0
    std::uninitialized_fill(first, elements() + current_size_, value);
619
0
  } else if (new_size < current_size_) {
620
0
    Destroy(unsafe_elements() + new_size, unsafe_elements() + current_size_);
621
0
    ExchangeCurrentSize(new_size);
622
0
  }
623
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&)
624
625
template <typename Element>
626
0
inline const Element& RepeatedField<Element>::Get(int index) const {
627
0
  ABSL_DCHECK_GE(index, 0);
628
0
  ABSL_DCHECK_LT(index, current_size_);
629
0
  return elements()[index];
630
0
}
631
632
template <typename Element>
633
inline const Element& RepeatedField<Element>::at(int index) const {
634
  ABSL_CHECK_GE(index, 0);
635
  ABSL_CHECK_LT(index, current_size_);
636
  return elements()[index];
637
}
638
639
template <typename Element>
640
inline Element& RepeatedField<Element>::at(int index) {
641
  ABSL_CHECK_GE(index, 0);
642
  ABSL_CHECK_LT(index, current_size_);
643
  return elements()[index];
644
}
645
646
template <typename Element>
647
inline Element* RepeatedField<Element>::Mutable(int index) {
648
  ABSL_DCHECK_GE(index, 0);
649
  ABSL_DCHECK_LT(index, current_size_);
650
  return &elements()[index];
651
}
652
653
template <typename Element>
654
0
inline void RepeatedField<Element>::Set(int index, const Element& value) {
655
0
  ABSL_DCHECK_GE(index, 0);
656
0
  ABSL_DCHECK_LT(index, current_size_);
657
0
  elements()[index] = value;
658
0
}
659
660
template <typename Element>
661
0
inline void RepeatedField<Element>::Add(Element value) {
662
0
  int total_size = total_size_;
663
0
  Element* elem = unsafe_elements();
664
0
  if (ABSL_PREDICT_FALSE(current_size_ == total_size)) {
665
0
    Grow(current_size_, current_size_ + 1);
666
0
    total_size = total_size_;
667
0
    elem = unsafe_elements();
668
0
  }
669
0
  int new_size = current_size_ + 1;
670
0
  void* p = elem + ExchangeCurrentSize(new_size);
671
0
  ::new (p) Element(std::move(value));
672
0
673
0
  // The below helps the compiler optimize dense loops.
674
0
  ABSL_ASSUME(new_size == current_size_);
675
0
  ABSL_ASSUME(elem == arena_or_elements_);
676
0
  ABSL_ASSUME(total_size == total_size_);
677
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)
678
679
template <typename Element>
680
inline Element* RepeatedField<Element>::Add() {
681
  if (ABSL_PREDICT_FALSE(current_size_ == total_size_)) {
682
    Grow(current_size_, current_size_ + 1);
683
  }
684
  void* p = unsafe_elements() + ExchangeCurrentSize(current_size_ + 1);
685
  return ::new (p) Element;
686
}
687
688
template <typename Element>
689
template <typename Iter>
690
inline void RepeatedField<Element>::AddForwardIterator(Iter begin, Iter end) {
691
  int total_size = total_size_;
692
  Element* elem = unsafe_elements();
693
  int new_size = current_size_ + static_cast<int>(std::distance(begin, end));
694
  if (ABSL_PREDICT_FALSE(new_size > total_size)) {
695
    Grow(current_size_, new_size);
696
    elem = unsafe_elements();
697
    total_size = total_size_;
698
  }
699
  UninitializedCopy(begin, end, elem + ExchangeCurrentSize(new_size));
700
701
  // The below helps the compiler optimize dense loops.
702
  ABSL_ASSUME(new_size == current_size_);
703
  ABSL_ASSUME(elem == arena_or_elements_);
704
  ABSL_ASSUME(total_size == total_size_);
705
}
706
707
template <typename Element>
708
template <typename Iter>
709
inline void RepeatedField<Element>::AddInputIterator(Iter begin, Iter end) {
710
  Element* first = unsafe_elements() + current_size_;
711
  Element* last = unsafe_elements() + total_size_;
712
  AnnotateSize(current_size_, total_size_);
713
714
  while (begin != end) {
715
    if (ABSL_PREDICT_FALSE(first == last)) {
716
      int current_size = first - unsafe_elements();
717
      GrowNoAnnotate(current_size, current_size + 1);
718
      first = unsafe_elements() + current_size;
719
      last = unsafe_elements() + total_size_;
720
    }
721
    ::new (static_cast<void*>(first)) Element(*begin);
722
    ++begin;
723
    ++first;
724
  }
725
726
  current_size_ = first - unsafe_elements();
727
  AnnotateSize(total_size_, current_size_);
728
}
729
730
template <typename Element>
731
template <typename Iter>
732
inline void RepeatedField<Element>::Add(Iter begin, Iter end) {
733
  if (std::is_base_of<
734
          std::forward_iterator_tag,
735
          typename std::iterator_traits<Iter>::iterator_category>::value) {
736
    AddForwardIterator(begin, end);
737
  } else {
738
    AddInputIterator(begin, end);
739
  }
740
}
741
742
template <typename Element>
743
inline void RepeatedField<Element>::RemoveLast() {
744
  ABSL_DCHECK_GT(current_size_, 0);
745
  elements()[current_size_ - 1].~Element();
746
  ExchangeCurrentSize(current_size_ - 1);
747
}
748
749
template <typename Element>
750
void RepeatedField<Element>::ExtractSubrange(int start, int num,
751
                                             Element* elements) {
752
  ABSL_DCHECK_GE(start, 0);
753
  ABSL_DCHECK_GE(num, 0);
754
  ABSL_DCHECK_LE(start + num, this->current_size_);
755
756
  // Save the values of the removed elements if requested.
757
  if (elements != nullptr) {
758
    for (int i = 0; i < num; ++i) elements[i] = this->Get(i + start);
759
  }
760
761
  // Slide remaining elements down to fill the gap.
762
  if (num > 0) {
763
    for (int i = start + num; i < this->current_size_; ++i)
764
      this->Set(i - num, this->Get(i));
765
    this->Truncate(this->current_size_ - num);
766
  }
767
}
768
769
template <typename Element>
770
0
inline void RepeatedField<Element>::Clear() {
771
0
  Destroy(unsafe_elements(), unsafe_elements() + current_size_);
772
0
  ExchangeCurrentSize(0);
773
0
}
774
775
template <typename Element>
776
inline void RepeatedField<Element>::MergeFrom(const RepeatedField& rhs) {
777
  ABSL_DCHECK_NE(&rhs, this);
778
  if (size_t size = rhs.current_size_) {
779
    Reserve(current_size_ + size);
780
    Element* dst = elements() + ExchangeCurrentSize(current_size_ + size);
781
    UninitializedCopyN(rhs.elements(), size, dst);
782
  }
783
}
784
785
template <typename Element>
786
inline void RepeatedField<Element>::CopyFrom(const RepeatedField& other) {
787
  if (&other == this) return;
788
  Clear();
789
  MergeFrom(other);
790
}
791
792
template <typename Element>
793
template <typename Iter>
794
inline void RepeatedField<Element>::Assign(Iter begin, Iter end) {
795
  Clear();
796
  Add(begin, end);
797
}
798
799
template <typename Element>
800
inline typename RepeatedField<Element>::iterator RepeatedField<Element>::erase(
801
    const_iterator position) {
802
  return erase(position, position + 1);
803
}
804
805
template <typename Element>
806
inline typename RepeatedField<Element>::iterator RepeatedField<Element>::erase(
807
    const_iterator first, const_iterator last) {
808
  size_type first_offset = first - cbegin();
809
  if (first != last) {
810
    Truncate(std::copy(last, cend(), begin() + first_offset) - cbegin());
811
  }
812
  return begin() + first_offset;
813
}
814
815
template <typename Element>
816
0
inline Element* RepeatedField<Element>::mutable_data() {
817
0
  return unsafe_elements();
818
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()
819
820
template <typename Element>
821
0
inline const Element* RepeatedField<Element>::data() const {
822
0
  return unsafe_elements();
823
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
824
825
template <typename Element>
826
inline void RepeatedField<Element>::InternalSwap(RepeatedField* other) {
827
  ABSL_DCHECK(this != other);
828
829
  // Swap all fields at once.
830
  static_assert(std::is_standard_layout<RepeatedField<Element>>::value,
831
                "offsetof() requires standard layout before c++17");
832
  internal::memswap<offsetof(RepeatedField, arena_or_elements_) +
833
                    sizeof(this->arena_or_elements_) -
834
                    offsetof(RepeatedField, current_size_)>(
835
      reinterpret_cast<char*>(this) + offsetof(RepeatedField, current_size_),
836
      reinterpret_cast<char*>(other) + offsetof(RepeatedField, current_size_));
837
}
838
839
template <typename Element>
840
void RepeatedField<Element>::Swap(RepeatedField* other) {
841
  if (this == other) return;
842
#ifdef PROTOBUF_FORCE_COPY_IN_SWAP
843
  if (GetOwningArena() != nullptr &&
844
      GetOwningArena() == other->GetOwningArena()) {
845
#else   // PROTOBUF_FORCE_COPY_IN_SWAP
846
  if (GetOwningArena() == other->GetOwningArena()) {
847
#endif  // !PROTOBUF_FORCE_COPY_IN_SWAP
848
    InternalSwap(other);
849
  } else {
850
    RepeatedField<Element> temp(other->GetOwningArena());
851
    temp.MergeFrom(*this);
852
    CopyFrom(*other);
853
    other->UnsafeArenaSwap(&temp);
854
  }
855
}
856
857
template <typename Element>
858
void RepeatedField<Element>::UnsafeArenaSwap(RepeatedField* other) {
859
  if (this == other) return;
860
  ABSL_DCHECK_EQ(GetOwningArena(), other->GetOwningArena());
861
  InternalSwap(other);
862
}
863
864
template <typename Element>
865
void RepeatedField<Element>::SwapElements(int index1, int index2) {
866
  using std::swap;  // enable ADL with fallback
867
  swap(elements()[index1], elements()[index2]);
868
}
869
870
template <typename Element>
871
inline typename RepeatedField<Element>::iterator
872
RepeatedField<Element>::begin() {
873
  return iterator(unsafe_elements());
874
}
875
template <typename Element>
876
inline typename RepeatedField<Element>::const_iterator
877
RepeatedField<Element>::begin() const {
878
  return const_iterator(unsafe_elements());
879
}
880
template <typename Element>
881
inline typename RepeatedField<Element>::const_iterator
882
RepeatedField<Element>::cbegin() const {
883
  return const_iterator(unsafe_elements());
884
}
885
template <typename Element>
886
inline typename RepeatedField<Element>::iterator RepeatedField<Element>::end() {
887
  return iterator(unsafe_elements() + current_size_);
888
}
889
template <typename Element>
890
inline typename RepeatedField<Element>::const_iterator
891
RepeatedField<Element>::end() const {
892
  return const_iterator(unsafe_elements() + current_size_);
893
}
894
template <typename Element>
895
inline typename RepeatedField<Element>::const_iterator
896
RepeatedField<Element>::cend() const {
897
  return const_iterator(unsafe_elements() + current_size_);
898
}
899
900
template <typename Element>
901
inline size_t RepeatedField<Element>::SpaceUsedExcludingSelfLong() const {
902
  return total_size_ > 0 ? (total_size_ * sizeof(Element) + kRepHeaderSize) : 0;
903
}
904
905
namespace internal {
906
// Returns the new size for a reserved field based on its 'total_size' and the
907
// requested 'new_size'. The result is clamped to the closed interval:
908
//   [internal::kMinRepeatedFieldAllocationSize,
909
//    std::numeric_limits<int>::max()]
910
// Requires:
911
//     new_size > total_size &&
912
//     (total_size == 0 ||
913
//      total_size >= kRepeatedFieldLowerClampLimit)
914
template <typename T, int kRepHeaderSize>
915
0
inline int CalculateReserveSize(int total_size, int new_size) {
916
0
  constexpr int lower_limit = RepeatedFieldLowerClampLimit<T, kRepHeaderSize>();
917
0
  if (new_size < lower_limit) {
918
0
    // Clamp to smallest allowed size.
919
0
    return lower_limit;
920
0
  }
921
0
  constexpr int kMaxSizeBeforeClamp =
922
0
      (std::numeric_limits<int>::max() - kRepHeaderSize) / 2;
923
0
  if (PROTOBUF_PREDICT_FALSE(total_size > kMaxSizeBeforeClamp)) {
924
0
    return std::numeric_limits<int>::max();
925
0
  }
926
0
  // We want to double the number of bytes, not the number of elements, to try
927
0
  // to stay within power-of-two allocations.
928
0
  // The allocation has kRepHeaderSize + sizeof(T) * capacity.
929
0
  int doubled_size = 2 * total_size + kRepHeaderSize / sizeof(T);
930
0
  return std::max(doubled_size, new_size);
931
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)
932
}  // namespace internal
933
934
template <typename Element>
935
void RepeatedField<Element>::Reserve(int new_size) {
936
  if (ABSL_PREDICT_FALSE(new_size > total_size_)) {
937
    Grow(current_size_, new_size);
938
  }
939
}
940
941
// Avoid inlining of Reserve(): new, copy, and delete[] lead to a significant
942
// amount of code bloat.
943
template <typename Element>
944
PROTOBUF_NOINLINE void RepeatedField<Element>::GrowNoAnnotate(int current_size,
945
0
                                                              int new_size) {
946
0
  ABSL_DCHECK_GT(new_size, total_size_);
947
0
  Rep* new_rep;
948
0
  Arena* arena = GetOwningArena();
949
0
950
0
  new_size = internal::CalculateReserveSize<Element, kRepHeaderSize>(
951
0
      total_size_, new_size);
952
0
953
0
  ABSL_DCHECK_LE(
954
0
      static_cast<size_t>(new_size),
955
0
      (std::numeric_limits<size_t>::max() - kRepHeaderSize) / sizeof(Element))
956
0
      << "Requested size is too large to fit into size_t.";
957
0
  size_t bytes =
958
0
      kRepHeaderSize + sizeof(Element) * static_cast<size_t>(new_size);
959
0
  if (arena == nullptr) {
960
0
    ABSL_DCHECK_LE((bytes - kRepHeaderSize) / sizeof(Element),
961
0
                   static_cast<size_t>(std::numeric_limits<int>::max()))
962
0
        << "Requested size is too large to fit element count into int.";
963
0
    internal::SizedPtr res = internal::AllocateAtLeast(bytes);
964
0
    size_t num_available =
965
0
        std::min((res.n - kRepHeaderSize) / sizeof(Element),
966
0
                 static_cast<size_t>(std::numeric_limits<int>::max()));
967
0
    new_size = static_cast<int>(num_available);
968
0
    new_rep = static_cast<Rep*>(res.p);
969
0
  } else {
970
0
    new_rep = reinterpret_cast<Rep*>(Arena::CreateArray<char>(arena, bytes));
971
0
  }
972
0
  new_rep->arena = arena;
973
0
974
0
  if (total_size_ > 0) {
975
0
    if (current_size > 0) {
976
0
      Element* pnew = new_rep->elements();
977
0
      Element* pold = elements();
978
0
      // TODO(b/263791665): add absl::is_trivially_relocatable<Element>
979
0
      if (std::is_trivial<Element>::value) {
980
0
        memcpy(pnew, pold, current_size * sizeof(Element));
981
0
      } else {
982
0
        for (Element* end = pnew + current_size; pnew != end; ++pnew, ++pold) {
983
0
          ::new (static_cast<void*>(pnew)) Element(std::move(*pold));
984
0
          pold->~Element();
985
0
        }
986
0
      }
987
0
    }
988
0
    InternalDeallocate();
989
0
  }
990
0
991
0
  total_size_ = new_size;
992
0
  arena_or_elements_ = new_rep->elements();
993
0
}
Unexecuted instantiation: google::protobuf::RepeatedField<unsigned int>::GrowNoAnnotate(int, int)
Unexecuted instantiation: google::protobuf::RepeatedField<unsigned long>::GrowNoAnnotate(int, int)
Unexecuted instantiation: google::protobuf::RepeatedField<long>::GrowNoAnnotate(int, int)
Unexecuted instantiation: google::protobuf::RepeatedField<float>::GrowNoAnnotate(int, int)
Unexecuted instantiation: google::protobuf::RepeatedField<double>::GrowNoAnnotate(int, int)
Unexecuted instantiation: google::protobuf::RepeatedField<int>::GrowNoAnnotate(int, int)
994
995
// TODO(b/266411038): we should really be able to make this:
996
// template <bool annotate_size = true>
997
// void Grow();
998
template <typename Element>
999
PROTOBUF_NOINLINE void RepeatedField<Element>::Grow(int current_size,
1000
0
                                                    int new_size) {
1001
0
  AnnotateSize(current_size, total_size_);
1002
0
  GrowNoAnnotate(current_size, new_size);
1003
0
  AnnotateSize(total_size_, current_size);
1004
0
}
Unexecuted instantiation: google::protobuf::RepeatedField<unsigned int>::Grow(int, int)
Unexecuted instantiation: google::protobuf::RepeatedField<unsigned long>::Grow(int, int)
Unexecuted instantiation: google::protobuf::RepeatedField<long>::Grow(int, int)
Unexecuted instantiation: google::protobuf::RepeatedField<float>::Grow(int, int)
Unexecuted instantiation: google::protobuf::RepeatedField<double>::Grow(int, int)
Unexecuted instantiation: google::protobuf::RepeatedField<int>::Grow(int, int)
1005
1006
template <typename Element>
1007
0
inline void RepeatedField<Element>::Truncate(int new_size) {
1008
0
  ABSL_DCHECK_LE(new_size, current_size_);
1009
0
  if (new_size < current_size_) {
1010
0
    Destroy(unsafe_elements() + new_size, unsafe_elements() + current_size_);
1011
0
    ExchangeCurrentSize(new_size);
1012
0
  }
1013
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)
1014
1015
template <>
1016
PROTOBUF_EXPORT size_t
1017
RepeatedField<absl::Cord>::SpaceUsedExcludingSelfLong() const;
1018
1019
1020
// -------------------------------------------------------------------
1021
1022
// Iterators and helper functions that follow the spirit of the STL
1023
// std::back_insert_iterator and std::back_inserter but are tailor-made
1024
// for RepeatedField and RepeatedPtrField. Typical usage would be:
1025
//
1026
//   std::copy(some_sequence.begin(), some_sequence.end(),
1027
//             RepeatedFieldBackInserter(proto.mutable_sequence()));
1028
//
1029
// Ported by johannes from util/gtl/proto-array-iterators.h
1030
1031
namespace internal {
1032
1033
// STL-like iterator implementation for RepeatedField.  You should not
1034
// refer to this class directly; use RepeatedField<T>::iterator instead.
1035
//
1036
// Note: All of the iterator operators *must* be inlined to avoid performance
1037
// regressions.  This is caused by the extern template declarations below (which
1038
// are required because of the RepeatedField extern template declarations).  If
1039
// any of these functions aren't explicitly inlined (e.g. defined in the class),
1040
// the compiler isn't allowed to inline them.
1041
template <typename Element>
1042
class RepeatedIterator {
1043
 public:
1044
  using iterator_category = std::random_access_iterator_tag;
1045
  // Note: remove_const is necessary for std::partial_sum, which uses value_type
1046
  // to determine the summation variable type.
1047
  using value_type = typename std::remove_const<Element>::type;
1048
  using difference_type = std::ptrdiff_t;
1049
  using pointer = Element*;
1050
  using reference = Element&;
1051
1052
  constexpr RepeatedIterator() noexcept : it_(nullptr) {}
1053
1054
  // Allows "upcasting" from RepeatedIterator<T**> to
1055
  // RepeatedIterator<const T*const*>.
1056
  template <typename OtherElement,
1057
            typename std::enable_if<std::is_convertible<
1058
                OtherElement*, pointer>::value>::type* = nullptr>
1059
  constexpr RepeatedIterator(
1060
      const RepeatedIterator<OtherElement>& other) noexcept
1061
      : it_(other.it_) {}
1062
1063
  // dereferenceable
1064
  constexpr reference operator*() const noexcept { return *it_; }
1065
  constexpr pointer operator->() const noexcept { return it_; }
1066
1067
 private:
1068
  // Helper alias to hide the internal type.
1069
  using iterator = RepeatedIterator<Element>;
1070
1071
 public:
1072
  // {inc,dec}rementable
1073
  iterator& operator++() noexcept {
1074
    ++it_;
1075
    return *this;
1076
  }
1077
  iterator operator++(int) noexcept { return iterator(it_++); }
1078
  iterator& operator--() noexcept {
1079
    --it_;
1080
    return *this;
1081
  }
1082
  iterator operator--(int) noexcept { return iterator(it_--); }
1083
1084
  // equality_comparable
1085
  friend constexpr bool operator==(const iterator& x,
1086
                                   const iterator& y) noexcept {
1087
    return x.it_ == y.it_;
1088
  }
1089
  friend constexpr bool operator!=(const iterator& x,
1090
                                   const iterator& y) noexcept {
1091
    return x.it_ != y.it_;
1092
  }
1093
1094
  // less_than_comparable
1095
  friend constexpr bool operator<(const iterator& x,
1096
                                  const iterator& y) noexcept {
1097
    return x.it_ < y.it_;
1098
  }
1099
  friend constexpr bool operator<=(const iterator& x,
1100
                                   const iterator& y) noexcept {
1101
    return x.it_ <= y.it_;
1102
  }
1103
  friend constexpr bool operator>(const iterator& x,
1104
                                  const iterator& y) noexcept {
1105
    return x.it_ > y.it_;
1106
  }
1107
  friend constexpr bool operator>=(const iterator& x,
1108
                                   const iterator& y) noexcept {
1109
    return x.it_ >= y.it_;
1110
  }
1111
1112
  // addable, subtractable
1113
  iterator& operator+=(difference_type d) noexcept {
1114
    it_ += d;
1115
    return *this;
1116
  }
1117
  constexpr iterator operator+(difference_type d) const noexcept {
1118
    return iterator(it_ + d);
1119
  }
1120
  friend constexpr iterator operator+(const difference_type d,
1121
                                      iterator it) noexcept {
1122
    return it + d;
1123
  }
1124
1125
  iterator& operator-=(difference_type d) noexcept {
1126
    it_ -= d;
1127
    return *this;
1128
  }
1129
  iterator constexpr operator-(difference_type d) const noexcept {
1130
    return iterator(it_ - d);
1131
  }
1132
1133
  // indexable
1134
  constexpr reference operator[](difference_type d) const noexcept {
1135
    return it_[d];
1136
  }
1137
1138
  // random access iterator
1139
  friend constexpr difference_type operator-(iterator it1,
1140
                                             iterator it2) noexcept {
1141
    return it1.it_ - it2.it_;
1142
  }
1143
1144
 private:
1145
  template <typename OtherElement>
1146
  friend class RepeatedIterator;
1147
1148
  // Allow construction from RepeatedField.
1149
  friend class RepeatedField<value_type>;
1150
  explicit RepeatedIterator(Element* it) noexcept : it_(it) {}
1151
1152
  // The internal iterator.
1153
  Element* it_;
1154
};
1155
1156
// A back inserter for RepeatedField objects.
1157
template <typename T>
1158
class RepeatedFieldBackInsertIterator {
1159
 public:
1160
  using iterator_category = std::output_iterator_tag;
1161
  using value_type = T;
1162
  using pointer = void;
1163
  using reference = void;
1164
  using difference_type = std::ptrdiff_t;
1165
1166
  explicit RepeatedFieldBackInsertIterator(
1167
      RepeatedField<T>* const mutable_field)
1168
      : field_(mutable_field) {}
1169
  RepeatedFieldBackInsertIterator<T>& operator=(const T& value) {
1170
    field_->Add(value);
1171
    return *this;
1172
  }
1173
  RepeatedFieldBackInsertIterator<T>& operator*() { return *this; }
1174
  RepeatedFieldBackInsertIterator<T>& operator++() { return *this; }
1175
  RepeatedFieldBackInsertIterator<T>& operator++(int /* unused */) {
1176
    return *this;
1177
  }
1178
1179
 private:
1180
  RepeatedField<T>* field_;
1181
};
1182
1183
}  // namespace internal
1184
1185
// Provides a back insert iterator for RepeatedField instances,
1186
// similar to std::back_inserter().
1187
template <typename T>
1188
internal::RepeatedFieldBackInsertIterator<T> RepeatedFieldBackInserter(
1189
    RepeatedField<T>* const mutable_field) {
1190
  return internal::RepeatedFieldBackInsertIterator<T>(mutable_field);
1191
}
1192
1193
1194
}  // namespace protobuf
1195
}  // namespace google
1196
1197
#include "google/protobuf/port_undef.inc"
1198
1199
#endif  // GOOGLE_PROTOBUF_REPEATED_FIELD_H__