/src/LPM/external.protobuf/include/google/protobuf/repeated_ptr_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 RepeatedPtrField. |
43 | | |
44 | | #ifndef GOOGLE_PROTOBUF_REPEATED_PTR_FIELD_H__ |
45 | | #define GOOGLE_PROTOBUF_REPEATED_PTR_FIELD_H__ |
46 | | |
47 | | #include <utility> |
48 | | |
49 | | #ifdef _MSC_VER |
50 | | // This is required for min/max on VS2013 only. |
51 | | #include <algorithm> |
52 | | #endif |
53 | | |
54 | | #include <iterator> |
55 | | #include <limits> |
56 | | #include <string> |
57 | | #include <type_traits> |
58 | | |
59 | | #include "google/protobuf/arena.h" |
60 | | #include "google/protobuf/port.h" |
61 | | #include "absl/log/absl_check.h" |
62 | | #include "google/protobuf/message_lite.h" |
63 | | #include "google/protobuf/port.h" |
64 | | |
65 | | |
66 | | // Must be included last. |
67 | | #include "google/protobuf/port_def.inc" |
68 | | |
69 | | #ifdef SWIG |
70 | | #error "You cannot SWIG proto headers" |
71 | | #endif |
72 | | |
73 | | namespace google { |
74 | | namespace protobuf { |
75 | | |
76 | | class Message; |
77 | | class Reflection; |
78 | | |
79 | | template <typename T> |
80 | | struct WeakRepeatedPtrField; |
81 | | |
82 | | namespace internal { |
83 | | |
84 | | class MergePartialFromCodedStreamHelper; |
85 | | class SwapFieldHelper; |
86 | | |
87 | | |
88 | | } // namespace internal |
89 | | |
90 | | namespace internal { |
91 | | template <typename It> |
92 | | class RepeatedPtrIterator; |
93 | | template <typename It, typename VoidPtr> |
94 | | class RepeatedPtrOverPtrsIterator; |
95 | | } // namespace internal |
96 | | |
97 | | namespace internal { |
98 | | |
99 | | // type-traits helper for RepeatedPtrFieldBase: we only want to invoke |
100 | | // arena-related "copy if on different arena" behavior if the necessary methods |
101 | | // exist on the contained type. In particular, we rely on MergeFrom() existing |
102 | | // as a general proxy for the fact that a copy will work, and we also provide a |
103 | | // specific override for std::string*. |
104 | | template <typename T> |
105 | | struct TypeImplementsMergeBehaviorProbeForMergeFrom { |
106 | | typedef char HasMerge; |
107 | | typedef long HasNoMerge; |
108 | | |
109 | | // We accept either of: |
110 | | // - void MergeFrom(const T& other) |
111 | | // - bool MergeFrom(const T& other) |
112 | | // |
113 | | // We mangle these names a bit to avoid compatibility issues in 'unclean' |
114 | | // include environments that may have, e.g., "#define test ..." (yes, this |
115 | | // exists). |
116 | | template <typename U, typename RetType, RetType (U::*)(const U& arg)> |
117 | | struct CheckType; |
118 | | template <typename U> |
119 | | static HasMerge Check(CheckType<U, void, &U::MergeFrom>*); |
120 | | template <typename U> |
121 | | static HasMerge Check(CheckType<U, bool, &U::MergeFrom>*); |
122 | | template <typename U> |
123 | | static HasNoMerge Check(...); |
124 | | |
125 | | // Resolves to either std::true_type or std::false_type. |
126 | | typedef std::integral_constant<bool, |
127 | | (sizeof(Check<T>(0)) == sizeof(HasMerge))> |
128 | | type; |
129 | | }; |
130 | | |
131 | | template <typename T, typename = void> |
132 | | struct TypeImplementsMergeBehavior |
133 | | : TypeImplementsMergeBehaviorProbeForMergeFrom<T> {}; |
134 | | |
135 | | |
136 | | template <> |
137 | | struct TypeImplementsMergeBehavior<std::string> { |
138 | | typedef std::true_type type; |
139 | | }; |
140 | | |
141 | | template <typename T> |
142 | | struct IsMovable |
143 | | : std::integral_constant<bool, std::is_move_constructible<T>::value && |
144 | | std::is_move_assignable<T>::value> {}; |
145 | | |
146 | | // This is the common base class for RepeatedPtrFields. It deals only in void* |
147 | | // pointers. Users should not use this interface directly. |
148 | | // |
149 | | // The methods of this interface correspond to the methods of RepeatedPtrField, |
150 | | // but may have a template argument called TypeHandler. Its signature is: |
151 | | // class TypeHandler { |
152 | | // public: |
153 | | // typedef MyType Type; |
154 | | // static Type* New(); |
155 | | // static Type* NewFromPrototype(const Type* prototype, |
156 | | // Arena* arena); |
157 | | // static void Delete(Type*); |
158 | | // static void Clear(Type*); |
159 | | // static void Merge(const Type& from, Type* to); |
160 | | // |
161 | | // // Only needs to be implemented if SpaceUsedExcludingSelf() is called. |
162 | | // static int SpaceUsedLong(const Type&); |
163 | | // }; |
164 | | class PROTOBUF_EXPORT RepeatedPtrFieldBase { |
165 | | protected: |
166 | | constexpr RepeatedPtrFieldBase() |
167 | 0 | : arena_(nullptr), current_size_(0), total_size_(0), rep_(nullptr) {} |
168 | | explicit RepeatedPtrFieldBase(Arena* arena) |
169 | 6.85k | : arena_(arena), current_size_(0), total_size_(0), rep_(nullptr) {} |
170 | | |
171 | | RepeatedPtrFieldBase(const RepeatedPtrFieldBase&) = delete; |
172 | | RepeatedPtrFieldBase& operator=(const RepeatedPtrFieldBase&) = delete; |
173 | | |
174 | 6.85k | ~RepeatedPtrFieldBase() { |
175 | | #ifndef NDEBUG |
176 | | // Try to trigger segfault / asan failure in non-opt builds. If arena_ |
177 | | // lifetime has ended before the destructor. |
178 | | if (arena_) (void)arena_->SpaceAllocated(); |
179 | | #endif |
180 | 6.85k | } |
181 | | |
182 | 0 | bool empty() const { return current_size_ == 0; } |
183 | 5.49k | int size() const { return current_size_; } |
184 | 0 | int Capacity() const { return total_size_; } |
185 | | |
186 | | template <typename TypeHandler> |
187 | | const typename TypeHandler::Type& at(int index) const { |
188 | | ABSL_CHECK_GE(index, 0); |
189 | | ABSL_CHECK_LT(index, current_size_); |
190 | | return *cast<TypeHandler>(rep_->elements[index]); |
191 | | } |
192 | | |
193 | | template <typename TypeHandler> |
194 | | typename TypeHandler::Type& at(int index) { |
195 | | ABSL_CHECK_GE(index, 0); |
196 | | ABSL_CHECK_LT(index, current_size_); |
197 | | return *cast<TypeHandler>(rep_->elements[index]); |
198 | | } |
199 | | |
200 | | template <typename TypeHandler> |
201 | 0 | typename TypeHandler::Type* Mutable(int index) { |
202 | 0 | ABSL_DCHECK_GE(index, 0); |
203 | 0 | ABSL_DCHECK_LT(index, current_size_); |
204 | 0 | return cast<TypeHandler>(rep_->elements[index]); |
205 | 0 | } Unexecuted instantiation: google::protobuf::RepeatedPtrField<google::protobuf::FileDescriptorProto>::TypeHandler::Type* google::protobuf::internal::RepeatedPtrFieldBase::Mutable<google::protobuf::RepeatedPtrField<google::protobuf::FileDescriptorProto>::TypeHandler>(int) Unexecuted instantiation: google::protobuf::RepeatedPtrField<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >::TypeHandler::Type* google::protobuf::internal::RepeatedPtrFieldBase::Mutable<google::protobuf::RepeatedPtrField<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >::TypeHandler>(int) Unexecuted instantiation: google::protobuf::RepeatedPtrField<google::protobuf::DescriptorProto>::TypeHandler::Type* google::protobuf::internal::RepeatedPtrFieldBase::Mutable<google::protobuf::RepeatedPtrField<google::protobuf::DescriptorProto>::TypeHandler>(int) Unexecuted instantiation: google::protobuf::RepeatedPtrField<google::protobuf::EnumDescriptorProto>::TypeHandler::Type* google::protobuf::internal::RepeatedPtrFieldBase::Mutable<google::protobuf::RepeatedPtrField<google::protobuf::EnumDescriptorProto>::TypeHandler>(int) Unexecuted instantiation: google::protobuf::RepeatedPtrField<google::protobuf::ServiceDescriptorProto>::TypeHandler::Type* google::protobuf::internal::RepeatedPtrFieldBase::Mutable<google::protobuf::RepeatedPtrField<google::protobuf::ServiceDescriptorProto>::TypeHandler>(int) Unexecuted instantiation: google::protobuf::RepeatedPtrField<google::protobuf::FieldDescriptorProto>::TypeHandler::Type* google::protobuf::internal::RepeatedPtrFieldBase::Mutable<google::protobuf::RepeatedPtrField<google::protobuf::FieldDescriptorProto>::TypeHandler>(int) Unexecuted instantiation: google::protobuf::RepeatedPtrField<google::protobuf::DescriptorProto_ExtensionRange>::TypeHandler::Type* google::protobuf::internal::RepeatedPtrFieldBase::Mutable<google::protobuf::RepeatedPtrField<google::protobuf::DescriptorProto_ExtensionRange>::TypeHandler>(int) Unexecuted instantiation: google::protobuf::RepeatedPtrField<google::protobuf::OneofDescriptorProto>::TypeHandler::Type* google::protobuf::internal::RepeatedPtrFieldBase::Mutable<google::protobuf::RepeatedPtrField<google::protobuf::OneofDescriptorProto>::TypeHandler>(int) Unexecuted instantiation: google::protobuf::RepeatedPtrField<google::protobuf::DescriptorProto_ReservedRange>::TypeHandler::Type* google::protobuf::internal::RepeatedPtrFieldBase::Mutable<google::protobuf::RepeatedPtrField<google::protobuf::DescriptorProto_ReservedRange>::TypeHandler>(int) Unexecuted instantiation: google::protobuf::RepeatedPtrField<google::protobuf::UninterpretedOption>::TypeHandler::Type* google::protobuf::internal::RepeatedPtrFieldBase::Mutable<google::protobuf::RepeatedPtrField<google::protobuf::UninterpretedOption>::TypeHandler>(int) Unexecuted instantiation: google::protobuf::RepeatedPtrField<google::protobuf::EnumValueDescriptorProto>::TypeHandler::Type* google::protobuf::internal::RepeatedPtrFieldBase::Mutable<google::protobuf::RepeatedPtrField<google::protobuf::EnumValueDescriptorProto>::TypeHandler>(int) Unexecuted instantiation: google::protobuf::RepeatedPtrField<google::protobuf::EnumDescriptorProto_EnumReservedRange>::TypeHandler::Type* google::protobuf::internal::RepeatedPtrFieldBase::Mutable<google::protobuf::RepeatedPtrField<google::protobuf::EnumDescriptorProto_EnumReservedRange>::TypeHandler>(int) Unexecuted instantiation: google::protobuf::RepeatedPtrField<google::protobuf::MethodDescriptorProto>::TypeHandler::Type* google::protobuf::internal::RepeatedPtrFieldBase::Mutable<google::protobuf::RepeatedPtrField<google::protobuf::MethodDescriptorProto>::TypeHandler>(int) Unexecuted instantiation: google::protobuf::RepeatedPtrField<google::protobuf::UninterpretedOption_NamePart>::TypeHandler::Type* google::protobuf::internal::RepeatedPtrFieldBase::Mutable<google::protobuf::RepeatedPtrField<google::protobuf::UninterpretedOption_NamePart>::TypeHandler>(int) Unexecuted instantiation: google::protobuf::RepeatedPtrField<google::protobuf::SourceCodeInfo_Location>::TypeHandler::Type* google::protobuf::internal::RepeatedPtrFieldBase::Mutable<google::protobuf::RepeatedPtrField<google::protobuf::SourceCodeInfo_Location>::TypeHandler>(int) Unexecuted instantiation: google::protobuf::RepeatedPtrField<google::protobuf::GeneratedCodeInfo_Annotation>::TypeHandler::Type* google::protobuf::internal::RepeatedPtrFieldBase::Mutable<google::protobuf::RepeatedPtrField<google::protobuf::GeneratedCodeInfo_Annotation>::TypeHandler>(int) Unexecuted instantiation: google::protobuf::RepeatedPtrField<gifProtoFuzzer::SubBlock>::TypeHandler::Type* google::protobuf::internal::RepeatedPtrFieldBase::Mutable<google::protobuf::RepeatedPtrField<gifProtoFuzzer::SubBlock>::TypeHandler>(int) Unexecuted instantiation: google::protobuf::RepeatedPtrField<gifProtoFuzzer::ImageChunk>::TypeHandler::Type* google::protobuf::internal::RepeatedPtrFieldBase::Mutable<google::protobuf::RepeatedPtrField<gifProtoFuzzer::ImageChunk>::TypeHandler>(int) |
206 | | |
207 | | template <typename TypeHandler> |
208 | | typename TypeHandler::Type* Add( |
209 | 0 | const typename TypeHandler::Type* prototype = nullptr) { |
210 | 0 | if (rep_ != nullptr && current_size_ < rep_->allocated_size) { |
211 | 0 | return cast<TypeHandler>( |
212 | 0 | rep_->elements[ExchangeCurrentSize(current_size_ + 1)]); |
213 | 0 | } |
214 | 0 | typename TypeHandler::Type* result = |
215 | 0 | TypeHandler::NewFromPrototype(prototype, arena_); |
216 | 0 | return reinterpret_cast<typename TypeHandler::Type*>( |
217 | 0 | AddOutOfLineHelper(result)); |
218 | 0 | } Unexecuted instantiation: google::protobuf::RepeatedPtrField<google::protobuf::FileDescriptorProto>::TypeHandler::Type* google::protobuf::internal::RepeatedPtrFieldBase::Add<google::protobuf::RepeatedPtrField<google::protobuf::FileDescriptorProto>::TypeHandler>(google::protobuf::RepeatedPtrField<google::protobuf::FileDescriptorProto>::TypeHandler::Type const*) Unexecuted instantiation: google::protobuf::RepeatedPtrField<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >::TypeHandler::Type* google::protobuf::internal::RepeatedPtrFieldBase::Add<google::protobuf::RepeatedPtrField<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >::TypeHandler>(google::protobuf::RepeatedPtrField<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >::TypeHandler::Type const*) Unexecuted instantiation: google::protobuf::RepeatedPtrField<google::protobuf::DescriptorProto>::TypeHandler::Type* google::protobuf::internal::RepeatedPtrFieldBase::Add<google::protobuf::RepeatedPtrField<google::protobuf::DescriptorProto>::TypeHandler>(google::protobuf::RepeatedPtrField<google::protobuf::DescriptorProto>::TypeHandler::Type const*) Unexecuted instantiation: google::protobuf::RepeatedPtrField<google::protobuf::EnumDescriptorProto>::TypeHandler::Type* google::protobuf::internal::RepeatedPtrFieldBase::Add<google::protobuf::RepeatedPtrField<google::protobuf::EnumDescriptorProto>::TypeHandler>(google::protobuf::RepeatedPtrField<google::protobuf::EnumDescriptorProto>::TypeHandler::Type const*) Unexecuted instantiation: google::protobuf::RepeatedPtrField<google::protobuf::ServiceDescriptorProto>::TypeHandler::Type* google::protobuf::internal::RepeatedPtrFieldBase::Add<google::protobuf::RepeatedPtrField<google::protobuf::ServiceDescriptorProto>::TypeHandler>(google::protobuf::RepeatedPtrField<google::protobuf::ServiceDescriptorProto>::TypeHandler::Type const*) Unexecuted instantiation: google::protobuf::RepeatedPtrField<google::protobuf::FieldDescriptorProto>::TypeHandler::Type* google::protobuf::internal::RepeatedPtrFieldBase::Add<google::protobuf::RepeatedPtrField<google::protobuf::FieldDescriptorProto>::TypeHandler>(google::protobuf::RepeatedPtrField<google::protobuf::FieldDescriptorProto>::TypeHandler::Type const*) Unexecuted instantiation: google::protobuf::RepeatedPtrField<google::protobuf::DescriptorProto_ExtensionRange>::TypeHandler::Type* google::protobuf::internal::RepeatedPtrFieldBase::Add<google::protobuf::RepeatedPtrField<google::protobuf::DescriptorProto_ExtensionRange>::TypeHandler>(google::protobuf::RepeatedPtrField<google::protobuf::DescriptorProto_ExtensionRange>::TypeHandler::Type const*) Unexecuted instantiation: google::protobuf::RepeatedPtrField<google::protobuf::OneofDescriptorProto>::TypeHandler::Type* google::protobuf::internal::RepeatedPtrFieldBase::Add<google::protobuf::RepeatedPtrField<google::protobuf::OneofDescriptorProto>::TypeHandler>(google::protobuf::RepeatedPtrField<google::protobuf::OneofDescriptorProto>::TypeHandler::Type const*) Unexecuted instantiation: google::protobuf::RepeatedPtrField<google::protobuf::DescriptorProto_ReservedRange>::TypeHandler::Type* google::protobuf::internal::RepeatedPtrFieldBase::Add<google::protobuf::RepeatedPtrField<google::protobuf::DescriptorProto_ReservedRange>::TypeHandler>(google::protobuf::RepeatedPtrField<google::protobuf::DescriptorProto_ReservedRange>::TypeHandler::Type const*) Unexecuted instantiation: google::protobuf::RepeatedPtrField<google::protobuf::UninterpretedOption>::TypeHandler::Type* google::protobuf::internal::RepeatedPtrFieldBase::Add<google::protobuf::RepeatedPtrField<google::protobuf::UninterpretedOption>::TypeHandler>(google::protobuf::RepeatedPtrField<google::protobuf::UninterpretedOption>::TypeHandler::Type const*) Unexecuted instantiation: google::protobuf::RepeatedPtrField<google::protobuf::EnumValueDescriptorProto>::TypeHandler::Type* google::protobuf::internal::RepeatedPtrFieldBase::Add<google::protobuf::RepeatedPtrField<google::protobuf::EnumValueDescriptorProto>::TypeHandler>(google::protobuf::RepeatedPtrField<google::protobuf::EnumValueDescriptorProto>::TypeHandler::Type const*) Unexecuted instantiation: google::protobuf::RepeatedPtrField<google::protobuf::EnumDescriptorProto_EnumReservedRange>::TypeHandler::Type* google::protobuf::internal::RepeatedPtrFieldBase::Add<google::protobuf::RepeatedPtrField<google::protobuf::EnumDescriptorProto_EnumReservedRange>::TypeHandler>(google::protobuf::RepeatedPtrField<google::protobuf::EnumDescriptorProto_EnumReservedRange>::TypeHandler::Type const*) Unexecuted instantiation: google::protobuf::RepeatedPtrField<google::protobuf::MethodDescriptorProto>::TypeHandler::Type* google::protobuf::internal::RepeatedPtrFieldBase::Add<google::protobuf::RepeatedPtrField<google::protobuf::MethodDescriptorProto>::TypeHandler>(google::protobuf::RepeatedPtrField<google::protobuf::MethodDescriptorProto>::TypeHandler::Type const*) Unexecuted instantiation: google::protobuf::RepeatedPtrField<google::protobuf::UninterpretedOption_NamePart>::TypeHandler::Type* google::protobuf::internal::RepeatedPtrFieldBase::Add<google::protobuf::RepeatedPtrField<google::protobuf::UninterpretedOption_NamePart>::TypeHandler>(google::protobuf::RepeatedPtrField<google::protobuf::UninterpretedOption_NamePart>::TypeHandler::Type const*) Unexecuted instantiation: google::protobuf::RepeatedPtrField<google::protobuf::SourceCodeInfo_Location>::TypeHandler::Type* google::protobuf::internal::RepeatedPtrFieldBase::Add<google::protobuf::RepeatedPtrField<google::protobuf::SourceCodeInfo_Location>::TypeHandler>(google::protobuf::RepeatedPtrField<google::protobuf::SourceCodeInfo_Location>::TypeHandler::Type const*) Unexecuted instantiation: google::protobuf::RepeatedPtrField<google::protobuf::GeneratedCodeInfo_Annotation>::TypeHandler::Type* google::protobuf::internal::RepeatedPtrFieldBase::Add<google::protobuf::RepeatedPtrField<google::protobuf::GeneratedCodeInfo_Annotation>::TypeHandler>(google::protobuf::RepeatedPtrField<google::protobuf::GeneratedCodeInfo_Annotation>::TypeHandler::Type const*) Unexecuted instantiation: google::protobuf::RepeatedPtrField<gifProtoFuzzer::SubBlock>::TypeHandler::Type* google::protobuf::internal::RepeatedPtrFieldBase::Add<google::protobuf::RepeatedPtrField<gifProtoFuzzer::SubBlock>::TypeHandler>(google::protobuf::RepeatedPtrField<gifProtoFuzzer::SubBlock>::TypeHandler::Type const*) Unexecuted instantiation: google::protobuf::RepeatedPtrField<gifProtoFuzzer::ImageChunk>::TypeHandler::Type* google::protobuf::internal::RepeatedPtrFieldBase::Add<google::protobuf::RepeatedPtrField<gifProtoFuzzer::ImageChunk>::TypeHandler>(google::protobuf::RepeatedPtrField<gifProtoFuzzer::ImageChunk>::TypeHandler::Type const*) |
219 | | |
220 | | template < |
221 | | typename TypeHandler, |
222 | | typename std::enable_if<TypeHandler::Movable::value>::type* = nullptr> |
223 | 0 | inline void Add(typename TypeHandler::Type&& value) { |
224 | 0 | if (rep_ != nullptr && current_size_ < rep_->allocated_size) { |
225 | 0 | *cast<TypeHandler>( |
226 | 0 | rep_->elements[ExchangeCurrentSize(current_size_ + 1)]) = |
227 | 0 | std::move(value); |
228 | 0 | return; |
229 | 0 | } |
230 | 0 | if (!rep_ || rep_->allocated_size == total_size_) { |
231 | 0 | Reserve(total_size_ + 1); |
232 | 0 | } |
233 | 0 | ++rep_->allocated_size; |
234 | 0 | typename TypeHandler::Type* result = |
235 | 0 | TypeHandler::New(arena_, std::move(value)); |
236 | 0 | rep_->elements[ExchangeCurrentSize(current_size_ + 1)] = result; |
237 | 0 | } |
238 | | |
239 | | template <typename TypeHandler> |
240 | | void Delete(int index) { |
241 | | ABSL_DCHECK_GE(index, 0); |
242 | | ABSL_DCHECK_LT(index, current_size_); |
243 | | TypeHandler::Delete(cast<TypeHandler>(rep_->elements[index]), arena_); |
244 | | } |
245 | | |
246 | | // Must be called from destructor. |
247 | | template <typename TypeHandler> |
248 | 0 | void Destroy() { |
249 | 0 | if (rep_ != nullptr && arena_ == nullptr) { |
250 | 0 | int n = rep_->allocated_size; |
251 | 0 | void* const* elements = rep_->elements; |
252 | 0 | for (int i = 0; i < n; i++) { |
253 | 0 | TypeHandler::Delete(cast<TypeHandler>(elements[i]), nullptr); |
254 | 0 | } |
255 | 0 | const size_t size = total_size_ * sizeof(elements[0]) + kRepHeaderSize; |
256 | 0 | internal::SizedDelete(rep_, size); |
257 | 0 | } |
258 | 0 | rep_ = nullptr; |
259 | 0 | } Unexecuted instantiation: void google::protobuf::internal::RepeatedPtrFieldBase::Destroy<google::protobuf::RepeatedPtrField<gifProtoFuzzer::SubBlock>::TypeHandler>() Unexecuted instantiation: void google::protobuf::internal::RepeatedPtrFieldBase::Destroy<google::protobuf::RepeatedPtrField<gifProtoFuzzer::ImageChunk>::TypeHandler>() |
260 | | |
261 | 6.85k | bool NeedsDestroy() const { return rep_ != nullptr && arena_ == nullptr; } |
262 | | void DestroyProtos(); // implemented in the cc file |
263 | | |
264 | | public: |
265 | | // The next few methods are public so that they can be called from generated |
266 | | // code when implicit weak fields are used, but they should never be called by |
267 | | // application code. |
268 | | |
269 | | template <typename TypeHandler> |
270 | 0 | const typename TypeHandler::Type& Get(int index) const { |
271 | 0 | ABSL_DCHECK_GE(index, 0); |
272 | 0 | ABSL_DCHECK_LT(index, current_size_); |
273 | 0 | return *cast<TypeHandler>(rep_->elements[index]); |
274 | 0 | } Unexecuted instantiation: google::protobuf::RepeatedPtrField<google::protobuf::FileDescriptorProto>::TypeHandler::Type const& google::protobuf::internal::RepeatedPtrFieldBase::Get<google::protobuf::RepeatedPtrField<google::protobuf::FileDescriptorProto>::TypeHandler>(int) const Unexecuted instantiation: google::protobuf::RepeatedPtrField<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >::TypeHandler::Type const& google::protobuf::internal::RepeatedPtrFieldBase::Get<google::protobuf::RepeatedPtrField<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >::TypeHandler>(int) const Unexecuted instantiation: google::protobuf::RepeatedPtrField<google::protobuf::DescriptorProto>::TypeHandler::Type const& google::protobuf::internal::RepeatedPtrFieldBase::Get<google::protobuf::RepeatedPtrField<google::protobuf::DescriptorProto>::TypeHandler>(int) const Unexecuted instantiation: google::protobuf::RepeatedPtrField<google::protobuf::EnumDescriptorProto>::TypeHandler::Type const& google::protobuf::internal::RepeatedPtrFieldBase::Get<google::protobuf::RepeatedPtrField<google::protobuf::EnumDescriptorProto>::TypeHandler>(int) const Unexecuted instantiation: google::protobuf::RepeatedPtrField<google::protobuf::ServiceDescriptorProto>::TypeHandler::Type const& google::protobuf::internal::RepeatedPtrFieldBase::Get<google::protobuf::RepeatedPtrField<google::protobuf::ServiceDescriptorProto>::TypeHandler>(int) const Unexecuted instantiation: google::protobuf::RepeatedPtrField<google::protobuf::FieldDescriptorProto>::TypeHandler::Type const& google::protobuf::internal::RepeatedPtrFieldBase::Get<google::protobuf::RepeatedPtrField<google::protobuf::FieldDescriptorProto>::TypeHandler>(int) const Unexecuted instantiation: google::protobuf::RepeatedPtrField<google::protobuf::DescriptorProto_ExtensionRange>::TypeHandler::Type const& google::protobuf::internal::RepeatedPtrFieldBase::Get<google::protobuf::RepeatedPtrField<google::protobuf::DescriptorProto_ExtensionRange>::TypeHandler>(int) const Unexecuted instantiation: google::protobuf::RepeatedPtrField<google::protobuf::OneofDescriptorProto>::TypeHandler::Type const& google::protobuf::internal::RepeatedPtrFieldBase::Get<google::protobuf::RepeatedPtrField<google::protobuf::OneofDescriptorProto>::TypeHandler>(int) const Unexecuted instantiation: google::protobuf::RepeatedPtrField<google::protobuf::DescriptorProto_ReservedRange>::TypeHandler::Type const& google::protobuf::internal::RepeatedPtrFieldBase::Get<google::protobuf::RepeatedPtrField<google::protobuf::DescriptorProto_ReservedRange>::TypeHandler>(int) const Unexecuted instantiation: google::protobuf::RepeatedPtrField<google::protobuf::UninterpretedOption>::TypeHandler::Type const& google::protobuf::internal::RepeatedPtrFieldBase::Get<google::protobuf::RepeatedPtrField<google::protobuf::UninterpretedOption>::TypeHandler>(int) const Unexecuted instantiation: google::protobuf::RepeatedPtrField<google::protobuf::EnumValueDescriptorProto>::TypeHandler::Type const& google::protobuf::internal::RepeatedPtrFieldBase::Get<google::protobuf::RepeatedPtrField<google::protobuf::EnumValueDescriptorProto>::TypeHandler>(int) const Unexecuted instantiation: google::protobuf::RepeatedPtrField<google::protobuf::EnumDescriptorProto_EnumReservedRange>::TypeHandler::Type const& google::protobuf::internal::RepeatedPtrFieldBase::Get<google::protobuf::RepeatedPtrField<google::protobuf::EnumDescriptorProto_EnumReservedRange>::TypeHandler>(int) const Unexecuted instantiation: google::protobuf::RepeatedPtrField<google::protobuf::MethodDescriptorProto>::TypeHandler::Type const& google::protobuf::internal::RepeatedPtrFieldBase::Get<google::protobuf::RepeatedPtrField<google::protobuf::MethodDescriptorProto>::TypeHandler>(int) const Unexecuted instantiation: google::protobuf::RepeatedPtrField<google::protobuf::UninterpretedOption_NamePart>::TypeHandler::Type const& google::protobuf::internal::RepeatedPtrFieldBase::Get<google::protobuf::RepeatedPtrField<google::protobuf::UninterpretedOption_NamePart>::TypeHandler>(int) const Unexecuted instantiation: google::protobuf::RepeatedPtrField<google::protobuf::SourceCodeInfo_Location>::TypeHandler::Type const& google::protobuf::internal::RepeatedPtrFieldBase::Get<google::protobuf::RepeatedPtrField<google::protobuf::SourceCodeInfo_Location>::TypeHandler>(int) const Unexecuted instantiation: google::protobuf::RepeatedPtrField<google::protobuf::GeneratedCodeInfo_Annotation>::TypeHandler::Type const& google::protobuf::internal::RepeatedPtrFieldBase::Get<google::protobuf::RepeatedPtrField<google::protobuf::GeneratedCodeInfo_Annotation>::TypeHandler>(int) const Unexecuted instantiation: google::protobuf::RepeatedPtrField<gifProtoFuzzer::SubBlock>::TypeHandler::Type const& google::protobuf::internal::RepeatedPtrFieldBase::Get<google::protobuf::RepeatedPtrField<gifProtoFuzzer::SubBlock>::TypeHandler>(int) const Unexecuted instantiation: google::protobuf::RepeatedPtrField<gifProtoFuzzer::ImageChunk>::TypeHandler::Type const& google::protobuf::internal::RepeatedPtrFieldBase::Get<google::protobuf::RepeatedPtrField<gifProtoFuzzer::ImageChunk>::TypeHandler>(int) const |
275 | | |
276 | | // Creates and adds an element using the given prototype, without introducing |
277 | | // a link-time dependency on the concrete message type. This method is used to |
278 | | // implement implicit weak fields. The prototype may be nullptr, in which case |
279 | | // an ImplicitWeakMessage will be used as a placeholder. |
280 | | MessageLite* AddWeak(const MessageLite* prototype); |
281 | | |
282 | | template <typename TypeHandler> |
283 | 4.11k | void Clear() { |
284 | 4.11k | const int n = current_size_; |
285 | 4.11k | ABSL_DCHECK_GE(n, 0); |
286 | 4.11k | if (n > 0) { |
287 | 88 | ClearNonEmpty<TypeHandler>(); |
288 | 88 | } |
289 | 4.11k | } Unexecuted instantiation: void google::protobuf::internal::RepeatedPtrFieldBase::Clear<google::protobuf::RepeatedPtrField<google::protobuf::FileDescriptorProto>::TypeHandler>() Unexecuted instantiation: void google::protobuf::internal::RepeatedPtrFieldBase::Clear<google::protobuf::RepeatedPtrField<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >::TypeHandler>() Unexecuted instantiation: void google::protobuf::internal::RepeatedPtrFieldBase::Clear<google::protobuf::RepeatedPtrField<google::protobuf::DescriptorProto>::TypeHandler>() Unexecuted instantiation: void google::protobuf::internal::RepeatedPtrFieldBase::Clear<google::protobuf::RepeatedPtrField<google::protobuf::EnumDescriptorProto>::TypeHandler>() Unexecuted instantiation: void google::protobuf::internal::RepeatedPtrFieldBase::Clear<google::protobuf::RepeatedPtrField<google::protobuf::ServiceDescriptorProto>::TypeHandler>() Unexecuted instantiation: void google::protobuf::internal::RepeatedPtrFieldBase::Clear<google::protobuf::RepeatedPtrField<google::protobuf::FieldDescriptorProto>::TypeHandler>() Unexecuted instantiation: void google::protobuf::internal::RepeatedPtrFieldBase::Clear<google::protobuf::RepeatedPtrField<google::protobuf::DescriptorProto_ExtensionRange>::TypeHandler>() Unexecuted instantiation: void google::protobuf::internal::RepeatedPtrFieldBase::Clear<google::protobuf::RepeatedPtrField<google::protobuf::OneofDescriptorProto>::TypeHandler>() Unexecuted instantiation: void google::protobuf::internal::RepeatedPtrFieldBase::Clear<google::protobuf::RepeatedPtrField<google::protobuf::DescriptorProto_ReservedRange>::TypeHandler>() Unexecuted instantiation: void google::protobuf::internal::RepeatedPtrFieldBase::Clear<google::protobuf::RepeatedPtrField<google::protobuf::UninterpretedOption>::TypeHandler>() Unexecuted instantiation: void google::protobuf::internal::RepeatedPtrFieldBase::Clear<google::protobuf::RepeatedPtrField<google::protobuf::EnumValueDescriptorProto>::TypeHandler>() Unexecuted instantiation: void google::protobuf::internal::RepeatedPtrFieldBase::Clear<google::protobuf::RepeatedPtrField<google::protobuf::EnumDescriptorProto_EnumReservedRange>::TypeHandler>() Unexecuted instantiation: void google::protobuf::internal::RepeatedPtrFieldBase::Clear<google::protobuf::RepeatedPtrField<google::protobuf::MethodDescriptorProto>::TypeHandler>() Unexecuted instantiation: void google::protobuf::internal::RepeatedPtrFieldBase::Clear<google::protobuf::RepeatedPtrField<google::protobuf::UninterpretedOption_NamePart>::TypeHandler>() Unexecuted instantiation: void google::protobuf::internal::RepeatedPtrFieldBase::Clear<google::protobuf::RepeatedPtrField<google::protobuf::SourceCodeInfo_Location>::TypeHandler>() Unexecuted instantiation: void google::protobuf::internal::RepeatedPtrFieldBase::Clear<google::protobuf::RepeatedPtrField<google::protobuf::GeneratedCodeInfo_Annotation>::TypeHandler>() void google::protobuf::internal::RepeatedPtrFieldBase::Clear<google::protobuf::RepeatedPtrField<gifProtoFuzzer::SubBlock>::TypeHandler>() Line | Count | Source | 283 | 1.46k | void Clear() { | 284 | 1.46k | const int n = current_size_; | 285 | 1.46k | ABSL_DCHECK_GE(n, 0); | 286 | 1.46k | if (n > 0) { | 287 | 0 | ClearNonEmpty<TypeHandler>(); | 288 | 0 | } | 289 | 1.46k | } |
void google::protobuf::internal::RepeatedPtrFieldBase::Clear<google::protobuf::RepeatedPtrField<gifProtoFuzzer::ImageChunk>::TypeHandler>() Line | Count | Source | 283 | 2.65k | void Clear() { | 284 | 2.65k | const int n = current_size_; | 285 | 2.65k | ABSL_DCHECK_GE(n, 0); | 286 | 2.65k | if (n > 0) { | 287 | 88 | ClearNonEmpty<TypeHandler>(); | 288 | 88 | } | 289 | 2.65k | } |
|
290 | | |
291 | | template <typename TypeHandler> |
292 | 730 | void MergeFrom(const RepeatedPtrFieldBase& other) { |
293 | | // To avoid unnecessary code duplication and reduce binary size, we use a |
294 | | // layered approach to implementing MergeFrom(). The toplevel method is |
295 | | // templated, so we get a small thunk per concrete message type in the |
296 | | // binary. This calls a shared implementation with most of the logic, |
297 | | // passing a function pointer to another type-specific piece of code that |
298 | | // calls the object-allocate and merge handlers. |
299 | 730 | ABSL_DCHECK_NE(&other, this); |
300 | 730 | if (other.current_size_ == 0) return; |
301 | 0 | MergeFromInternal(other, |
302 | 0 | &RepeatedPtrFieldBase::MergeFromInnerLoop<TypeHandler>); |
303 | 0 | } void google::protobuf::internal::RepeatedPtrFieldBase::MergeFrom<google::protobuf::RepeatedPtrField<gifProtoFuzzer::SubBlock>::TypeHandler>(google::protobuf::internal::RepeatedPtrFieldBase const&) Line | Count | Source | 292 | 730 | void MergeFrom(const RepeatedPtrFieldBase& other) { | 293 | | // To avoid unnecessary code duplication and reduce binary size, we use a | 294 | | // layered approach to implementing MergeFrom(). The toplevel method is | 295 | | // templated, so we get a small thunk per concrete message type in the | 296 | | // binary. This calls a shared implementation with most of the logic, | 297 | | // passing a function pointer to another type-specific piece of code that | 298 | | // calls the object-allocate and merge handlers. | 299 | 730 | ABSL_DCHECK_NE(&other, this); | 300 | 730 | if (other.current_size_ == 0) return; | 301 | 0 | MergeFromInternal(other, | 302 | 0 | &RepeatedPtrFieldBase::MergeFromInnerLoop<TypeHandler>); | 303 | 0 | } |
Unexecuted instantiation: void google::protobuf::internal::RepeatedPtrFieldBase::MergeFrom<google::protobuf::RepeatedPtrField<gifProtoFuzzer::ImageChunk>::TypeHandler>(google::protobuf::internal::RepeatedPtrFieldBase const&) |
304 | | |
305 | 0 | inline void InternalSwap(RepeatedPtrFieldBase* rhs) { |
306 | 0 | ABSL_DCHECK(this != rhs); |
307 | | |
308 | | // Swap all fields at once. |
309 | 0 | auto temp = std::make_tuple(rhs->arena_, rhs->current_size_, |
310 | 0 | rhs->total_size_, rhs->rep_); |
311 | 0 | std::tie(rhs->arena_, rhs->current_size_, rhs->total_size_, rhs->rep_) = |
312 | 0 | std::make_tuple(arena_, current_size_, total_size_, rep_); |
313 | 0 | std::tie(arena_, current_size_, total_size_, rep_) = temp; |
314 | 0 | } |
315 | | |
316 | | // Prepares the container for adding elements via `AddAllocatedForParse`. |
317 | | // It ensures some invariants to avoid checking then in the Add loop: |
318 | | // - rep_ is not null. |
319 | | // - there are no preallocated elements. |
320 | | // Returns true if the invariants hold and `AddAllocatedForParse` can be |
321 | | // used. |
322 | 0 | bool PrepareForParse() { |
323 | 0 | if (current_size_ == total_size_) { |
324 | 0 | InternalExtend(1); |
325 | 0 | } |
326 | 0 | return rep_->allocated_size == current_size_; |
327 | 0 | } |
328 | | |
329 | | // Similar to `AddAllocated` but faster. |
330 | | // Can only be invoked after a call to `PrepareForParse` that returned `true`, |
331 | | // or other calls to `AddAllocatedForParse`. |
332 | | template <typename TypeHandler> |
333 | | void AddAllocatedForParse(typename TypeHandler::Type* value) { |
334 | | PROTOBUF_ASSUME(rep_ != nullptr); |
335 | | PROTOBUF_ASSUME(current_size_ == rep_->allocated_size); |
336 | | if (current_size_ == total_size_) { |
337 | | // The array is completely full with no cleared objects, so grow it. |
338 | | InternalExtend(1); |
339 | | } |
340 | | rep_->elements[current_size_++] = value; |
341 | | ++rep_->allocated_size; |
342 | | } |
343 | | |
344 | | protected: |
345 | | template <typename TypeHandler> |
346 | | void RemoveLast() { |
347 | | ABSL_DCHECK_GT(current_size_, 0); |
348 | | ExchangeCurrentSize(current_size_ - 1); |
349 | | TypeHandler::Clear(cast<TypeHandler>(rep_->elements[current_size_])); |
350 | | } |
351 | | |
352 | | template <typename TypeHandler> |
353 | 0 | void CopyFrom(const RepeatedPtrFieldBase& other) { |
354 | 0 | if (&other == this) return; |
355 | 0 | RepeatedPtrFieldBase::Clear<TypeHandler>(); |
356 | 0 | RepeatedPtrFieldBase::MergeFrom<TypeHandler>(other); |
357 | 0 | } Unexecuted instantiation: void google::protobuf::internal::RepeatedPtrFieldBase::CopyFrom<google::protobuf::RepeatedPtrField<gifProtoFuzzer::SubBlock>::TypeHandler>(google::protobuf::internal::RepeatedPtrFieldBase const&) Unexecuted instantiation: void google::protobuf::internal::RepeatedPtrFieldBase::CopyFrom<google::protobuf::RepeatedPtrField<gifProtoFuzzer::ImageChunk>::TypeHandler>(google::protobuf::internal::RepeatedPtrFieldBase const&) |
358 | | |
359 | | void CloseGap(int start, int num); // implemented in the cc file |
360 | | |
361 | | void Reserve(int new_size); // implemented in the cc file |
362 | | |
363 | | template <typename TypeHandler> |
364 | | static inline typename TypeHandler::Type* copy( |
365 | | typename TypeHandler::Type* value) { |
366 | | auto* new_value = TypeHandler::NewFromPrototype(value, nullptr); |
367 | | TypeHandler::Merge(*value, new_value); |
368 | | return new_value; |
369 | | } |
370 | | |
371 | | // Used for constructing iterators. |
372 | 10.9k | void* const* raw_data() const { return rep_ ? rep_->elements : nullptr; } |
373 | 0 | void** raw_mutable_data() const { |
374 | 0 | return rep_ ? const_cast<void**>(rep_->elements) : nullptr; |
375 | 0 | } |
376 | | |
377 | | template <typename TypeHandler> |
378 | | typename TypeHandler::Type** mutable_data() { |
379 | | // TODO(kenton): Breaks C++ aliasing rules. We should probably remove this |
380 | | // method entirely. |
381 | | return reinterpret_cast<typename TypeHandler::Type**>(raw_mutable_data()); |
382 | | } |
383 | | |
384 | | template <typename TypeHandler> |
385 | | const typename TypeHandler::Type* const* data() const { |
386 | | // TODO(kenton): Breaks C++ aliasing rules. We should probably remove this |
387 | | // method entirely. |
388 | | return reinterpret_cast<const typename TypeHandler::Type* const*>( |
389 | | raw_data()); |
390 | | } |
391 | | |
392 | | template <typename TypeHandler> |
393 | | PROTOBUF_NDEBUG_INLINE void Swap(RepeatedPtrFieldBase* other) { |
394 | | #ifdef PROTOBUF_FORCE_COPY_IN_SWAP |
395 | | if (GetOwningArena() != nullptr && |
396 | | GetOwningArena() == other->GetOwningArena()) |
397 | | #else // PROTOBUF_FORCE_COPY_IN_SWAP |
398 | | if (GetOwningArena() == other->GetOwningArena()) |
399 | | #endif // !PROTOBUF_FORCE_COPY_IN_SWAP |
400 | | { |
401 | | InternalSwap(other); |
402 | | } else { |
403 | | SwapFallback<TypeHandler>(other); |
404 | | } |
405 | | } |
406 | | |
407 | 0 | void SwapElements(int index1, int index2) { |
408 | 0 | using std::swap; // enable ADL with fallback |
409 | 0 | swap(rep_->elements[index1], rep_->elements[index2]); |
410 | 0 | } |
411 | | |
412 | | template <typename TypeHandler> |
413 | | size_t SpaceUsedExcludingSelfLong() const { |
414 | | size_t allocated_bytes = static_cast<size_t>(total_size_) * sizeof(void*); |
415 | | if (rep_ != nullptr) { |
416 | | for (int i = 0; i < rep_->allocated_size; ++i) { |
417 | | allocated_bytes += |
418 | | TypeHandler::SpaceUsedLong(*cast<TypeHandler>(rep_->elements[i])); |
419 | | } |
420 | | allocated_bytes += kRepHeaderSize; |
421 | | } |
422 | | return allocated_bytes; |
423 | | } |
424 | | |
425 | | // Advanced memory management -------------------------------------- |
426 | | |
427 | | // Like Add(), but if there are no cleared objects to use, returns nullptr. |
428 | | template <typename TypeHandler> |
429 | | typename TypeHandler::Type* AddFromCleared() { |
430 | | if (rep_ != nullptr && current_size_ < rep_->allocated_size) { |
431 | | return cast<TypeHandler>( |
432 | | rep_->elements[ExchangeCurrentSize(current_size_ + 1)]); |
433 | | } else { |
434 | | return nullptr; |
435 | | } |
436 | | } |
437 | | |
438 | | template <typename TypeHandler> |
439 | | void AddAllocated(typename TypeHandler::Type* value) { |
440 | | typename TypeImplementsMergeBehavior<typename TypeHandler::Type>::type t; |
441 | | AddAllocatedInternal<TypeHandler>(value, t); |
442 | | } |
443 | | |
444 | | template <typename TypeHandler> |
445 | | void UnsafeArenaAddAllocated(typename TypeHandler::Type* value) { |
446 | | // Make room for the new pointer. |
447 | | if (!rep_ || current_size_ == total_size_) { |
448 | | // The array is completely full with no cleared objects, so grow it. |
449 | | Reserve(total_size_ + 1); |
450 | | ++rep_->allocated_size; |
451 | | } else if (rep_->allocated_size == total_size_) { |
452 | | // There is no more space in the pointer array because it contains some |
453 | | // cleared objects awaiting reuse. We don't want to grow the array in |
454 | | // this case because otherwise a loop calling AddAllocated() followed by |
455 | | // Clear() would leak memory. |
456 | | TypeHandler::Delete(cast<TypeHandler>(rep_->elements[current_size_]), |
457 | | arena_); |
458 | | } else if (current_size_ < rep_->allocated_size) { |
459 | | // We have some cleared objects. We don't care about their order, so we |
460 | | // can just move the first one to the end to make space. |
461 | | rep_->elements[rep_->allocated_size] = rep_->elements[current_size_]; |
462 | | ++rep_->allocated_size; |
463 | | } else { |
464 | | // There are no cleared objects. |
465 | | ++rep_->allocated_size; |
466 | | } |
467 | | |
468 | | rep_->elements[ExchangeCurrentSize(current_size_ + 1)] = value; |
469 | | } |
470 | | |
471 | | template <typename TypeHandler> |
472 | | PROTOBUF_NODISCARD typename TypeHandler::Type* ReleaseLast() { |
473 | | typename TypeImplementsMergeBehavior<typename TypeHandler::Type>::type t; |
474 | | return ReleaseLastInternal<TypeHandler>(t); |
475 | | } |
476 | | |
477 | | // Releases and returns the last element, but does not do out-of-arena copy. |
478 | | // Instead, just returns the raw pointer to the contained element in the |
479 | | // arena. |
480 | | template <typename TypeHandler> |
481 | | typename TypeHandler::Type* UnsafeArenaReleaseLast() { |
482 | | ABSL_DCHECK_GT(current_size_, 0); |
483 | | ExchangeCurrentSize(current_size_ - 1); |
484 | | typename TypeHandler::Type* result = |
485 | | cast<TypeHandler>(rep_->elements[current_size_]); |
486 | | --rep_->allocated_size; |
487 | | if (current_size_ < rep_->allocated_size) { |
488 | | // There are cleared elements on the end; replace the removed element |
489 | | // with the last allocated element. |
490 | | rep_->elements[current_size_] = rep_->elements[rep_->allocated_size]; |
491 | | } |
492 | | return result; |
493 | | } |
494 | | |
495 | 0 | int ClearedCount() const { |
496 | 0 | return rep_ ? (rep_->allocated_size - current_size_) : 0; |
497 | 0 | } |
498 | | |
499 | | template <typename TypeHandler> |
500 | | void AddCleared(typename TypeHandler::Type* value) { |
501 | | ABSL_DCHECK(GetOwningArena() == nullptr) |
502 | | << "AddCleared() can only be used on a " |
503 | | "RepeatedPtrField not on an arena."; |
504 | | ABSL_DCHECK(TypeHandler::GetOwningArena(value) == nullptr) |
505 | | << "AddCleared() can only accept values not on an arena."; |
506 | | if (!rep_ || rep_->allocated_size == total_size_) { |
507 | | Reserve(total_size_ + 1); |
508 | | } |
509 | | rep_->elements[rep_->allocated_size++] = value; |
510 | | } |
511 | | |
512 | | template <typename TypeHandler> |
513 | | PROTOBUF_NODISCARD typename TypeHandler::Type* ReleaseCleared() { |
514 | | ABSL_DCHECK(GetOwningArena() == nullptr) |
515 | | << "ReleaseCleared() can only be used on a RepeatedPtrField not on " |
516 | | << "an arena."; |
517 | | ABSL_DCHECK(rep_ != nullptr); |
518 | | ABSL_DCHECK_GT(rep_->allocated_size, current_size_); |
519 | | return cast<TypeHandler>(rep_->elements[--rep_->allocated_size]); |
520 | | } |
521 | | |
522 | | template <typename TypeHandler> |
523 | | void AddAllocatedInternal(typename TypeHandler::Type* value, std::true_type) { |
524 | | // AddAllocated version that implements arena-safe copying behavior. |
525 | | Arena* element_arena = |
526 | | reinterpret_cast<Arena*>(TypeHandler::GetOwningArena(value)); |
527 | | Arena* arena = GetOwningArena(); |
528 | | if (arena == element_arena && rep_ && rep_->allocated_size < total_size_) { |
529 | | // Fast path: underlying arena representation (tagged pointer) is equal to |
530 | | // our arena pointer, and we can add to array without resizing it (at |
531 | | // least one slot that is not allocated). |
532 | | void** elems = rep_->elements; |
533 | | if (current_size_ < rep_->allocated_size) { |
534 | | // Make space at [current] by moving first allocated element to end of |
535 | | // allocated list. |
536 | | elems[rep_->allocated_size] = elems[current_size_]; |
537 | | } |
538 | | elems[ExchangeCurrentSize(current_size_ + 1)] = value; |
539 | | rep_->allocated_size = rep_->allocated_size + 1; |
540 | | } else { |
541 | | AddAllocatedSlowWithCopy<TypeHandler>(value, element_arena, arena); |
542 | | } |
543 | | } |
544 | | |
545 | | template <typename TypeHandler> |
546 | | void AddAllocatedInternal( |
547 | | // AddAllocated version that does not implement arena-safe copying |
548 | | // behavior. |
549 | | typename TypeHandler::Type* value, std::false_type) { |
550 | | if (rep_ && rep_->allocated_size < total_size_) { |
551 | | // Fast path: underlying arena representation (tagged pointer) is equal to |
552 | | // our arena pointer, and we can add to array without resizing it (at |
553 | | // least one slot that is not allocated). |
554 | | void** elems = rep_->elements; |
555 | | if (current_size_ < rep_->allocated_size) { |
556 | | // Make space at [current] by moving first allocated element to end of |
557 | | // allocated list. |
558 | | elems[rep_->allocated_size] = elems[current_size_]; |
559 | | } |
560 | | elems[ExchangeCurrentSize(current_size_ + 1)] = value; |
561 | | ++rep_->allocated_size; |
562 | | } else { |
563 | | UnsafeArenaAddAllocated<TypeHandler>(value); |
564 | | } |
565 | | } |
566 | | |
567 | | // Slowpath handles all cases, copying if necessary. |
568 | | template <typename TypeHandler> |
569 | | PROTOBUF_NOINLINE void AddAllocatedSlowWithCopy( |
570 | | // Pass value_arena and my_arena to avoid duplicate virtual call (value) |
571 | | // or load (mine). |
572 | | typename TypeHandler::Type* value, Arena* value_arena, Arena* my_arena) { |
573 | | // Ensure that either the value is in the same arena, or if not, we do the |
574 | | // appropriate thing: Own() it (if it's on heap and we're in an arena) or |
575 | | // copy it to our arena/heap (otherwise). |
576 | | if (my_arena != nullptr && value_arena == nullptr) { |
577 | | my_arena->Own(value); |
578 | | } else if (my_arena != value_arena) { |
579 | | typename TypeHandler::Type* new_value = |
580 | | TypeHandler::NewFromPrototype(value, my_arena); |
581 | | TypeHandler::Merge(*value, new_value); |
582 | | TypeHandler::Delete(value, value_arena); |
583 | | value = new_value; |
584 | | } |
585 | | |
586 | | UnsafeArenaAddAllocated<TypeHandler>(value); |
587 | | } |
588 | | |
589 | | template <typename TypeHandler> |
590 | | typename TypeHandler::Type* ReleaseLastInternal(std::true_type) { |
591 | | // ReleaseLast() for types that implement merge/copy behavior. |
592 | | // First, release an element. |
593 | | typename TypeHandler::Type* result = UnsafeArenaReleaseLast<TypeHandler>(); |
594 | | // Now perform a copy if we're on an arena. |
595 | | Arena* arena = GetOwningArena(); |
596 | | |
597 | | typename TypeHandler::Type* new_result; |
598 | | #ifdef PROTOBUF_FORCE_COPY_IN_RELEASE |
599 | | new_result = copy<TypeHandler>(result); |
600 | | if (arena == nullptr) delete result; |
601 | | #else // PROTOBUF_FORCE_COPY_IN_RELEASE |
602 | | new_result = (arena == nullptr) ? result : copy<TypeHandler>(result); |
603 | | #endif // !PROTOBUF_FORCE_COPY_IN_RELEASE |
604 | | return new_result; |
605 | | } |
606 | | |
607 | | template <typename TypeHandler> |
608 | | typename TypeHandler::Type* ReleaseLastInternal(std::false_type) { |
609 | | // ReleaseLast() for types that *do not* implement merge/copy behavior -- |
610 | | // this is the same as UnsafeArenaReleaseLast(). Note that we |
611 | | // ABSL_DCHECK-fail if we're on an arena, since the user really should |
612 | | // implement the copy operation in this case. |
613 | | ABSL_DCHECK(GetOwningArena() == nullptr) |
614 | | << "ReleaseLast() called on a RepeatedPtrField that is on an arena, " |
615 | | << "with a type that does not implement MergeFrom. This is unsafe; " |
616 | | << "please implement MergeFrom for your type."; |
617 | | return UnsafeArenaReleaseLast<TypeHandler>(); |
618 | | } |
619 | | |
620 | | template <typename TypeHandler> |
621 | | PROTOBUF_NOINLINE void SwapFallback(RepeatedPtrFieldBase* other) { |
622 | | #ifdef PROTOBUF_FORCE_COPY_IN_SWAP |
623 | | ABSL_DCHECK(GetOwningArena() == nullptr || |
624 | | other->GetOwningArena() != GetOwningArena()); |
625 | | #else // PROTOBUF_FORCE_COPY_IN_SWAP |
626 | | ABSL_DCHECK(other->GetOwningArena() != GetOwningArena()); |
627 | | #endif // !PROTOBUF_FORCE_COPY_IN_SWAP |
628 | | |
629 | | // Copy semantics in this case. We try to improve efficiency by placing the |
630 | | // temporary on |other|'s arena so that messages are copied twice rather |
631 | | // than three times. |
632 | | RepeatedPtrFieldBase temp(other->GetOwningArena()); |
633 | | temp.MergeFrom<TypeHandler>(*this); |
634 | | this->Clear<TypeHandler>(); |
635 | | this->MergeFrom<TypeHandler>(*other); |
636 | | other->InternalSwap(&temp); |
637 | | temp.Destroy<TypeHandler>(); // Frees rep_ if `other` had no arena. |
638 | | } |
639 | | |
640 | | // Gets the Arena on which this RepeatedPtrField stores its elements. |
641 | 0 | inline Arena* GetArena() const { return GetOwningArena(); } |
642 | | |
643 | | protected: |
644 | 0 | inline Arena* GetOwningArena() const { return arena_; } |
645 | | |
646 | | private: |
647 | | template <typename T> friend class Arena::InternalHelper; |
648 | | |
649 | | static constexpr int kInitialSize = 0; |
650 | | // A few notes on internal representation: |
651 | | // |
652 | | // We use an indirected approach, with struct Rep, to keep |
653 | | // sizeof(RepeatedPtrFieldBase) equivalent to what it was before arena support |
654 | | // was added; namely, 3 8-byte machine words on x86-64. An instance of Rep is |
655 | | // allocated only when the repeated field is non-empty, and it is a |
656 | | // dynamically-sized struct (the header is directly followed by elements[]). |
657 | | // We place arena_ and current_size_ directly in the object to avoid cache |
658 | | // misses due to the indirection, because these fields are checked frequently. |
659 | | // Placing all fields directly in the RepeatedPtrFieldBase instance would cost |
660 | | // significant performance for memory-sensitive workloads. |
661 | | Arena* arena_; |
662 | | int current_size_; |
663 | | int total_size_; |
664 | | |
665 | | // Replaces current_size_ with new_size and returns the previous value of |
666 | | // current_size_. This function is intended to be the only place where |
667 | | // current_size_ is modified. |
668 | 88 | inline int ExchangeCurrentSize(int new_size) { |
669 | 88 | int prev_size = current_size_; |
670 | 88 | current_size_ = new_size; |
671 | 88 | return prev_size; |
672 | 88 | } |
673 | | |
674 | | struct Rep { |
675 | | int allocated_size; |
676 | | // Here we declare a huge array as a way of approximating C's "flexible |
677 | | // array member" feature without relying on undefined behavior. |
678 | | void* elements[(std::numeric_limits<int>::max() - 2 * sizeof(int)) / |
679 | | sizeof(void*)]; |
680 | | }; |
681 | | static constexpr size_t kRepHeaderSize = offsetof(Rep, elements); |
682 | | Rep* rep_; |
683 | | |
684 | | template <typename TypeHandler> |
685 | 30.7k | static inline typename TypeHandler::Type* cast(void* element) { |
686 | 30.7k | return reinterpret_cast<typename TypeHandler::Type*>(element); |
687 | 30.7k | } Unexecuted instantiation: google::protobuf::RepeatedPtrField<google::protobuf::FileDescriptorProto>::TypeHandler::Type* google::protobuf::internal::RepeatedPtrFieldBase::cast<google::protobuf::RepeatedPtrField<google::protobuf::FileDescriptorProto>::TypeHandler>(void*) Unexecuted instantiation: google::protobuf::RepeatedPtrField<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >::TypeHandler::Type* google::protobuf::internal::RepeatedPtrFieldBase::cast<google::protobuf::RepeatedPtrField<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >::TypeHandler>(void*) Unexecuted instantiation: google::protobuf::RepeatedPtrField<google::protobuf::DescriptorProto>::TypeHandler::Type* google::protobuf::internal::RepeatedPtrFieldBase::cast<google::protobuf::RepeatedPtrField<google::protobuf::DescriptorProto>::TypeHandler>(void*) Unexecuted instantiation: google::protobuf::RepeatedPtrField<google::protobuf::EnumDescriptorProto>::TypeHandler::Type* google::protobuf::internal::RepeatedPtrFieldBase::cast<google::protobuf::RepeatedPtrField<google::protobuf::EnumDescriptorProto>::TypeHandler>(void*) Unexecuted instantiation: google::protobuf::RepeatedPtrField<google::protobuf::ServiceDescriptorProto>::TypeHandler::Type* google::protobuf::internal::RepeatedPtrFieldBase::cast<google::protobuf::RepeatedPtrField<google::protobuf::ServiceDescriptorProto>::TypeHandler>(void*) Unexecuted instantiation: google::protobuf::RepeatedPtrField<google::protobuf::FieldDescriptorProto>::TypeHandler::Type* google::protobuf::internal::RepeatedPtrFieldBase::cast<google::protobuf::RepeatedPtrField<google::protobuf::FieldDescriptorProto>::TypeHandler>(void*) Unexecuted instantiation: google::protobuf::RepeatedPtrField<google::protobuf::DescriptorProto_ExtensionRange>::TypeHandler::Type* google::protobuf::internal::RepeatedPtrFieldBase::cast<google::protobuf::RepeatedPtrField<google::protobuf::DescriptorProto_ExtensionRange>::TypeHandler>(void*) Unexecuted instantiation: google::protobuf::RepeatedPtrField<google::protobuf::OneofDescriptorProto>::TypeHandler::Type* google::protobuf::internal::RepeatedPtrFieldBase::cast<google::protobuf::RepeatedPtrField<google::protobuf::OneofDescriptorProto>::TypeHandler>(void*) Unexecuted instantiation: google::protobuf::RepeatedPtrField<google::protobuf::DescriptorProto_ReservedRange>::TypeHandler::Type* google::protobuf::internal::RepeatedPtrFieldBase::cast<google::protobuf::RepeatedPtrField<google::protobuf::DescriptorProto_ReservedRange>::TypeHandler>(void*) Unexecuted instantiation: google::protobuf::RepeatedPtrField<google::protobuf::UninterpretedOption>::TypeHandler::Type* google::protobuf::internal::RepeatedPtrFieldBase::cast<google::protobuf::RepeatedPtrField<google::protobuf::UninterpretedOption>::TypeHandler>(void*) Unexecuted instantiation: google::protobuf::RepeatedPtrField<google::protobuf::EnumValueDescriptorProto>::TypeHandler::Type* google::protobuf::internal::RepeatedPtrFieldBase::cast<google::protobuf::RepeatedPtrField<google::protobuf::EnumValueDescriptorProto>::TypeHandler>(void*) Unexecuted instantiation: google::protobuf::RepeatedPtrField<google::protobuf::EnumDescriptorProto_EnumReservedRange>::TypeHandler::Type* google::protobuf::internal::RepeatedPtrFieldBase::cast<google::protobuf::RepeatedPtrField<google::protobuf::EnumDescriptorProto_EnumReservedRange>::TypeHandler>(void*) Unexecuted instantiation: google::protobuf::RepeatedPtrField<google::protobuf::MethodDescriptorProto>::TypeHandler::Type* google::protobuf::internal::RepeatedPtrFieldBase::cast<google::protobuf::RepeatedPtrField<google::protobuf::MethodDescriptorProto>::TypeHandler>(void*) Unexecuted instantiation: google::protobuf::RepeatedPtrField<google::protobuf::UninterpretedOption_NamePart>::TypeHandler::Type* google::protobuf::internal::RepeatedPtrFieldBase::cast<google::protobuf::RepeatedPtrField<google::protobuf::UninterpretedOption_NamePart>::TypeHandler>(void*) Unexecuted instantiation: google::protobuf::RepeatedPtrField<google::protobuf::SourceCodeInfo_Location>::TypeHandler::Type* google::protobuf::internal::RepeatedPtrFieldBase::cast<google::protobuf::RepeatedPtrField<google::protobuf::SourceCodeInfo_Location>::TypeHandler>(void*) Unexecuted instantiation: google::protobuf::RepeatedPtrField<google::protobuf::GeneratedCodeInfo_Annotation>::TypeHandler::Type* google::protobuf::internal::RepeatedPtrFieldBase::cast<google::protobuf::RepeatedPtrField<google::protobuf::GeneratedCodeInfo_Annotation>::TypeHandler>(void*) Unexecuted instantiation: google::protobuf::RepeatedPtrField<gifProtoFuzzer::SubBlock>::TypeHandler::Type* google::protobuf::internal::RepeatedPtrFieldBase::cast<google::protobuf::RepeatedPtrField<gifProtoFuzzer::SubBlock>::TypeHandler>(void*) google::protobuf::RepeatedPtrField<gifProtoFuzzer::ImageChunk>::TypeHandler::Type* google::protobuf::internal::RepeatedPtrFieldBase::cast<google::protobuf::RepeatedPtrField<gifProtoFuzzer::ImageChunk>::TypeHandler>(void*) Line | Count | Source | 685 | 30.7k | static inline typename TypeHandler::Type* cast(void* element) { | 686 | 30.7k | return reinterpret_cast<typename TypeHandler::Type*>(element); | 687 | 30.7k | } |
|
688 | | template <typename TypeHandler> |
689 | | static inline const typename TypeHandler::Type* cast(const void* element) { |
690 | | return reinterpret_cast<const typename TypeHandler::Type*>(element); |
691 | | } |
692 | | |
693 | | // Out-of-line helper routine for Clear() once the inlined check has |
694 | | // determined the container is non-empty |
695 | | template <typename TypeHandler> |
696 | 88 | PROTOBUF_NOINLINE void ClearNonEmpty() { |
697 | 88 | const int n = current_size_; |
698 | 88 | void* const* elements = rep_->elements; |
699 | 88 | int i = 0; |
700 | 88 | ABSL_DCHECK_GT( |
701 | 88 | n, |
702 | 88 | 0); // do/while loop to avoid initial test because we know n > 0 |
703 | 30.7k | do { |
704 | 30.7k | TypeHandler::Clear(cast<TypeHandler>(elements[i++])); |
705 | 30.7k | } while (i < n); |
706 | 88 | ExchangeCurrentSize(0); |
707 | 88 | } Unexecuted instantiation: void google::protobuf::internal::RepeatedPtrFieldBase::ClearNonEmpty<google::protobuf::RepeatedPtrField<google::protobuf::FileDescriptorProto>::TypeHandler>() Unexecuted instantiation: void google::protobuf::internal::RepeatedPtrFieldBase::ClearNonEmpty<google::protobuf::RepeatedPtrField<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >::TypeHandler>() Unexecuted instantiation: void google::protobuf::internal::RepeatedPtrFieldBase::ClearNonEmpty<google::protobuf::RepeatedPtrField<google::protobuf::DescriptorProto>::TypeHandler>() Unexecuted instantiation: void google::protobuf::internal::RepeatedPtrFieldBase::ClearNonEmpty<google::protobuf::RepeatedPtrField<google::protobuf::EnumDescriptorProto>::TypeHandler>() Unexecuted instantiation: void google::protobuf::internal::RepeatedPtrFieldBase::ClearNonEmpty<google::protobuf::RepeatedPtrField<google::protobuf::ServiceDescriptorProto>::TypeHandler>() Unexecuted instantiation: void google::protobuf::internal::RepeatedPtrFieldBase::ClearNonEmpty<google::protobuf::RepeatedPtrField<google::protobuf::FieldDescriptorProto>::TypeHandler>() Unexecuted instantiation: void google::protobuf::internal::RepeatedPtrFieldBase::ClearNonEmpty<google::protobuf::RepeatedPtrField<google::protobuf::DescriptorProto_ExtensionRange>::TypeHandler>() Unexecuted instantiation: void google::protobuf::internal::RepeatedPtrFieldBase::ClearNonEmpty<google::protobuf::RepeatedPtrField<google::protobuf::OneofDescriptorProto>::TypeHandler>() Unexecuted instantiation: void google::protobuf::internal::RepeatedPtrFieldBase::ClearNonEmpty<google::protobuf::RepeatedPtrField<google::protobuf::DescriptorProto_ReservedRange>::TypeHandler>() Unexecuted instantiation: void google::protobuf::internal::RepeatedPtrFieldBase::ClearNonEmpty<google::protobuf::RepeatedPtrField<google::protobuf::UninterpretedOption>::TypeHandler>() Unexecuted instantiation: void google::protobuf::internal::RepeatedPtrFieldBase::ClearNonEmpty<google::protobuf::RepeatedPtrField<google::protobuf::EnumValueDescriptorProto>::TypeHandler>() Unexecuted instantiation: void google::protobuf::internal::RepeatedPtrFieldBase::ClearNonEmpty<google::protobuf::RepeatedPtrField<google::protobuf::EnumDescriptorProto_EnumReservedRange>::TypeHandler>() Unexecuted instantiation: void google::protobuf::internal::RepeatedPtrFieldBase::ClearNonEmpty<google::protobuf::RepeatedPtrField<google::protobuf::MethodDescriptorProto>::TypeHandler>() Unexecuted instantiation: void google::protobuf::internal::RepeatedPtrFieldBase::ClearNonEmpty<google::protobuf::RepeatedPtrField<google::protobuf::UninterpretedOption_NamePart>::TypeHandler>() Unexecuted instantiation: void google::protobuf::internal::RepeatedPtrFieldBase::ClearNonEmpty<google::protobuf::RepeatedPtrField<google::protobuf::SourceCodeInfo_Location>::TypeHandler>() Unexecuted instantiation: void google::protobuf::internal::RepeatedPtrFieldBase::ClearNonEmpty<google::protobuf::RepeatedPtrField<google::protobuf::GeneratedCodeInfo_Annotation>::TypeHandler>() Unexecuted instantiation: void google::protobuf::internal::RepeatedPtrFieldBase::ClearNonEmpty<google::protobuf::RepeatedPtrField<gifProtoFuzzer::SubBlock>::TypeHandler>() void google::protobuf::internal::RepeatedPtrFieldBase::ClearNonEmpty<google::protobuf::RepeatedPtrField<gifProtoFuzzer::ImageChunk>::TypeHandler>() Line | Count | Source | 696 | 88 | PROTOBUF_NOINLINE void ClearNonEmpty() { | 697 | 88 | const int n = current_size_; | 698 | 88 | void* const* elements = rep_->elements; | 699 | 88 | int i = 0; | 700 | 88 | ABSL_DCHECK_GT( | 701 | 88 | n, | 702 | 88 | 0); // do/while loop to avoid initial test because we know n > 0 | 703 | 30.7k | do { | 704 | 30.7k | TypeHandler::Clear(cast<TypeHandler>(elements[i++])); | 705 | 30.7k | } while (i < n); | 706 | 88 | ExchangeCurrentSize(0); | 707 | 88 | } |
|
708 | | |
709 | | // Non-templated inner function to avoid code duplication. Takes a function |
710 | | // pointer to the type-specific (templated) inner allocate/merge loop. |
711 | | PROTOBUF_NOINLINE void MergeFromInternal( |
712 | | const RepeatedPtrFieldBase& other, |
713 | 0 | void (RepeatedPtrFieldBase::*inner_loop)(void**, void**, int, int)) { |
714 | | // Note: wrapper has already guaranteed that other.rep_ != nullptr here. |
715 | 0 | int other_size = other.current_size_; |
716 | 0 | void** other_elements = other.rep_->elements; |
717 | 0 | void** new_elements = InternalExtend(other_size); |
718 | 0 | int allocated_elems = rep_->allocated_size - current_size_; |
719 | 0 | (this->*inner_loop)(new_elements, other_elements, other_size, |
720 | 0 | allocated_elems); |
721 | 0 | ExchangeCurrentSize(current_size_ + other_size); |
722 | 0 | if (rep_->allocated_size < current_size_) { |
723 | 0 | rep_->allocated_size = current_size_; |
724 | 0 | } |
725 | 0 | } |
726 | | |
727 | | // Merges other_elems to our_elems. |
728 | | template <typename TypeHandler> |
729 | | PROTOBUF_NOINLINE void MergeFromInnerLoop(void** our_elems, |
730 | | void** other_elems, int length, |
731 | 0 | int already_allocated) { |
732 | 0 | if (already_allocated < length) { |
733 | 0 | Arena* arena = GetOwningArena(); |
734 | 0 | typename TypeHandler::Type* elem_prototype = |
735 | 0 | reinterpret_cast<typename TypeHandler::Type*>(other_elems[0]); |
736 | 0 | for (int i = already_allocated; i < length; i++) { |
737 | | // Allocate a new empty element that we'll merge into below |
738 | 0 | typename TypeHandler::Type* new_elem = |
739 | 0 | TypeHandler::NewFromPrototype(elem_prototype, arena); |
740 | 0 | our_elems[i] = new_elem; |
741 | 0 | } |
742 | 0 | } |
743 | | // Main loop that does the actual merging |
744 | 0 | for (int i = 0; i < length; i++) { |
745 | | // Already allocated: use existing element. |
746 | 0 | typename TypeHandler::Type* other_elem = |
747 | 0 | reinterpret_cast<typename TypeHandler::Type*>(other_elems[i]); |
748 | 0 | typename TypeHandler::Type* new_elem = |
749 | 0 | reinterpret_cast<typename TypeHandler::Type*>(our_elems[i]); |
750 | 0 | TypeHandler::Merge(*other_elem, new_elem); |
751 | 0 | } |
752 | 0 | } Unexecuted instantiation: void google::protobuf::internal::RepeatedPtrFieldBase::MergeFromInnerLoop<google::protobuf::RepeatedPtrField<gifProtoFuzzer::SubBlock>::TypeHandler>(void**, void**, int, int) Unexecuted instantiation: void google::protobuf::internal::RepeatedPtrFieldBase::MergeFromInnerLoop<google::protobuf::RepeatedPtrField<gifProtoFuzzer::ImageChunk>::TypeHandler>(void**, void**, int, int) |
753 | | |
754 | | // Internal helper: extends array space if necessary to contain |
755 | | // |extend_amount| more elements, and returns a pointer to the element |
756 | | // immediately following the old list of elements. This interface factors out |
757 | | // common behavior from Reserve() and MergeFrom() to reduce code size. |
758 | | // |extend_amount| must be > 0. |
759 | | void** InternalExtend(int extend_amount); |
760 | | |
761 | | // Internal helper for Add: adds "obj" as the next element in the |
762 | | // array, including potentially resizing the array with Reserve if |
763 | | // needed |
764 | | void* AddOutOfLineHelper(void* obj); |
765 | | |
766 | | // The reflection implementation needs to call protected methods directly, |
767 | | // reinterpreting pointers as being to Message instead of a specific Message |
768 | | // subclass. |
769 | | friend class ::PROTOBUF_NAMESPACE_ID::Reflection; |
770 | | friend class ::PROTOBUF_NAMESPACE_ID::internal::SwapFieldHelper; |
771 | | |
772 | | // ExtensionSet stores repeated message extensions as |
773 | | // RepeatedPtrField<MessageLite>, but non-lite ExtensionSets need to implement |
774 | | // SpaceUsedLong(), and thus need to call SpaceUsedExcludingSelfLong() |
775 | | // reinterpreting MessageLite as Message. ExtensionSet also needs to make use |
776 | | // of AddFromCleared(), which is not part of the public interface. |
777 | | friend class ExtensionSet; |
778 | | |
779 | | // The MapFieldBase implementation needs to call protected methods directly, |
780 | | // reinterpreting pointers as being to Message instead of a specific Message |
781 | | // subclass. |
782 | | friend class MapFieldBase; |
783 | | friend class MapFieldBaseStub; |
784 | | |
785 | | // The table-driven MergePartialFromCodedStream implementation needs to |
786 | | // operate on RepeatedPtrField<MessageLite>. |
787 | | friend class MergePartialFromCodedStreamHelper; |
788 | | friend class AccessorHelper; |
789 | | template <typename T> |
790 | | friend struct google::protobuf::WeakRepeatedPtrField; |
791 | | friend class internal::TcParser; // TODO(jorg): Remove this friend. |
792 | | }; |
793 | | |
794 | | template <typename GenericType> |
795 | | class GenericTypeHandler { |
796 | | public: |
797 | | typedef GenericType Type; |
798 | | using Movable = IsMovable<GenericType>; |
799 | | |
800 | 0 | static inline GenericType* New(Arena* arena) { |
801 | 0 | return Arena::CreateMaybeMessage<Type>(arena); |
802 | 0 | } Unexecuted instantiation: google::protobuf::internal::GenericTypeHandler<google::protobuf::FileDescriptorProto>::New(google::protobuf::Arena*) Unexecuted instantiation: google::protobuf::internal::GenericTypeHandler<google::protobuf::DescriptorProto>::New(google::protobuf::Arena*) Unexecuted instantiation: google::protobuf::internal::GenericTypeHandler<google::protobuf::EnumDescriptorProto>::New(google::protobuf::Arena*) Unexecuted instantiation: google::protobuf::internal::GenericTypeHandler<google::protobuf::ServiceDescriptorProto>::New(google::protobuf::Arena*) Unexecuted instantiation: google::protobuf::internal::GenericTypeHandler<google::protobuf::FieldDescriptorProto>::New(google::protobuf::Arena*) Unexecuted instantiation: google::protobuf::internal::GenericTypeHandler<google::protobuf::DescriptorProto_ExtensionRange>::New(google::protobuf::Arena*) Unexecuted instantiation: google::protobuf::internal::GenericTypeHandler<google::protobuf::OneofDescriptorProto>::New(google::protobuf::Arena*) Unexecuted instantiation: google::protobuf::internal::GenericTypeHandler<google::protobuf::DescriptorProto_ReservedRange>::New(google::protobuf::Arena*) Unexecuted instantiation: google::protobuf::internal::GenericTypeHandler<google::protobuf::UninterpretedOption>::New(google::protobuf::Arena*) Unexecuted instantiation: google::protobuf::internal::GenericTypeHandler<google::protobuf::EnumValueDescriptorProto>::New(google::protobuf::Arena*) Unexecuted instantiation: google::protobuf::internal::GenericTypeHandler<google::protobuf::EnumDescriptorProto_EnumReservedRange>::New(google::protobuf::Arena*) Unexecuted instantiation: google::protobuf::internal::GenericTypeHandler<google::protobuf::MethodDescriptorProto>::New(google::protobuf::Arena*) Unexecuted instantiation: google::protobuf::internal::GenericTypeHandler<google::protobuf::UninterpretedOption_NamePart>::New(google::protobuf::Arena*) Unexecuted instantiation: google::protobuf::internal::GenericTypeHandler<google::protobuf::SourceCodeInfo_Location>::New(google::protobuf::Arena*) Unexecuted instantiation: google::protobuf::internal::GenericTypeHandler<google::protobuf::GeneratedCodeInfo_Annotation>::New(google::protobuf::Arena*) Unexecuted instantiation: google::protobuf::internal::GenericTypeHandler<gifProtoFuzzer::SubBlock>::New(google::protobuf::Arena*) Unexecuted instantiation: google::protobuf::internal::GenericTypeHandler<gifProtoFuzzer::ImageChunk>::New(google::protobuf::Arena*) |
803 | | static inline GenericType* New(Arena* arena, GenericType&& value) { |
804 | | return Arena::Create<GenericType>(arena, std::move(value)); |
805 | | } |
806 | | static inline GenericType* NewFromPrototype(const GenericType* /*prototype*/, |
807 | 0 | Arena* arena = nullptr) { |
808 | 0 | return New(arena); |
809 | 0 | } Unexecuted instantiation: google::protobuf::internal::GenericTypeHandler<google::protobuf::FileDescriptorProto>::NewFromPrototype(google::protobuf::FileDescriptorProto const*, google::protobuf::Arena*) Unexecuted instantiation: google::protobuf::internal::GenericTypeHandler<google::protobuf::DescriptorProto>::NewFromPrototype(google::protobuf::DescriptorProto const*, google::protobuf::Arena*) Unexecuted instantiation: google::protobuf::internal::GenericTypeHandler<google::protobuf::EnumDescriptorProto>::NewFromPrototype(google::protobuf::EnumDescriptorProto const*, google::protobuf::Arena*) Unexecuted instantiation: google::protobuf::internal::GenericTypeHandler<google::protobuf::ServiceDescriptorProto>::NewFromPrototype(google::protobuf::ServiceDescriptorProto const*, google::protobuf::Arena*) Unexecuted instantiation: google::protobuf::internal::GenericTypeHandler<google::protobuf::FieldDescriptorProto>::NewFromPrototype(google::protobuf::FieldDescriptorProto const*, google::protobuf::Arena*) Unexecuted instantiation: google::protobuf::internal::GenericTypeHandler<google::protobuf::DescriptorProto_ExtensionRange>::NewFromPrototype(google::protobuf::DescriptorProto_ExtensionRange const*, google::protobuf::Arena*) Unexecuted instantiation: google::protobuf::internal::GenericTypeHandler<google::protobuf::OneofDescriptorProto>::NewFromPrototype(google::protobuf::OneofDescriptorProto const*, google::protobuf::Arena*) Unexecuted instantiation: google::protobuf::internal::GenericTypeHandler<google::protobuf::DescriptorProto_ReservedRange>::NewFromPrototype(google::protobuf::DescriptorProto_ReservedRange const*, google::protobuf::Arena*) Unexecuted instantiation: google::protobuf::internal::GenericTypeHandler<google::protobuf::UninterpretedOption>::NewFromPrototype(google::protobuf::UninterpretedOption const*, google::protobuf::Arena*) Unexecuted instantiation: google::protobuf::internal::GenericTypeHandler<google::protobuf::EnumValueDescriptorProto>::NewFromPrototype(google::protobuf::EnumValueDescriptorProto const*, google::protobuf::Arena*) Unexecuted instantiation: google::protobuf::internal::GenericTypeHandler<google::protobuf::EnumDescriptorProto_EnumReservedRange>::NewFromPrototype(google::protobuf::EnumDescriptorProto_EnumReservedRange const*, google::protobuf::Arena*) Unexecuted instantiation: google::protobuf::internal::GenericTypeHandler<google::protobuf::MethodDescriptorProto>::NewFromPrototype(google::protobuf::MethodDescriptorProto const*, google::protobuf::Arena*) Unexecuted instantiation: google::protobuf::internal::GenericTypeHandler<google::protobuf::UninterpretedOption_NamePart>::NewFromPrototype(google::protobuf::UninterpretedOption_NamePart const*, google::protobuf::Arena*) Unexecuted instantiation: google::protobuf::internal::GenericTypeHandler<google::protobuf::SourceCodeInfo_Location>::NewFromPrototype(google::protobuf::SourceCodeInfo_Location const*, google::protobuf::Arena*) Unexecuted instantiation: google::protobuf::internal::GenericTypeHandler<google::protobuf::GeneratedCodeInfo_Annotation>::NewFromPrototype(google::protobuf::GeneratedCodeInfo_Annotation const*, google::protobuf::Arena*) Unexecuted instantiation: google::protobuf::internal::GenericTypeHandler<gifProtoFuzzer::SubBlock>::NewFromPrototype(gifProtoFuzzer::SubBlock const*, google::protobuf::Arena*) Unexecuted instantiation: google::protobuf::internal::GenericTypeHandler<gifProtoFuzzer::ImageChunk>::NewFromPrototype(gifProtoFuzzer::ImageChunk const*, google::protobuf::Arena*) |
810 | 0 | static inline void Delete(GenericType* value, Arena* arena) { |
811 | 0 | if (arena == nullptr) { |
812 | 0 | delete value; |
813 | 0 | } |
814 | 0 | } Unexecuted instantiation: google::protobuf::internal::GenericTypeHandler<gifProtoFuzzer::SubBlock>::Delete(gifProtoFuzzer::SubBlock*, google::protobuf::Arena*) Unexecuted instantiation: google::protobuf::internal::GenericTypeHandler<gifProtoFuzzer::ImageChunk>::Delete(gifProtoFuzzer::ImageChunk*, google::protobuf::Arena*) |
815 | | static inline Arena* GetOwningArena(GenericType* value) { |
816 | | return Arena::InternalGetOwningArena(value); |
817 | | } |
818 | | |
819 | 30.7k | static inline void Clear(GenericType* value) { value->Clear(); } Unexecuted instantiation: google::protobuf::internal::GenericTypeHandler<google::protobuf::FileDescriptorProto>::Clear(google::protobuf::FileDescriptorProto*) Unexecuted instantiation: google::protobuf::internal::GenericTypeHandler<google::protobuf::DescriptorProto>::Clear(google::protobuf::DescriptorProto*) Unexecuted instantiation: google::protobuf::internal::GenericTypeHandler<google::protobuf::EnumDescriptorProto>::Clear(google::protobuf::EnumDescriptorProto*) Unexecuted instantiation: google::protobuf::internal::GenericTypeHandler<google::protobuf::ServiceDescriptorProto>::Clear(google::protobuf::ServiceDescriptorProto*) Unexecuted instantiation: google::protobuf::internal::GenericTypeHandler<google::protobuf::FieldDescriptorProto>::Clear(google::protobuf::FieldDescriptorProto*) Unexecuted instantiation: google::protobuf::internal::GenericTypeHandler<google::protobuf::DescriptorProto_ExtensionRange>::Clear(google::protobuf::DescriptorProto_ExtensionRange*) Unexecuted instantiation: google::protobuf::internal::GenericTypeHandler<google::protobuf::OneofDescriptorProto>::Clear(google::protobuf::OneofDescriptorProto*) Unexecuted instantiation: google::protobuf::internal::GenericTypeHandler<google::protobuf::DescriptorProto_ReservedRange>::Clear(google::protobuf::DescriptorProto_ReservedRange*) Unexecuted instantiation: google::protobuf::internal::GenericTypeHandler<google::protobuf::UninterpretedOption>::Clear(google::protobuf::UninterpretedOption*) Unexecuted instantiation: google::protobuf::internal::GenericTypeHandler<google::protobuf::EnumValueDescriptorProto>::Clear(google::protobuf::EnumValueDescriptorProto*) Unexecuted instantiation: google::protobuf::internal::GenericTypeHandler<google::protobuf::EnumDescriptorProto_EnumReservedRange>::Clear(google::protobuf::EnumDescriptorProto_EnumReservedRange*) Unexecuted instantiation: google::protobuf::internal::GenericTypeHandler<google::protobuf::MethodDescriptorProto>::Clear(google::protobuf::MethodDescriptorProto*) Unexecuted instantiation: google::protobuf::internal::GenericTypeHandler<google::protobuf::UninterpretedOption_NamePart>::Clear(google::protobuf::UninterpretedOption_NamePart*) Unexecuted instantiation: google::protobuf::internal::GenericTypeHandler<google::protobuf::SourceCodeInfo_Location>::Clear(google::protobuf::SourceCodeInfo_Location*) Unexecuted instantiation: google::protobuf::internal::GenericTypeHandler<google::protobuf::GeneratedCodeInfo_Annotation>::Clear(google::protobuf::GeneratedCodeInfo_Annotation*) Unexecuted instantiation: google::protobuf::internal::GenericTypeHandler<gifProtoFuzzer::SubBlock>::Clear(gifProtoFuzzer::SubBlock*) google::protobuf::internal::GenericTypeHandler<gifProtoFuzzer::ImageChunk>::Clear(gifProtoFuzzer::ImageChunk*) Line | Count | Source | 819 | 30.7k | static inline void Clear(GenericType* value) { value->Clear(); } |
|
820 | | static void Merge(const GenericType& from, GenericType* to); |
821 | | static inline size_t SpaceUsedLong(const GenericType& value) { |
822 | | return value.SpaceUsedLong(); |
823 | | } |
824 | | }; |
825 | | |
826 | | // NewFromPrototypeHelper() is not defined inline here, as we will need to do a |
827 | | // virtual function dispatch anyways to go from Message* to call New/Merge. (The |
828 | | // additional helper is needed as a workaround for MSVC.) |
829 | | MessageLite* NewFromPrototypeHelper(const MessageLite* prototype, Arena* arena); |
830 | | |
831 | | template <> |
832 | | inline MessageLite* GenericTypeHandler<MessageLite>::NewFromPrototype( |
833 | 0 | const MessageLite* prototype, Arena* arena) { |
834 | 0 | return NewFromPrototypeHelper(prototype, arena); |
835 | 0 | } |
836 | | template <> |
837 | | inline Arena* GenericTypeHandler<MessageLite>::GetOwningArena( |
838 | 0 | MessageLite* value) { |
839 | 0 | return value->GetOwningArena(); |
840 | 0 | } |
841 | | |
842 | | template <typename GenericType> |
843 | | PROTOBUF_NOINLINE inline void GenericTypeHandler<GenericType>::Merge( |
844 | 0 | const GenericType& from, GenericType* to) { |
845 | 0 | to->MergeFrom(from); |
846 | 0 | } Unexecuted instantiation: google::protobuf::internal::GenericTypeHandler<gifProtoFuzzer::SubBlock>::Merge(gifProtoFuzzer::SubBlock const&, gifProtoFuzzer::SubBlock*) Unexecuted instantiation: google::protobuf::internal::GenericTypeHandler<gifProtoFuzzer::ImageChunk>::Merge(gifProtoFuzzer::ImageChunk const&, gifProtoFuzzer::ImageChunk*) |
847 | | template <> |
848 | | void GenericTypeHandler<MessageLite>::Merge(const MessageLite& from, |
849 | | MessageLite* to); |
850 | | |
851 | | template <> |
852 | 0 | inline void GenericTypeHandler<std::string>::Clear(std::string* value) { |
853 | 0 | value->clear(); |
854 | 0 | } |
855 | | template <> |
856 | | void GenericTypeHandler<std::string>::Merge(const std::string& from, |
857 | | std::string* to); |
858 | | |
859 | | // Message specialization bodies defined in message.cc. This split is necessary |
860 | | // to allow proto2-lite (which includes this header) to be independent of |
861 | | // Message. |
862 | | template <> |
863 | | PROTOBUF_EXPORT Message* GenericTypeHandler<Message>::NewFromPrototype( |
864 | | const Message* prototype, Arena* arena); |
865 | | template <> |
866 | | PROTOBUF_EXPORT Arena* GenericTypeHandler<Message>::GetOwningArena( |
867 | | Message* value); |
868 | | |
869 | | class StringTypeHandler { |
870 | | public: |
871 | | typedef std::string Type; |
872 | | using Movable = IsMovable<Type>; |
873 | | |
874 | 0 | static PROTOBUF_NOINLINE std::string* New(Arena* arena) { |
875 | 0 | return Arena::Create<std::string>(arena); |
876 | 0 | } |
877 | 0 | static PROTOBUF_NOINLINE std::string* New(Arena* arena, std::string&& value) { |
878 | 0 | return Arena::Create<std::string>(arena, std::move(value)); |
879 | 0 | } |
880 | | static inline std::string* NewFromPrototype(const std::string*, |
881 | 0 | Arena* arena) { |
882 | 0 | return New(arena); |
883 | 0 | } |
884 | 0 | static inline Arena* GetOwningArena(std::string*) { return nullptr; } |
885 | 0 | static inline void Delete(std::string* value, Arena* arena) { |
886 | 0 | if (arena == nullptr) { |
887 | 0 | delete value; |
888 | 0 | } |
889 | 0 | } |
890 | 0 | static inline void Clear(std::string* value) { value->clear(); } |
891 | 0 | static inline void Merge(const std::string& from, std::string* to) { |
892 | 0 | *to = from; |
893 | 0 | } |
894 | 0 | static size_t SpaceUsedLong(const std::string& value) { |
895 | 0 | return sizeof(value) + StringSpaceUsedExcludingSelfLong(value); |
896 | 0 | } |
897 | | }; |
898 | | |
899 | | } // namespace internal |
900 | | |
901 | | // RepeatedPtrField is like RepeatedField, but used for repeated strings or |
902 | | // Messages. |
903 | | template <typename Element> |
904 | | class RepeatedPtrField final : private internal::RepeatedPtrFieldBase { |
905 | | static_assert(!std::is_const<Element>::value, |
906 | | "We do not support const value types."); |
907 | | static_assert(!std::is_volatile<Element>::value, |
908 | | "We do not support volatile value types."); |
909 | | static_assert(!std::is_pointer<Element>::value, |
910 | | "We do not support pointer value types."); |
911 | | static_assert(!std::is_reference<Element>::value, |
912 | | "We do not support reference value types."); |
913 | 13.7k | static constexpr PROTOBUF_ALWAYS_INLINE void StaticValidityCheck() { |
914 | 13.7k | static_assert( |
915 | 13.7k | absl::disjunction< |
916 | 13.7k | internal::is_supported_string_type<Element>, |
917 | 13.7k | internal::is_supported_message_type<Element>>::value, |
918 | 13.7k | "We only support string and Message types in RepeatedPtrField."); |
919 | 13.7k | } google::protobuf::RepeatedPtrField<gifProtoFuzzer::SubBlock>::StaticValidityCheck() Line | Count | Source | 913 | 11.2k | static constexpr PROTOBUF_ALWAYS_INLINE void StaticValidityCheck() { | 914 | 11.2k | static_assert( | 915 | 11.2k | absl::disjunction< | 916 | 11.2k | internal::is_supported_string_type<Element>, | 917 | 11.2k | internal::is_supported_message_type<Element>>::value, | 918 | 11.2k | "We only support string and Message types in RepeatedPtrField."); | 919 | 11.2k | } |
google::protobuf::RepeatedPtrField<gifProtoFuzzer::ImageChunk>::StaticValidityCheck() Line | Count | Source | 913 | 2.50k | static constexpr PROTOBUF_ALWAYS_INLINE void StaticValidityCheck() { | 914 | 2.50k | static_assert( | 915 | 2.50k | absl::disjunction< | 916 | 2.50k | internal::is_supported_string_type<Element>, | 917 | 2.50k | internal::is_supported_message_type<Element>>::value, | 918 | 2.50k | "We only support string and Message types in RepeatedPtrField."); | 919 | 2.50k | } |
|
920 | | |
921 | | public: |
922 | | constexpr RepeatedPtrField(); |
923 | | explicit RepeatedPtrField(Arena* arena); |
924 | | |
925 | | RepeatedPtrField(const RepeatedPtrField& other); |
926 | | |
927 | | template <typename Iter, |
928 | | typename = typename std::enable_if<std::is_constructible< |
929 | | Element, decltype(*std::declval<Iter>())>::value>::type> |
930 | | RepeatedPtrField(Iter begin, Iter end); |
931 | | |
932 | | ~RepeatedPtrField(); |
933 | | |
934 | | RepeatedPtrField& operator=(const RepeatedPtrField& other); |
935 | | |
936 | | RepeatedPtrField(RepeatedPtrField&& other) noexcept; |
937 | | RepeatedPtrField& operator=(RepeatedPtrField&& other) noexcept; |
938 | | |
939 | | bool empty() const; |
940 | | int size() const; |
941 | | |
942 | | const Element& Get(int index) const; |
943 | | Element* Mutable(int index); |
944 | | |
945 | | // Unlike std::vector, adding an element to a RepeatedPtrField doesn't always |
946 | | // make a new element; it might re-use an element left over from when the |
947 | | // field was Clear()'d or reize()'d smaller. For this reason, Add() is the |
948 | | // fastest API for adding a new element. |
949 | | Element* Add(); |
950 | | |
951 | | // `Add(std::move(value));` is equivalent to `*Add() = std::move(value);` |
952 | | // It will either move-construct to the end of this field, or swap value |
953 | | // with the new-or-recycled element at the end of this field. Note that |
954 | | // this operation is very slow if this RepeatedPtrField is not on the |
955 | | // same Arena, if any, as `value`. |
956 | | void Add(Element&& value); |
957 | | |
958 | | // Copying to the end of this RepeatedPtrField is slowest of all; it can't |
959 | | // reliably copy-construct to the last element of this RepeatedPtrField, for |
960 | | // example (unlike std::vector). |
961 | | // We currently block this API. The right way to add to the end is to call |
962 | | // Add() and modify the element it points to. |
963 | | // If you must add an existing value, call `*Add() = value;` |
964 | | void Add(const Element& value) = delete; |
965 | | |
966 | | // Append elements in the range [begin, end) after reserving |
967 | | // the appropriate number of elements. |
968 | | template <typename Iter> |
969 | | void Add(Iter begin, Iter end); |
970 | | |
971 | | const Element& operator[](int index) const { return Get(index); } |
972 | | Element& operator[](int index) { return *Mutable(index); } |
973 | | |
974 | | const Element& at(int index) const; |
975 | | Element& at(int index); |
976 | | |
977 | | // Removes the last element in the array. |
978 | | // Ownership of the element is retained by the array. |
979 | | void RemoveLast(); |
980 | | |
981 | | // Deletes elements with indices in the range [start .. start+num-1]. |
982 | | // Caution: moves all elements with indices [start+num .. ]. |
983 | | // Calling this routine inside a loop can cause quadratic behavior. |
984 | | void DeleteSubrange(int start, int num); |
985 | | |
986 | | PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear(); |
987 | | void MergeFrom(const RepeatedPtrField& other); |
988 | | PROTOBUF_ATTRIBUTE_REINITIALIZES void CopyFrom(const RepeatedPtrField& other); |
989 | | |
990 | | // Replaces the contents with RepeatedPtrField(begin, end). |
991 | | template <typename Iter> |
992 | | PROTOBUF_ATTRIBUTE_REINITIALIZES void Assign(Iter begin, Iter end); |
993 | | |
994 | | // Reserves space to expand the field to at least the given size. This only |
995 | | // resizes the pointer array; it doesn't allocate any objects. If the |
996 | | // array is grown, it will always be at least doubled in size. |
997 | | void Reserve(int new_size); |
998 | | |
999 | | int Capacity() const; |
1000 | | |
1001 | | // Gets the underlying array. This pointer is possibly invalidated by |
1002 | | // any add or remove operation. |
1003 | | Element** mutable_data(); |
1004 | | const Element* const* data() const; |
1005 | | |
1006 | | // Swaps entire contents with "other". If they are on separate arenas, then |
1007 | | // copies data. |
1008 | | void Swap(RepeatedPtrField* other); |
1009 | | |
1010 | | // Swaps entire contents with "other". Caller should guarantee that either |
1011 | | // both fields are on the same arena or both are on the heap. Swapping between |
1012 | | // different arenas with this function is disallowed and is caught via |
1013 | | // ABSL_DCHECK. |
1014 | | void UnsafeArenaSwap(RepeatedPtrField* other); |
1015 | | |
1016 | | // Swaps two elements. |
1017 | | void SwapElements(int index1, int index2); |
1018 | | |
1019 | | // STL-like iterator support |
1020 | | typedef internal::RepeatedPtrIterator<Element> iterator; |
1021 | | typedef internal::RepeatedPtrIterator<const Element> const_iterator; |
1022 | | typedef Element value_type; |
1023 | | typedef value_type& reference; |
1024 | | typedef const value_type& const_reference; |
1025 | | typedef value_type* pointer; |
1026 | | typedef const value_type* const_pointer; |
1027 | | typedef int size_type; |
1028 | | typedef ptrdiff_t difference_type; |
1029 | | |
1030 | | iterator begin(); |
1031 | | const_iterator begin() const; |
1032 | | const_iterator cbegin() const; |
1033 | | iterator end(); |
1034 | | const_iterator end() const; |
1035 | | const_iterator cend() const; |
1036 | | |
1037 | | // Reverse iterator support |
1038 | | typedef std::reverse_iterator<const_iterator> const_reverse_iterator; |
1039 | | typedef std::reverse_iterator<iterator> reverse_iterator; |
1040 | | reverse_iterator rbegin() { return reverse_iterator(end()); } |
1041 | | const_reverse_iterator rbegin() const { |
1042 | | return const_reverse_iterator(end()); |
1043 | | } |
1044 | | reverse_iterator rend() { return reverse_iterator(begin()); } |
1045 | | const_reverse_iterator rend() const { |
1046 | | return const_reverse_iterator(begin()); |
1047 | | } |
1048 | | |
1049 | | // Custom STL-like iterator that iterates over and returns the underlying |
1050 | | // pointers to Element rather than Element itself. |
1051 | | typedef internal::RepeatedPtrOverPtrsIterator<Element*, void*> |
1052 | | pointer_iterator; |
1053 | | typedef internal::RepeatedPtrOverPtrsIterator<const Element* const, |
1054 | | const void* const> |
1055 | | const_pointer_iterator; |
1056 | | pointer_iterator pointer_begin(); |
1057 | | const_pointer_iterator pointer_begin() const; |
1058 | | pointer_iterator pointer_end(); |
1059 | | const_pointer_iterator pointer_end() const; |
1060 | | |
1061 | | // Returns (an estimate of) the number of bytes used by the repeated field, |
1062 | | // excluding sizeof(*this). |
1063 | | size_t SpaceUsedExcludingSelfLong() const; |
1064 | | |
1065 | | int SpaceUsedExcludingSelf() const { |
1066 | | return internal::ToIntSize(SpaceUsedExcludingSelfLong()); |
1067 | | } |
1068 | | |
1069 | | // Advanced memory management -------------------------------------- |
1070 | | // When hardcore memory management becomes necessary -- as it sometimes |
1071 | | // does here at Google -- the following methods may be useful. |
1072 | | |
1073 | | // Adds an already-allocated object, passing ownership to the |
1074 | | // RepeatedPtrField. |
1075 | | // |
1076 | | // Note that some special behavior occurs with respect to arenas: |
1077 | | // |
1078 | | // (i) if this field holds submessages, the new submessage will be copied if |
1079 | | // the original is in an arena and this RepeatedPtrField is either in a |
1080 | | // different arena, or on the heap. |
1081 | | // (ii) if this field holds strings, the passed-in string *must* be |
1082 | | // heap-allocated, not arena-allocated. There is no way to dynamically check |
1083 | | // this at runtime, so User Beware. |
1084 | | void AddAllocated(Element* value); |
1085 | | |
1086 | | // Removes and returns the last element, passing ownership to the caller. |
1087 | | // Requires: size() > 0 |
1088 | | // |
1089 | | // If this RepeatedPtrField is on an arena, an object copy is required to pass |
1090 | | // ownership back to the user (for compatible semantics). Use |
1091 | | // UnsafeArenaReleaseLast() if this behavior is undesired. |
1092 | | PROTOBUF_NODISCARD Element* ReleaseLast(); |
1093 | | |
1094 | | // Adds an already-allocated object, skipping arena-ownership checks. The user |
1095 | | // must guarantee that the given object is in the same arena as this |
1096 | | // RepeatedPtrField. |
1097 | | // It is also useful in legacy code that uses temporary ownership to avoid |
1098 | | // copies. Example: |
1099 | | // RepeatedPtrField<T> temp_field; |
1100 | | // temp_field.UnsafeArenaAddAllocated(new T); |
1101 | | // ... // Do something with temp_field |
1102 | | // temp_field.UnsafeArenaExtractSubrange(0, temp_field.size(), nullptr); |
1103 | | // If you put temp_field on the arena this fails, because the ownership |
1104 | | // transfers to the arena at the "AddAllocated" call and is not released |
1105 | | // anymore, causing a double delete. UnsafeArenaAddAllocated prevents this. |
1106 | | void UnsafeArenaAddAllocated(Element* value); |
1107 | | |
1108 | | // Removes and returns the last element. Unlike ReleaseLast, the returned |
1109 | | // pointer is always to the original object. This may be in an arena, in |
1110 | | // which case it would have the arena's lifetime. |
1111 | | // Requires: current_size_ > 0 |
1112 | | Element* UnsafeArenaReleaseLast(); |
1113 | | |
1114 | | // Extracts elements with indices in the range "[start .. start+num-1]". |
1115 | | // The caller assumes ownership of the extracted elements and is responsible |
1116 | | // for deleting them when they are no longer needed. |
1117 | | // If "elements" is non-nullptr, then pointers to the extracted elements |
1118 | | // are stored in "elements[0 .. num-1]" for the convenience of the caller. |
1119 | | // If "elements" is nullptr, then the caller must use some other mechanism |
1120 | | // to perform any further operations (like deletion) on these elements. |
1121 | | // Caution: implementation also moves elements with indices [start+num ..]. |
1122 | | // Calling this routine inside a loop can cause quadratic behavior. |
1123 | | // |
1124 | | // Memory copying behavior is identical to ReleaseLast(), described above: if |
1125 | | // this RepeatedPtrField is on an arena, an object copy is performed for each |
1126 | | // returned element, so that all returned element pointers are to |
1127 | | // heap-allocated copies. If this copy is not desired, the user should call |
1128 | | // UnsafeArenaExtractSubrange(). |
1129 | | void ExtractSubrange(int start, int num, Element** elements); |
1130 | | |
1131 | | // Identical to ExtractSubrange() described above, except that no object |
1132 | | // copies are ever performed. Instead, the raw object pointers are returned. |
1133 | | // Thus, if on an arena, the returned objects must not be freed, because they |
1134 | | // will not be heap-allocated objects. |
1135 | | void UnsafeArenaExtractSubrange(int start, int num, Element** elements); |
1136 | | |
1137 | | // When elements are removed by calls to RemoveLast() or Clear(), they |
1138 | | // are not actually freed. Instead, they are cleared and kept so that |
1139 | | // they can be reused later. This can save lots of CPU time when |
1140 | | // repeatedly reusing a protocol message for similar purposes. |
1141 | | // |
1142 | | // Hardcore programs may choose to manipulate these cleared objects |
1143 | | // to better optimize memory management using the following routines. |
1144 | | |
1145 | | // Gets the number of cleared objects that are currently being kept |
1146 | | // around for reuse. |
1147 | | ABSL_DEPRECATED("This will be removed in a future release") |
1148 | | int ClearedCount() const; |
1149 | | |
1150 | | #ifndef PROTOBUF_FUTURE_REMOVE_CLEARED_API |
1151 | | // Adds an element to the pool of cleared objects, passing ownership to |
1152 | | // the RepeatedPtrField. The element must be cleared prior to calling |
1153 | | // this method. |
1154 | | // |
1155 | | // This method cannot be called when either the repeated field or |value| is |
1156 | | // on an arena; both cases will trigger a ABSL_DCHECK-failure. |
1157 | | ABSL_DEPRECATED("This will be removed in a future release") |
1158 | | void AddCleared(Element* value); |
1159 | | // Removes and returns a single element from the cleared pool, passing |
1160 | | // ownership to the caller. The element is guaranteed to be cleared. |
1161 | | // Requires: ClearedCount() > 0 |
1162 | | // |
1163 | | // This method cannot be called when the repeated field is on an arena; doing |
1164 | | // so will trigger a ABSL_DCHECK-failure. |
1165 | | PROTOBUF_NODISCARD |
1166 | | ABSL_DEPRECATED("This will be removed in a future release") |
1167 | | Element* ReleaseCleared(); |
1168 | | #endif // !PROTOBUF_FUTURE_REMOVE_CLEARED_API |
1169 | | |
1170 | | // Removes the element referenced by position. |
1171 | | // |
1172 | | // Returns an iterator to the element immediately following the removed |
1173 | | // element. |
1174 | | // |
1175 | | // Invalidates all iterators at or after the removed element, including end(). |
1176 | | iterator erase(const_iterator position); |
1177 | | |
1178 | | // Removes the elements in the range [first, last). |
1179 | | // |
1180 | | // Returns an iterator to the element immediately following the removed range. |
1181 | | // |
1182 | | // Invalidates all iterators at or after the removed range, including end(). |
1183 | | iterator erase(const_iterator first, const_iterator last); |
1184 | | |
1185 | | // Gets the arena on which this RepeatedPtrField stores its elements. |
1186 | | inline Arena* GetArena(); |
1187 | | |
1188 | | ABSL_DEPRECATED("This will be removed in a future release") |
1189 | | inline Arena* GetArena() const; |
1190 | | |
1191 | | // For internal use only. |
1192 | | // |
1193 | | // This is public due to it being called by generated code. |
1194 | 0 | void InternalSwap(RepeatedPtrField* other) { |
1195 | 0 | internal::RepeatedPtrFieldBase::InternalSwap(other); |
1196 | 0 | } Unexecuted instantiation: google::protobuf::RepeatedPtrField<gifProtoFuzzer::SubBlock>::InternalSwap(google::protobuf::RepeatedPtrField<gifProtoFuzzer::SubBlock>*) Unexecuted instantiation: google::protobuf::RepeatedPtrField<gifProtoFuzzer::ImageChunk>::InternalSwap(google::protobuf::RepeatedPtrField<gifProtoFuzzer::ImageChunk>*) |
1197 | | |
1198 | | private: |
1199 | | // Note: RepeatedPtrField SHOULD NOT be subclassed by users. |
1200 | | class TypeHandler; |
1201 | | |
1202 | | // Internal version of GetArena(). |
1203 | | inline Arena* GetOwningArena() const; |
1204 | | |
1205 | | // Implementations for ExtractSubrange(). The copying behavior must be |
1206 | | // included only if the type supports the necessary operations (e.g., |
1207 | | // MergeFrom()), so we must resolve this at compile time. ExtractSubrange() |
1208 | | // uses SFINAE to choose one of the below implementations. |
1209 | | void ExtractSubrangeInternal(int start, int num, Element** elements, |
1210 | | std::true_type); |
1211 | | void ExtractSubrangeInternal(int start, int num, Element** elements, |
1212 | | std::false_type); |
1213 | | |
1214 | | void AddAllocatedForParse(Element* p) { |
1215 | | return RepeatedPtrFieldBase::AddAllocatedForParse<TypeHandler>(p); |
1216 | | } |
1217 | | |
1218 | | friend class Arena; |
1219 | | friend class internal::TcParser; |
1220 | | |
1221 | | template <typename T> |
1222 | | friend struct WeakRepeatedPtrField; |
1223 | | |
1224 | | typedef void InternalArenaConstructable_; |
1225 | | |
1226 | | }; |
1227 | | |
1228 | | // ------------------------------------------------------------------- |
1229 | | |
1230 | | template <typename Element> |
1231 | | class RepeatedPtrField<Element>::TypeHandler |
1232 | | : public internal::GenericTypeHandler<Element> {}; |
1233 | | |
1234 | | template <> |
1235 | | class RepeatedPtrField<std::string>::TypeHandler |
1236 | | : public internal::StringTypeHandler {}; |
1237 | | |
1238 | | template <typename Element> |
1239 | | constexpr RepeatedPtrField<Element>::RepeatedPtrField() |
1240 | | : RepeatedPtrFieldBase() { |
1241 | | StaticValidityCheck(); |
1242 | | } |
1243 | | |
1244 | | template <typename Element> |
1245 | | inline RepeatedPtrField<Element>::RepeatedPtrField(Arena* arena) |
1246 | 6.85k | : RepeatedPtrFieldBase(arena) { |
1247 | 6.85k | StaticValidityCheck(); |
1248 | 6.85k | } google::protobuf::RepeatedPtrField<gifProtoFuzzer::SubBlock>::RepeatedPtrField(google::protobuf::Arena*) Line | Count | Source | 1246 | 5.60k | : RepeatedPtrFieldBase(arena) { | 1247 | 5.60k | StaticValidityCheck(); | 1248 | 5.60k | } |
google::protobuf::RepeatedPtrField<gifProtoFuzzer::ImageChunk>::RepeatedPtrField(google::protobuf::Arena*) Line | Count | Source | 1246 | 1.25k | : RepeatedPtrFieldBase(arena) { | 1247 | 1.25k | StaticValidityCheck(); | 1248 | 1.25k | } |
|
1249 | | |
1250 | | template <typename Element> |
1251 | | inline RepeatedPtrField<Element>::RepeatedPtrField( |
1252 | | const RepeatedPtrField& other) |
1253 | 0 | : RepeatedPtrFieldBase() { |
1254 | 0 | StaticValidityCheck(); |
1255 | 0 | MergeFrom(other); |
1256 | 0 | } Unexecuted instantiation: google::protobuf::RepeatedPtrField<gifProtoFuzzer::SubBlock>::RepeatedPtrField(google::protobuf::RepeatedPtrField<gifProtoFuzzer::SubBlock> const&) Unexecuted instantiation: google::protobuf::RepeatedPtrField<gifProtoFuzzer::ImageChunk>::RepeatedPtrField(google::protobuf::RepeatedPtrField<gifProtoFuzzer::ImageChunk> const&) |
1257 | | |
1258 | | template <typename Element> |
1259 | | template <typename Iter, typename> |
1260 | | inline RepeatedPtrField<Element>::RepeatedPtrField(Iter begin, Iter end) { |
1261 | | StaticValidityCheck(); |
1262 | | Add(begin, end); |
1263 | | } |
1264 | | |
1265 | | template <typename Element> |
1266 | 6.85k | RepeatedPtrField<Element>::~RepeatedPtrField() { |
1267 | 6.85k | StaticValidityCheck(); |
1268 | | #ifdef __cpp_if_constexpr |
1269 | | if constexpr (std::is_base_of<MessageLite, Element>::value) { |
1270 | | #else |
1271 | 6.85k | if (std::is_base_of<MessageLite, Element>::value) { |
1272 | 6.85k | #endif |
1273 | 6.85k | if (NeedsDestroy()) DestroyProtos(); |
1274 | 6.85k | } else { |
1275 | 0 | Destroy<TypeHandler>(); |
1276 | 0 | } |
1277 | 6.85k | } google::protobuf::RepeatedPtrField<gifProtoFuzzer::SubBlock>::~RepeatedPtrField() Line | Count | Source | 1266 | 5.60k | RepeatedPtrField<Element>::~RepeatedPtrField() { | 1267 | 5.60k | StaticValidityCheck(); | 1268 | | #ifdef __cpp_if_constexpr | 1269 | | if constexpr (std::is_base_of<MessageLite, Element>::value) { | 1270 | | #else | 1271 | 5.60k | if (std::is_base_of<MessageLite, Element>::value) { | 1272 | 5.60k | #endif | 1273 | 5.60k | if (NeedsDestroy()) DestroyProtos(); | 1274 | 5.60k | } else { | 1275 | 0 | Destroy<TypeHandler>(); | 1276 | 0 | } | 1277 | 5.60k | } |
google::protobuf::RepeatedPtrField<gifProtoFuzzer::ImageChunk>::~RepeatedPtrField() Line | Count | Source | 1266 | 1.25k | RepeatedPtrField<Element>::~RepeatedPtrField() { | 1267 | 1.25k | StaticValidityCheck(); | 1268 | | #ifdef __cpp_if_constexpr | 1269 | | if constexpr (std::is_base_of<MessageLite, Element>::value) { | 1270 | | #else | 1271 | 1.25k | if (std::is_base_of<MessageLite, Element>::value) { | 1272 | 1.25k | #endif | 1273 | 1.25k | if (NeedsDestroy()) DestroyProtos(); | 1274 | 1.25k | } else { | 1275 | 0 | Destroy<TypeHandler>(); | 1276 | 0 | } | 1277 | 1.25k | } |
|
1278 | | |
1279 | | template <typename Element> |
1280 | | inline RepeatedPtrField<Element>& RepeatedPtrField<Element>::operator=( |
1281 | | const RepeatedPtrField& other) { |
1282 | | if (this != &other) CopyFrom(other); |
1283 | | return *this; |
1284 | | } |
1285 | | |
1286 | | template <typename Element> |
1287 | | inline RepeatedPtrField<Element>::RepeatedPtrField( |
1288 | | RepeatedPtrField&& other) noexcept |
1289 | | : RepeatedPtrField() { |
1290 | | #ifdef PROTOBUF_FORCE_COPY_IN_MOVE |
1291 | | CopyFrom(other); |
1292 | | #else // PROTOBUF_FORCE_COPY_IN_MOVE |
1293 | | // We don't just call Swap(&other) here because it would perform 3 copies if |
1294 | | // other is on an arena. This field can't be on an arena because arena |
1295 | | // construction always uses the Arena* accepting constructor. |
1296 | | if (other.GetOwningArena()) { |
1297 | | CopyFrom(other); |
1298 | | } else { |
1299 | | InternalSwap(&other); |
1300 | | } |
1301 | | #endif // !PROTOBUF_FORCE_COPY_IN_MOVE |
1302 | | } |
1303 | | |
1304 | | template <typename Element> |
1305 | | inline RepeatedPtrField<Element>& RepeatedPtrField<Element>::operator=( |
1306 | | RepeatedPtrField&& other) noexcept { |
1307 | | // We don't just call Swap(&other) here because it would perform 3 copies if |
1308 | | // the two fields are on different arenas. |
1309 | | if (this != &other) { |
1310 | | if (GetOwningArena() != other.GetOwningArena() |
1311 | | #ifdef PROTOBUF_FORCE_COPY_IN_MOVE |
1312 | | || GetOwningArena() == nullptr |
1313 | | #endif // !PROTOBUF_FORCE_COPY_IN_MOVE |
1314 | | ) { |
1315 | | CopyFrom(other); |
1316 | | } else { |
1317 | | InternalSwap(&other); |
1318 | | } |
1319 | | } |
1320 | | return *this; |
1321 | | } |
1322 | | |
1323 | | template <typename Element> |
1324 | | inline bool RepeatedPtrField<Element>::empty() const { |
1325 | | return RepeatedPtrFieldBase::empty(); |
1326 | | } |
1327 | | |
1328 | | template <typename Element> |
1329 | 5.49k | inline int RepeatedPtrField<Element>::size() const { |
1330 | 5.49k | return RepeatedPtrFieldBase::size(); |
1331 | 5.49k | } Unexecuted instantiation: google::protobuf::RepeatedPtrField<google::protobuf::FileDescriptorProto>::size() const Unexecuted instantiation: google::protobuf::RepeatedPtrField<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >::size() const Unexecuted instantiation: google::protobuf::RepeatedPtrField<google::protobuf::DescriptorProto>::size() const Unexecuted instantiation: google::protobuf::RepeatedPtrField<google::protobuf::EnumDescriptorProto>::size() const Unexecuted instantiation: google::protobuf::RepeatedPtrField<google::protobuf::ServiceDescriptorProto>::size() const Unexecuted instantiation: google::protobuf::RepeatedPtrField<google::protobuf::FieldDescriptorProto>::size() const Unexecuted instantiation: google::protobuf::RepeatedPtrField<google::protobuf::DescriptorProto_ExtensionRange>::size() const Unexecuted instantiation: google::protobuf::RepeatedPtrField<google::protobuf::OneofDescriptorProto>::size() const Unexecuted instantiation: google::protobuf::RepeatedPtrField<google::protobuf::DescriptorProto_ReservedRange>::size() const Unexecuted instantiation: google::protobuf::RepeatedPtrField<google::protobuf::UninterpretedOption>::size() const Unexecuted instantiation: google::protobuf::RepeatedPtrField<google::protobuf::EnumValueDescriptorProto>::size() const Unexecuted instantiation: google::protobuf::RepeatedPtrField<google::protobuf::EnumDescriptorProto_EnumReservedRange>::size() const Unexecuted instantiation: google::protobuf::RepeatedPtrField<google::protobuf::MethodDescriptorProto>::size() const Unexecuted instantiation: google::protobuf::RepeatedPtrField<google::protobuf::UninterpretedOption_NamePart>::size() const Unexecuted instantiation: google::protobuf::RepeatedPtrField<google::protobuf::SourceCodeInfo_Location>::size() const Unexecuted instantiation: google::protobuf::RepeatedPtrField<google::protobuf::GeneratedCodeInfo_Annotation>::size() const google::protobuf::RepeatedPtrField<gifProtoFuzzer::SubBlock>::size() const Line | Count | Source | 1329 | 4.39k | inline int RepeatedPtrField<Element>::size() const { | 1330 | 4.39k | return RepeatedPtrFieldBase::size(); | 1331 | 4.39k | } |
google::protobuf::RepeatedPtrField<gifProtoFuzzer::ImageChunk>::size() const Line | Count | Source | 1329 | 1.09k | inline int RepeatedPtrField<Element>::size() const { | 1330 | 1.09k | return RepeatedPtrFieldBase::size(); | 1331 | 1.09k | } |
|
1332 | | |
1333 | | template <typename Element> |
1334 | 0 | inline const Element& RepeatedPtrField<Element>::Get(int index) const { |
1335 | 0 | return RepeatedPtrFieldBase::Get<TypeHandler>(index); |
1336 | 0 | } Unexecuted instantiation: google::protobuf::RepeatedPtrField<google::protobuf::FileDescriptorProto>::Get(int) const Unexecuted instantiation: google::protobuf::RepeatedPtrField<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >::Get(int) const Unexecuted instantiation: google::protobuf::RepeatedPtrField<google::protobuf::DescriptorProto>::Get(int) const Unexecuted instantiation: google::protobuf::RepeatedPtrField<google::protobuf::EnumDescriptorProto>::Get(int) const Unexecuted instantiation: google::protobuf::RepeatedPtrField<google::protobuf::ServiceDescriptorProto>::Get(int) const Unexecuted instantiation: google::protobuf::RepeatedPtrField<google::protobuf::FieldDescriptorProto>::Get(int) const Unexecuted instantiation: google::protobuf::RepeatedPtrField<google::protobuf::DescriptorProto_ExtensionRange>::Get(int) const Unexecuted instantiation: google::protobuf::RepeatedPtrField<google::protobuf::OneofDescriptorProto>::Get(int) const Unexecuted instantiation: google::protobuf::RepeatedPtrField<google::protobuf::DescriptorProto_ReservedRange>::Get(int) const Unexecuted instantiation: google::protobuf::RepeatedPtrField<google::protobuf::UninterpretedOption>::Get(int) const Unexecuted instantiation: google::protobuf::RepeatedPtrField<google::protobuf::EnumValueDescriptorProto>::Get(int) const Unexecuted instantiation: google::protobuf::RepeatedPtrField<google::protobuf::EnumDescriptorProto_EnumReservedRange>::Get(int) const Unexecuted instantiation: google::protobuf::RepeatedPtrField<google::protobuf::MethodDescriptorProto>::Get(int) const Unexecuted instantiation: google::protobuf::RepeatedPtrField<google::protobuf::UninterpretedOption_NamePart>::Get(int) const Unexecuted instantiation: google::protobuf::RepeatedPtrField<google::protobuf::SourceCodeInfo_Location>::Get(int) const Unexecuted instantiation: google::protobuf::RepeatedPtrField<google::protobuf::GeneratedCodeInfo_Annotation>::Get(int) const Unexecuted instantiation: google::protobuf::RepeatedPtrField<gifProtoFuzzer::SubBlock>::Get(int) const Unexecuted instantiation: google::protobuf::RepeatedPtrField<gifProtoFuzzer::ImageChunk>::Get(int) const |
1337 | | |
1338 | | template <typename Element> |
1339 | | inline const Element& RepeatedPtrField<Element>::at(int index) const { |
1340 | | return RepeatedPtrFieldBase::at<TypeHandler>(index); |
1341 | | } |
1342 | | |
1343 | | template <typename Element> |
1344 | | inline Element& RepeatedPtrField<Element>::at(int index) { |
1345 | | return RepeatedPtrFieldBase::at<TypeHandler>(index); |
1346 | | } |
1347 | | |
1348 | | |
1349 | | template <typename Element> |
1350 | 0 | inline Element* RepeatedPtrField<Element>::Mutable(int index) { |
1351 | 0 | return RepeatedPtrFieldBase::Mutable<TypeHandler>(index); |
1352 | 0 | } Unexecuted instantiation: google::protobuf::RepeatedPtrField<google::protobuf::FileDescriptorProto>::Mutable(int) Unexecuted instantiation: google::protobuf::RepeatedPtrField<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >::Mutable(int) Unexecuted instantiation: google::protobuf::RepeatedPtrField<google::protobuf::DescriptorProto>::Mutable(int) Unexecuted instantiation: google::protobuf::RepeatedPtrField<google::protobuf::EnumDescriptorProto>::Mutable(int) Unexecuted instantiation: google::protobuf::RepeatedPtrField<google::protobuf::ServiceDescriptorProto>::Mutable(int) Unexecuted instantiation: google::protobuf::RepeatedPtrField<google::protobuf::FieldDescriptorProto>::Mutable(int) Unexecuted instantiation: google::protobuf::RepeatedPtrField<google::protobuf::DescriptorProto_ExtensionRange>::Mutable(int) Unexecuted instantiation: google::protobuf::RepeatedPtrField<google::protobuf::OneofDescriptorProto>::Mutable(int) Unexecuted instantiation: google::protobuf::RepeatedPtrField<google::protobuf::DescriptorProto_ReservedRange>::Mutable(int) Unexecuted instantiation: google::protobuf::RepeatedPtrField<google::protobuf::UninterpretedOption>::Mutable(int) Unexecuted instantiation: google::protobuf::RepeatedPtrField<google::protobuf::EnumValueDescriptorProto>::Mutable(int) Unexecuted instantiation: google::protobuf::RepeatedPtrField<google::protobuf::EnumDescriptorProto_EnumReservedRange>::Mutable(int) Unexecuted instantiation: google::protobuf::RepeatedPtrField<google::protobuf::MethodDescriptorProto>::Mutable(int) Unexecuted instantiation: google::protobuf::RepeatedPtrField<google::protobuf::UninterpretedOption_NamePart>::Mutable(int) Unexecuted instantiation: google::protobuf::RepeatedPtrField<google::protobuf::SourceCodeInfo_Location>::Mutable(int) Unexecuted instantiation: google::protobuf::RepeatedPtrField<google::protobuf::GeneratedCodeInfo_Annotation>::Mutable(int) Unexecuted instantiation: google::protobuf::RepeatedPtrField<gifProtoFuzzer::SubBlock>::Mutable(int) Unexecuted instantiation: google::protobuf::RepeatedPtrField<gifProtoFuzzer::ImageChunk>::Mutable(int) |
1353 | | |
1354 | | template <typename Element> |
1355 | 0 | PROTOBUF_NOINLINE Element* RepeatedPtrField<Element>::Add() { |
1356 | 0 | return RepeatedPtrFieldBase::Add<TypeHandler>(); |
1357 | 0 | } Unexecuted instantiation: google::protobuf::RepeatedPtrField<google::protobuf::FileDescriptorProto>::Add() Unexecuted instantiation: google::protobuf::RepeatedPtrField<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >::Add() Unexecuted instantiation: google::protobuf::RepeatedPtrField<google::protobuf::DescriptorProto>::Add() Unexecuted instantiation: google::protobuf::RepeatedPtrField<google::protobuf::EnumDescriptorProto>::Add() Unexecuted instantiation: google::protobuf::RepeatedPtrField<google::protobuf::ServiceDescriptorProto>::Add() Unexecuted instantiation: google::protobuf::RepeatedPtrField<google::protobuf::FieldDescriptorProto>::Add() Unexecuted instantiation: google::protobuf::RepeatedPtrField<google::protobuf::DescriptorProto_ExtensionRange>::Add() Unexecuted instantiation: google::protobuf::RepeatedPtrField<google::protobuf::OneofDescriptorProto>::Add() Unexecuted instantiation: google::protobuf::RepeatedPtrField<google::protobuf::DescriptorProto_ReservedRange>::Add() Unexecuted instantiation: google::protobuf::RepeatedPtrField<google::protobuf::UninterpretedOption>::Add() Unexecuted instantiation: google::protobuf::RepeatedPtrField<google::protobuf::EnumValueDescriptorProto>::Add() Unexecuted instantiation: google::protobuf::RepeatedPtrField<google::protobuf::EnumDescriptorProto_EnumReservedRange>::Add() Unexecuted instantiation: google::protobuf::RepeatedPtrField<google::protobuf::MethodDescriptorProto>::Add() Unexecuted instantiation: google::protobuf::RepeatedPtrField<google::protobuf::UninterpretedOption_NamePart>::Add() Unexecuted instantiation: google::protobuf::RepeatedPtrField<google::protobuf::SourceCodeInfo_Location>::Add() Unexecuted instantiation: google::protobuf::RepeatedPtrField<google::protobuf::GeneratedCodeInfo_Annotation>::Add() Unexecuted instantiation: google::protobuf::RepeatedPtrField<gifProtoFuzzer::SubBlock>::Add() Unexecuted instantiation: google::protobuf::RepeatedPtrField<gifProtoFuzzer::ImageChunk>::Add() |
1358 | | |
1359 | | template <typename Element> |
1360 | 0 | inline void RepeatedPtrField<Element>::Add(Element&& value) { |
1361 | 0 | RepeatedPtrFieldBase::Add<TypeHandler>(std::move(value)); |
1362 | 0 | } |
1363 | | |
1364 | | template <typename Element> |
1365 | | template <typename Iter> |
1366 | | inline void RepeatedPtrField<Element>::Add(Iter begin, Iter end) { |
1367 | | if (std::is_base_of< |
1368 | | std::forward_iterator_tag, |
1369 | | typename std::iterator_traits<Iter>::iterator_category>::value) { |
1370 | | int reserve = static_cast<int>(std::distance(begin, end)); |
1371 | | Reserve(size() + reserve); |
1372 | | } |
1373 | | for (; begin != end; ++begin) { |
1374 | | *Add() = *begin; |
1375 | | } |
1376 | | } |
1377 | | |
1378 | | template <typename Element> |
1379 | | inline void RepeatedPtrField<Element>::RemoveLast() { |
1380 | | RepeatedPtrFieldBase::RemoveLast<TypeHandler>(); |
1381 | | } |
1382 | | |
1383 | | template <typename Element> |
1384 | | inline void RepeatedPtrField<Element>::DeleteSubrange(int start, int num) { |
1385 | | ABSL_DCHECK_GE(start, 0); |
1386 | | ABSL_DCHECK_GE(num, 0); |
1387 | | ABSL_DCHECK_LE(start + num, size()); |
1388 | | for (int i = 0; i < num; ++i) { |
1389 | | RepeatedPtrFieldBase::Delete<TypeHandler>(start + i); |
1390 | | } |
1391 | | UnsafeArenaExtractSubrange(start, num, nullptr); |
1392 | | } |
1393 | | |
1394 | | template <typename Element> |
1395 | | inline void RepeatedPtrField<Element>::ExtractSubrange(int start, int num, |
1396 | | Element** elements) { |
1397 | | typename internal::TypeImplementsMergeBehavior< |
1398 | | typename TypeHandler::Type>::type t; |
1399 | | ExtractSubrangeInternal(start, num, elements, t); |
1400 | | } |
1401 | | |
1402 | | // ExtractSubrange() implementation for types that implement merge/copy |
1403 | | // behavior. |
1404 | | template <typename Element> |
1405 | | inline void RepeatedPtrField<Element>::ExtractSubrangeInternal( |
1406 | | int start, int num, Element** elements, std::true_type) { |
1407 | | ABSL_DCHECK_GE(start, 0); |
1408 | | ABSL_DCHECK_GE(num, 0); |
1409 | | ABSL_DCHECK_LE(start + num, size()); |
1410 | | |
1411 | | if (num == 0) return; |
1412 | | |
1413 | | ABSL_DCHECK_NE(elements, nullptr) |
1414 | | << "Releasing elements without transferring ownership is an unsafe " |
1415 | | "operation. Use UnsafeArenaExtractSubrange."; |
1416 | | if (elements == nullptr) { |
1417 | | CloseGap(start, num); |
1418 | | return; |
1419 | | } |
1420 | | |
1421 | | Arena* arena = GetOwningArena(); |
1422 | | #ifdef PROTOBUF_FORCE_COPY_IN_RELEASE |
1423 | | // Always copy. |
1424 | | for (int i = 0; i < num; ++i) { |
1425 | | elements[i] = copy<TypeHandler>( |
1426 | | RepeatedPtrFieldBase::Mutable<TypeHandler>(i + start)); |
1427 | | } |
1428 | | if (arena == nullptr) { |
1429 | | for (int i = 0; i < num; ++i) { |
1430 | | delete RepeatedPtrFieldBase::Mutable<TypeHandler>(i + start); |
1431 | | } |
1432 | | } |
1433 | | #else // PROTOBUF_FORCE_COPY_IN_RELEASE |
1434 | | // If we're on an arena, we perform a copy for each element so that the |
1435 | | // returned elements are heap-allocated. Otherwise, just forward it. |
1436 | | if (arena != nullptr) { |
1437 | | for (int i = 0; i < num; ++i) { |
1438 | | elements[i] = copy<TypeHandler>( |
1439 | | RepeatedPtrFieldBase::Mutable<TypeHandler>(i + start)); |
1440 | | } |
1441 | | } else { |
1442 | | for (int i = 0; i < num; ++i) { |
1443 | | elements[i] = RepeatedPtrFieldBase::Mutable<TypeHandler>(i + start); |
1444 | | } |
1445 | | } |
1446 | | #endif // !PROTOBUF_FORCE_COPY_IN_RELEASE |
1447 | | CloseGap(start, num); |
1448 | | } |
1449 | | |
1450 | | // ExtractSubrange() implementation for types that do not implement merge/copy |
1451 | | // behavior. |
1452 | | template <typename Element> |
1453 | | inline void RepeatedPtrField<Element>::ExtractSubrangeInternal( |
1454 | | int start, int num, Element** elements, std::false_type) { |
1455 | | // This case is identical to UnsafeArenaExtractSubrange(). However, since |
1456 | | // ExtractSubrange() must return heap-allocated objects by contract, and we |
1457 | | // cannot fulfill this contract if we are an on arena, we must ABSL_DCHECK() |
1458 | | // that we are not on an arena. |
1459 | | ABSL_DCHECK(GetOwningArena() == nullptr) |
1460 | | << "ExtractSubrange() when arena is non-nullptr is only supported when " |
1461 | | << "the Element type supplies a MergeFrom() operation to make copies."; |
1462 | | UnsafeArenaExtractSubrange(start, num, elements); |
1463 | | } |
1464 | | |
1465 | | template <typename Element> |
1466 | | inline void RepeatedPtrField<Element>::UnsafeArenaExtractSubrange( |
1467 | | int start, int num, Element** elements) { |
1468 | | ABSL_DCHECK_GE(start, 0); |
1469 | | ABSL_DCHECK_GE(num, 0); |
1470 | | ABSL_DCHECK_LE(start + num, size()); |
1471 | | |
1472 | | if (num > 0) { |
1473 | | // Save the values of the removed elements if requested. |
1474 | | if (elements != nullptr) { |
1475 | | for (int i = 0; i < num; ++i) { |
1476 | | elements[i] = RepeatedPtrFieldBase::Mutable<TypeHandler>(i + start); |
1477 | | } |
1478 | | } |
1479 | | CloseGap(start, num); |
1480 | | } |
1481 | | } |
1482 | | |
1483 | | template <typename Element> |
1484 | 4.11k | inline void RepeatedPtrField<Element>::Clear() { |
1485 | 4.11k | RepeatedPtrFieldBase::Clear<TypeHandler>(); |
1486 | 4.11k | } Unexecuted instantiation: google::protobuf::RepeatedPtrField<google::protobuf::FileDescriptorProto>::Clear() Unexecuted instantiation: google::protobuf::RepeatedPtrField<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >::Clear() Unexecuted instantiation: google::protobuf::RepeatedPtrField<google::protobuf::DescriptorProto>::Clear() Unexecuted instantiation: google::protobuf::RepeatedPtrField<google::protobuf::EnumDescriptorProto>::Clear() Unexecuted instantiation: google::protobuf::RepeatedPtrField<google::protobuf::ServiceDescriptorProto>::Clear() Unexecuted instantiation: google::protobuf::RepeatedPtrField<google::protobuf::FieldDescriptorProto>::Clear() Unexecuted instantiation: google::protobuf::RepeatedPtrField<google::protobuf::DescriptorProto_ExtensionRange>::Clear() Unexecuted instantiation: google::protobuf::RepeatedPtrField<google::protobuf::OneofDescriptorProto>::Clear() Unexecuted instantiation: google::protobuf::RepeatedPtrField<google::protobuf::DescriptorProto_ReservedRange>::Clear() Unexecuted instantiation: google::protobuf::RepeatedPtrField<google::protobuf::UninterpretedOption>::Clear() Unexecuted instantiation: google::protobuf::RepeatedPtrField<google::protobuf::EnumValueDescriptorProto>::Clear() Unexecuted instantiation: google::protobuf::RepeatedPtrField<google::protobuf::EnumDescriptorProto_EnumReservedRange>::Clear() Unexecuted instantiation: google::protobuf::RepeatedPtrField<google::protobuf::MethodDescriptorProto>::Clear() Unexecuted instantiation: google::protobuf::RepeatedPtrField<google::protobuf::UninterpretedOption_NamePart>::Clear() Unexecuted instantiation: google::protobuf::RepeatedPtrField<google::protobuf::SourceCodeInfo_Location>::Clear() Unexecuted instantiation: google::protobuf::RepeatedPtrField<google::protobuf::GeneratedCodeInfo_Annotation>::Clear() google::protobuf::RepeatedPtrField<gifProtoFuzzer::SubBlock>::Clear() Line | Count | Source | 1484 | 1.46k | inline void RepeatedPtrField<Element>::Clear() { | 1485 | 1.46k | RepeatedPtrFieldBase::Clear<TypeHandler>(); | 1486 | 1.46k | } |
google::protobuf::RepeatedPtrField<gifProtoFuzzer::ImageChunk>::Clear() Line | Count | Source | 1484 | 2.65k | inline void RepeatedPtrField<Element>::Clear() { | 1485 | 2.65k | RepeatedPtrFieldBase::Clear<TypeHandler>(); | 1486 | 2.65k | } |
|
1487 | | |
1488 | | template <typename Element> |
1489 | | inline void RepeatedPtrField<Element>::MergeFrom( |
1490 | 730 | const RepeatedPtrField& other) { |
1491 | 730 | RepeatedPtrFieldBase::MergeFrom<TypeHandler>(other); |
1492 | 730 | } google::protobuf::RepeatedPtrField<gifProtoFuzzer::SubBlock>::MergeFrom(google::protobuf::RepeatedPtrField<gifProtoFuzzer::SubBlock> const&) Line | Count | Source | 1490 | 730 | const RepeatedPtrField& other) { | 1491 | 730 | RepeatedPtrFieldBase::MergeFrom<TypeHandler>(other); | 1492 | 730 | } |
Unexecuted instantiation: google::protobuf::RepeatedPtrField<gifProtoFuzzer::ImageChunk>::MergeFrom(google::protobuf::RepeatedPtrField<gifProtoFuzzer::ImageChunk> const&) |
1493 | | |
1494 | | template <typename Element> |
1495 | 0 | inline void RepeatedPtrField<Element>::CopyFrom(const RepeatedPtrField& other) { |
1496 | 0 | RepeatedPtrFieldBase::CopyFrom<TypeHandler>(other); |
1497 | 0 | } Unexecuted instantiation: google::protobuf::RepeatedPtrField<gifProtoFuzzer::SubBlock>::CopyFrom(google::protobuf::RepeatedPtrField<gifProtoFuzzer::SubBlock> const&) Unexecuted instantiation: google::protobuf::RepeatedPtrField<gifProtoFuzzer::ImageChunk>::CopyFrom(google::protobuf::RepeatedPtrField<gifProtoFuzzer::ImageChunk> const&) |
1498 | | |
1499 | | template <typename Element> |
1500 | | template <typename Iter> |
1501 | | inline void RepeatedPtrField<Element>::Assign(Iter begin, Iter end) { |
1502 | | Clear(); |
1503 | | Add(begin, end); |
1504 | | } |
1505 | | |
1506 | | template <typename Element> |
1507 | | inline typename RepeatedPtrField<Element>::iterator |
1508 | | RepeatedPtrField<Element>::erase(const_iterator position) { |
1509 | | return erase(position, position + 1); |
1510 | | } |
1511 | | |
1512 | | template <typename Element> |
1513 | | inline typename RepeatedPtrField<Element>::iterator |
1514 | | RepeatedPtrField<Element>::erase(const_iterator first, const_iterator last) { |
1515 | | size_type pos_offset = static_cast<size_type>(std::distance(cbegin(), first)); |
1516 | | size_type last_offset = static_cast<size_type>(std::distance(cbegin(), last)); |
1517 | | DeleteSubrange(pos_offset, last_offset - pos_offset); |
1518 | | return begin() + pos_offset; |
1519 | | } |
1520 | | |
1521 | | template <typename Element> |
1522 | | inline Element** RepeatedPtrField<Element>::mutable_data() { |
1523 | | return RepeatedPtrFieldBase::mutable_data<TypeHandler>(); |
1524 | | } |
1525 | | |
1526 | | template <typename Element> |
1527 | | inline const Element* const* RepeatedPtrField<Element>::data() const { |
1528 | | return RepeatedPtrFieldBase::data<TypeHandler>(); |
1529 | | } |
1530 | | |
1531 | | template <typename Element> |
1532 | | inline void RepeatedPtrField<Element>::Swap(RepeatedPtrField* other) { |
1533 | | if (this == other) return; |
1534 | | RepeatedPtrFieldBase::Swap<TypeHandler>(other); |
1535 | | } |
1536 | | |
1537 | | template <typename Element> |
1538 | | inline void RepeatedPtrField<Element>::UnsafeArenaSwap( |
1539 | | RepeatedPtrField* other) { |
1540 | | if (this == other) return; |
1541 | | ABSL_DCHECK_EQ(GetOwningArena(), other->GetOwningArena()); |
1542 | | RepeatedPtrFieldBase::InternalSwap(other); |
1543 | | } |
1544 | | |
1545 | | template <typename Element> |
1546 | | inline void RepeatedPtrField<Element>::SwapElements(int index1, int index2) { |
1547 | | RepeatedPtrFieldBase::SwapElements(index1, index2); |
1548 | | } |
1549 | | |
1550 | | template <typename Element> |
1551 | | inline Arena* RepeatedPtrField<Element>::GetArena() { |
1552 | | return RepeatedPtrFieldBase::GetArena(); |
1553 | | } |
1554 | | |
1555 | | template <typename Element> |
1556 | | inline Arena* RepeatedPtrField<Element>::GetArena() const { |
1557 | | return RepeatedPtrFieldBase::GetArena(); |
1558 | | } |
1559 | | |
1560 | | template <typename Element> |
1561 | 0 | inline Arena* RepeatedPtrField<Element>::GetOwningArena() const { |
1562 | 0 | return RepeatedPtrFieldBase::GetOwningArena(); |
1563 | 0 | } Unexecuted instantiation: google::protobuf::RepeatedPtrField<gifProtoFuzzer::SubBlock>::GetOwningArena() const Unexecuted instantiation: google::protobuf::RepeatedPtrField<gifProtoFuzzer::ImageChunk>::GetOwningArena() const |
1564 | | |
1565 | | template <typename Element> |
1566 | | inline size_t RepeatedPtrField<Element>::SpaceUsedExcludingSelfLong() const { |
1567 | | return RepeatedPtrFieldBase::SpaceUsedExcludingSelfLong<TypeHandler>(); |
1568 | | } |
1569 | | |
1570 | | template <typename Element> |
1571 | | inline void RepeatedPtrField<Element>::AddAllocated(Element* value) { |
1572 | | RepeatedPtrFieldBase::AddAllocated<TypeHandler>(value); |
1573 | | } |
1574 | | |
1575 | | template <typename Element> |
1576 | | inline void RepeatedPtrField<Element>::UnsafeArenaAddAllocated(Element* value) { |
1577 | | RepeatedPtrFieldBase::UnsafeArenaAddAllocated<TypeHandler>(value); |
1578 | | } |
1579 | | |
1580 | | template <typename Element> |
1581 | | inline Element* RepeatedPtrField<Element>::ReleaseLast() { |
1582 | | return RepeatedPtrFieldBase::ReleaseLast<TypeHandler>(); |
1583 | | } |
1584 | | |
1585 | | template <typename Element> |
1586 | | inline Element* RepeatedPtrField<Element>::UnsafeArenaReleaseLast() { |
1587 | | return RepeatedPtrFieldBase::UnsafeArenaReleaseLast<TypeHandler>(); |
1588 | | } |
1589 | | |
1590 | | template <typename Element> |
1591 | | inline int RepeatedPtrField<Element>::ClearedCount() const { |
1592 | | return RepeatedPtrFieldBase::ClearedCount(); |
1593 | | } |
1594 | | |
1595 | | #ifndef PROTOBUF_FUTURE_REMOVE_CLEARED_API |
1596 | | template <typename Element> |
1597 | | inline void RepeatedPtrField<Element>::AddCleared(Element* value) { |
1598 | | return RepeatedPtrFieldBase::AddCleared<TypeHandler>(value); |
1599 | | } |
1600 | | |
1601 | | template <typename Element> |
1602 | | inline Element* RepeatedPtrField<Element>::ReleaseCleared() { |
1603 | | return RepeatedPtrFieldBase::ReleaseCleared<TypeHandler>(); |
1604 | | } |
1605 | | #endif // !PROTOBUF_FUTURE_REMOVE_CLEARED_API |
1606 | | |
1607 | | template <typename Element> |
1608 | | inline void RepeatedPtrField<Element>::Reserve(int new_size) { |
1609 | | return RepeatedPtrFieldBase::Reserve(new_size); |
1610 | | } |
1611 | | |
1612 | | template <typename Element> |
1613 | | inline int RepeatedPtrField<Element>::Capacity() const { |
1614 | | return RepeatedPtrFieldBase::Capacity(); |
1615 | | } |
1616 | | |
1617 | | // ------------------------------------------------------------------- |
1618 | | |
1619 | | namespace internal { |
1620 | | |
1621 | | // STL-like iterator implementation for RepeatedPtrField. You should not |
1622 | | // refer to this class directly; use RepeatedPtrField<T>::iterator instead. |
1623 | | // |
1624 | | // The iterator for RepeatedPtrField<T>, RepeatedPtrIterator<T>, is |
1625 | | // very similar to iterator_ptr<T**> in util/gtl/iterator_adaptors.h, |
1626 | | // but adds random-access operators and is modified to wrap a void** base |
1627 | | // iterator (since RepeatedPtrField stores its array as a void* array and |
1628 | | // casting void** to T** would violate C++ aliasing rules). |
1629 | | // |
1630 | | // This code based on net/proto/proto-array-internal.h by Jeffrey Yasskin |
1631 | | // (jyasskin@google.com). |
1632 | | template <typename Element> |
1633 | | class RepeatedPtrIterator { |
1634 | | public: |
1635 | | using iterator = RepeatedPtrIterator<Element>; |
1636 | | using iterator_category = std::random_access_iterator_tag; |
1637 | | using value_type = typename std::remove_const<Element>::type; |
1638 | | using difference_type = std::ptrdiff_t; |
1639 | | using pointer = Element*; |
1640 | | using reference = Element&; |
1641 | | |
1642 | | RepeatedPtrIterator() : it_(nullptr) {} |
1643 | 10.9k | explicit RepeatedPtrIterator(void* const* it) : it_(it) {} google::protobuf::internal::RepeatedPtrIterator<gifProtoFuzzer::SubBlock>::RepeatedPtrIterator(void* const*) Line | Count | Source | 1643 | 8.79k | explicit RepeatedPtrIterator(void* const* it) : it_(it) {} |
google::protobuf::internal::RepeatedPtrIterator<gifProtoFuzzer::ImageChunk>::RepeatedPtrIterator(void* const*) Line | Count | Source | 1643 | 2.18k | explicit RepeatedPtrIterator(void* const* it) : it_(it) {} |
|
1644 | | |
1645 | | // Allows "upcasting" from RepeatedPtrIterator<T**> to |
1646 | | // RepeatedPtrIterator<const T*const*>. |
1647 | | template <typename OtherElement, |
1648 | | typename std::enable_if<std::is_convertible< |
1649 | | OtherElement*, pointer>::value>::type* = nullptr> |
1650 | | RepeatedPtrIterator(const RepeatedPtrIterator<OtherElement>& other) |
1651 | 10.9k | : it_(other.it_) {} google::protobuf::internal::RepeatedPtrIterator<gifProtoFuzzer::SubBlock const>::RepeatedPtrIterator<gifProtoFuzzer::SubBlock, (void*)0>(google::protobuf::internal::RepeatedPtrIterator<gifProtoFuzzer::SubBlock> const&) Line | Count | Source | 1651 | 8.79k | : it_(other.it_) {} |
google::protobuf::internal::RepeatedPtrIterator<gifProtoFuzzer::ImageChunk const>::RepeatedPtrIterator<gifProtoFuzzer::ImageChunk, (void*)0>(google::protobuf::internal::RepeatedPtrIterator<gifProtoFuzzer::ImageChunk> const&) Line | Count | Source | 1651 | 2.18k | : it_(other.it_) {} |
|
1652 | | |
1653 | | // dereferenceable |
1654 | 64.7k | reference operator*() const { return *reinterpret_cast<Element*>(*it_); } google::protobuf::internal::RepeatedPtrIterator<gifProtoFuzzer::SubBlock const>::operator*() const Line | Count | Source | 1654 | 59.7k | reference operator*() const { return *reinterpret_cast<Element*>(*it_); } |
google::protobuf::internal::RepeatedPtrIterator<gifProtoFuzzer::ImageChunk const>::operator*() const Line | Count | Source | 1654 | 5.06k | reference operator*() const { return *reinterpret_cast<Element*>(*it_); } |
|
1655 | | pointer operator->() const { return &(operator*()); } |
1656 | | |
1657 | | // {inc,dec}rementable |
1658 | 64.7k | iterator& operator++() { |
1659 | 64.7k | ++it_; |
1660 | 64.7k | return *this; |
1661 | 64.7k | } google::protobuf::internal::RepeatedPtrIterator<gifProtoFuzzer::SubBlock const>::operator++() Line | Count | Source | 1658 | 59.7k | iterator& operator++() { | 1659 | 59.7k | ++it_; | 1660 | 59.7k | return *this; | 1661 | 59.7k | } |
google::protobuf::internal::RepeatedPtrIterator<gifProtoFuzzer::ImageChunk const>::operator++() Line | Count | Source | 1658 | 5.06k | iterator& operator++() { | 1659 | 5.06k | ++it_; | 1660 | 5.06k | return *this; | 1661 | 5.06k | } |
|
1662 | | iterator operator++(int) { return iterator(it_++); } |
1663 | | iterator& operator--() { |
1664 | | --it_; |
1665 | | return *this; |
1666 | | } |
1667 | | iterator operator--(int) { return iterator(it_--); } |
1668 | | |
1669 | | // equality_comparable |
1670 | | friend bool operator==(const iterator& x, const iterator& y) { |
1671 | | return x.it_ == y.it_; |
1672 | | } |
1673 | 70.2k | friend bool operator!=(const iterator& x, const iterator& y) { |
1674 | 70.2k | return x.it_ != y.it_; |
1675 | 70.2k | } google::protobuf::internal::operator!=(google::protobuf::internal::RepeatedPtrIterator<gifProtoFuzzer::SubBlock const> const&, google::protobuf::internal::RepeatedPtrIterator<gifProtoFuzzer::SubBlock const> const&) Line | Count | Source | 1673 | 64.1k | friend bool operator!=(const iterator& x, const iterator& y) { | 1674 | 64.1k | return x.it_ != y.it_; | 1675 | 64.1k | } |
google::protobuf::internal::operator!=(google::protobuf::internal::RepeatedPtrIterator<gifProtoFuzzer::ImageChunk const> const&, google::protobuf::internal::RepeatedPtrIterator<gifProtoFuzzer::ImageChunk const> const&) Line | Count | Source | 1673 | 6.15k | friend bool operator!=(const iterator& x, const iterator& y) { | 1674 | 6.15k | return x.it_ != y.it_; | 1675 | 6.15k | } |
|
1676 | | |
1677 | | // less_than_comparable |
1678 | | friend bool operator<(const iterator& x, const iterator& y) { |
1679 | | return x.it_ < y.it_; |
1680 | | } |
1681 | | friend bool operator<=(const iterator& x, const iterator& y) { |
1682 | | return x.it_ <= y.it_; |
1683 | | } |
1684 | | friend bool operator>(const iterator& x, const iterator& y) { |
1685 | | return x.it_ > y.it_; |
1686 | | } |
1687 | | friend bool operator>=(const iterator& x, const iterator& y) { |
1688 | | return x.it_ >= y.it_; |
1689 | | } |
1690 | | |
1691 | | // addable, subtractable |
1692 | | iterator& operator+=(difference_type d) { |
1693 | | it_ += d; |
1694 | | return *this; |
1695 | | } |
1696 | | friend iterator operator+(iterator it, const difference_type d) { |
1697 | | it += d; |
1698 | | return it; |
1699 | | } |
1700 | | friend iterator operator+(const difference_type d, iterator it) { |
1701 | | it += d; |
1702 | | return it; |
1703 | | } |
1704 | | iterator& operator-=(difference_type d) { |
1705 | | it_ -= d; |
1706 | | return *this; |
1707 | | } |
1708 | | friend iterator operator-(iterator it, difference_type d) { |
1709 | | it -= d; |
1710 | | return it; |
1711 | | } |
1712 | | |
1713 | | // indexable |
1714 | | reference operator[](difference_type d) const { return *(*this + d); } |
1715 | | |
1716 | | // random access iterator |
1717 | | friend difference_type operator-(iterator it1, iterator it2) { |
1718 | | return it1.it_ - it2.it_; |
1719 | | } |
1720 | | |
1721 | | private: |
1722 | | template <typename OtherElement> |
1723 | | friend class RepeatedPtrIterator; |
1724 | | |
1725 | | // The internal iterator. |
1726 | | void* const* it_; |
1727 | | }; |
1728 | | |
1729 | | // Provides an iterator that operates on pointers to the underlying objects |
1730 | | // rather than the objects themselves as RepeatedPtrIterator does. |
1731 | | // Consider using this when working with stl algorithms that change |
1732 | | // the array. |
1733 | | // The VoidPtr template parameter holds the type-agnostic pointer value |
1734 | | // referenced by the iterator. It should either be "void *" for a mutable |
1735 | | // iterator, or "const void* const" for a constant iterator. |
1736 | | template <typename Element, typename VoidPtr> |
1737 | | class RepeatedPtrOverPtrsIterator { |
1738 | | public: |
1739 | | using iterator = RepeatedPtrOverPtrsIterator<Element, VoidPtr>; |
1740 | | using iterator_category = std::random_access_iterator_tag; |
1741 | | using value_type = typename std::remove_const<Element>::type; |
1742 | | using difference_type = std::ptrdiff_t; |
1743 | | using pointer = Element*; |
1744 | | using reference = Element&; |
1745 | | |
1746 | | RepeatedPtrOverPtrsIterator() : it_(nullptr) {} |
1747 | | explicit RepeatedPtrOverPtrsIterator(VoidPtr* it) : it_(it) {} |
1748 | | |
1749 | | // Allows "upcasting" from RepeatedPtrOverPtrsIterator<T**> to |
1750 | | // RepeatedPtrOverPtrsIterator<const T*const*>. |
1751 | | template < |
1752 | | typename OtherElement, typename OtherVoidPtr, |
1753 | | typename std::enable_if< |
1754 | | std::is_convertible<OtherElement*, pointer>::value && |
1755 | | std::is_convertible<OtherVoidPtr*, VoidPtr>::value>::type* = nullptr> |
1756 | | RepeatedPtrOverPtrsIterator( |
1757 | | const RepeatedPtrOverPtrsIterator<OtherElement, OtherVoidPtr>& other) |
1758 | | : it_(other.it_) {} |
1759 | | |
1760 | | // dereferenceable |
1761 | | reference operator*() const { return *reinterpret_cast<Element*>(it_); } |
1762 | | pointer operator->() const { return &(operator*()); } |
1763 | | |
1764 | | // {inc,dec}rementable |
1765 | | iterator& operator++() { |
1766 | | ++it_; |
1767 | | return *this; |
1768 | | } |
1769 | | iterator operator++(int) { return iterator(it_++); } |
1770 | | iterator& operator--() { |
1771 | | --it_; |
1772 | | return *this; |
1773 | | } |
1774 | | iterator operator--(int) { return iterator(it_--); } |
1775 | | |
1776 | | // equality_comparable |
1777 | | friend bool operator==(const iterator& x, const iterator& y) { |
1778 | | return x.it_ == y.it_; |
1779 | | } |
1780 | | friend bool operator!=(const iterator& x, const iterator& y) { |
1781 | | return x.it_ != y.it_; |
1782 | | } |
1783 | | |
1784 | | // less_than_comparable |
1785 | | friend bool operator<(const iterator& x, const iterator& y) { |
1786 | | return x.it_ < y.it_; |
1787 | | } |
1788 | | friend bool operator<=(const iterator& x, const iterator& y) { |
1789 | | return x.it_ <= y.it_; |
1790 | | } |
1791 | | friend bool operator>(const iterator& x, const iterator& y) { |
1792 | | return x.it_ > y.it_; |
1793 | | } |
1794 | | friend bool operator>=(const iterator& x, const iterator& y) { |
1795 | | return x.it_ >= y.it_; |
1796 | | } |
1797 | | |
1798 | | // addable, subtractable |
1799 | | iterator& operator+=(difference_type d) { |
1800 | | it_ += d; |
1801 | | return *this; |
1802 | | } |
1803 | | friend iterator operator+(iterator it, difference_type d) { |
1804 | | it += d; |
1805 | | return it; |
1806 | | } |
1807 | | friend iterator operator+(difference_type d, iterator it) { |
1808 | | it += d; |
1809 | | return it; |
1810 | | } |
1811 | | iterator& operator-=(difference_type d) { |
1812 | | it_ -= d; |
1813 | | return *this; |
1814 | | } |
1815 | | friend iterator operator-(iterator it, difference_type d) { |
1816 | | it -= d; |
1817 | | return it; |
1818 | | } |
1819 | | |
1820 | | // indexable |
1821 | | reference operator[](difference_type d) const { return *(*this + d); } |
1822 | | |
1823 | | // random access iterator |
1824 | | friend difference_type operator-(iterator it1, iterator it2) { |
1825 | | return it1.it_ - it2.it_; |
1826 | | } |
1827 | | |
1828 | | private: |
1829 | | template <typename OtherElement, typename OtherVoidPtr> |
1830 | | friend class RepeatedPtrOverPtrsIterator; |
1831 | | |
1832 | | // The internal iterator. |
1833 | | VoidPtr* it_; |
1834 | | }; |
1835 | | |
1836 | | } // namespace internal |
1837 | | |
1838 | | template <typename Element> |
1839 | | inline typename RepeatedPtrField<Element>::iterator |
1840 | | RepeatedPtrField<Element>::begin() { |
1841 | | return iterator(raw_data()); |
1842 | | } |
1843 | | template <typename Element> |
1844 | | inline typename RepeatedPtrField<Element>::const_iterator |
1845 | 5.49k | RepeatedPtrField<Element>::begin() const { |
1846 | 5.49k | return iterator(raw_data()); |
1847 | 5.49k | } google::protobuf::RepeatedPtrField<gifProtoFuzzer::SubBlock>::begin() const Line | Count | Source | 1845 | 4.39k | RepeatedPtrField<Element>::begin() const { | 1846 | 4.39k | return iterator(raw_data()); | 1847 | 4.39k | } |
google::protobuf::RepeatedPtrField<gifProtoFuzzer::ImageChunk>::begin() const Line | Count | Source | 1845 | 1.09k | RepeatedPtrField<Element>::begin() const { | 1846 | 1.09k | return iterator(raw_data()); | 1847 | 1.09k | } |
|
1848 | | template <typename Element> |
1849 | | inline typename RepeatedPtrField<Element>::const_iterator |
1850 | | RepeatedPtrField<Element>::cbegin() const { |
1851 | | return begin(); |
1852 | | } |
1853 | | template <typename Element> |
1854 | | inline typename RepeatedPtrField<Element>::iterator |
1855 | | RepeatedPtrField<Element>::end() { |
1856 | | return iterator(raw_data() + size()); |
1857 | | } |
1858 | | template <typename Element> |
1859 | | inline typename RepeatedPtrField<Element>::const_iterator |
1860 | 5.49k | RepeatedPtrField<Element>::end() const { |
1861 | 5.49k | return iterator(raw_data() + size()); |
1862 | 5.49k | } google::protobuf::RepeatedPtrField<gifProtoFuzzer::SubBlock>::end() const Line | Count | Source | 1860 | 4.39k | RepeatedPtrField<Element>::end() const { | 1861 | 4.39k | return iterator(raw_data() + size()); | 1862 | 4.39k | } |
google::protobuf::RepeatedPtrField<gifProtoFuzzer::ImageChunk>::end() const Line | Count | Source | 1860 | 1.09k | RepeatedPtrField<Element>::end() const { | 1861 | 1.09k | return iterator(raw_data() + size()); | 1862 | 1.09k | } |
|
1863 | | template <typename Element> |
1864 | | inline typename RepeatedPtrField<Element>::const_iterator |
1865 | | RepeatedPtrField<Element>::cend() const { |
1866 | | return end(); |
1867 | | } |
1868 | | |
1869 | | template <typename Element> |
1870 | | inline typename RepeatedPtrField<Element>::pointer_iterator |
1871 | | RepeatedPtrField<Element>::pointer_begin() { |
1872 | | return pointer_iterator(raw_mutable_data()); |
1873 | | } |
1874 | | template <typename Element> |
1875 | | inline typename RepeatedPtrField<Element>::const_pointer_iterator |
1876 | | RepeatedPtrField<Element>::pointer_begin() const { |
1877 | | return const_pointer_iterator(const_cast<const void* const*>(raw_data())); |
1878 | | } |
1879 | | template <typename Element> |
1880 | | inline typename RepeatedPtrField<Element>::pointer_iterator |
1881 | | RepeatedPtrField<Element>::pointer_end() { |
1882 | | return pointer_iterator(raw_mutable_data() + size()); |
1883 | | } |
1884 | | template <typename Element> |
1885 | | inline typename RepeatedPtrField<Element>::const_pointer_iterator |
1886 | | RepeatedPtrField<Element>::pointer_end() const { |
1887 | | return const_pointer_iterator( |
1888 | | const_cast<const void* const*>(raw_data() + size())); |
1889 | | } |
1890 | | |
1891 | | // Iterators and helper functions that follow the spirit of the STL |
1892 | | // std::back_insert_iterator and std::back_inserter but are tailor-made |
1893 | | // for RepeatedField and RepeatedPtrField. Typical usage would be: |
1894 | | // |
1895 | | // std::copy(some_sequence.begin(), some_sequence.end(), |
1896 | | // RepeatedFieldBackInserter(proto.mutable_sequence())); |
1897 | | // |
1898 | | // Ported by johannes from util/gtl/proto-array-iterators.h |
1899 | | |
1900 | | namespace internal { |
1901 | | |
1902 | | // A back inserter for RepeatedPtrField objects. |
1903 | | template <typename T> |
1904 | | class RepeatedPtrFieldBackInsertIterator { |
1905 | | public: |
1906 | | using iterator_category = std::output_iterator_tag; |
1907 | | using value_type = T; |
1908 | | using pointer = void; |
1909 | | using reference = void; |
1910 | | using difference_type = std::ptrdiff_t; |
1911 | | |
1912 | | RepeatedPtrFieldBackInsertIterator(RepeatedPtrField<T>* const mutable_field) |
1913 | | : field_(mutable_field) {} |
1914 | | RepeatedPtrFieldBackInsertIterator<T>& operator=(const T& value) { |
1915 | | *field_->Add() = value; |
1916 | | return *this; |
1917 | | } |
1918 | | RepeatedPtrFieldBackInsertIterator<T>& operator=( |
1919 | | const T* const ptr_to_value) { |
1920 | | *field_->Add() = *ptr_to_value; |
1921 | | return *this; |
1922 | | } |
1923 | | RepeatedPtrFieldBackInsertIterator<T>& operator=(T&& value) { |
1924 | | *field_->Add() = std::move(value); |
1925 | | return *this; |
1926 | | } |
1927 | | RepeatedPtrFieldBackInsertIterator<T>& operator*() { return *this; } |
1928 | | RepeatedPtrFieldBackInsertIterator<T>& operator++() { return *this; } |
1929 | | RepeatedPtrFieldBackInsertIterator<T>& operator++(int /* unused */) { |
1930 | | return *this; |
1931 | | } |
1932 | | |
1933 | | private: |
1934 | | RepeatedPtrField<T>* field_; |
1935 | | }; |
1936 | | |
1937 | | // A back inserter for RepeatedPtrFields that inserts by transferring ownership |
1938 | | // of a pointer. |
1939 | | template <typename T> |
1940 | | class AllocatedRepeatedPtrFieldBackInsertIterator { |
1941 | | public: |
1942 | | using iterator_category = std::output_iterator_tag; |
1943 | | using value_type = T; |
1944 | | using pointer = void; |
1945 | | using reference = void; |
1946 | | using difference_type = std::ptrdiff_t; |
1947 | | |
1948 | | explicit AllocatedRepeatedPtrFieldBackInsertIterator( |
1949 | | RepeatedPtrField<T>* const mutable_field) |
1950 | | : field_(mutable_field) {} |
1951 | | AllocatedRepeatedPtrFieldBackInsertIterator<T>& operator=( |
1952 | | T* const ptr_to_value) { |
1953 | | field_->AddAllocated(ptr_to_value); |
1954 | | return *this; |
1955 | | } |
1956 | | AllocatedRepeatedPtrFieldBackInsertIterator<T>& operator*() { return *this; } |
1957 | | AllocatedRepeatedPtrFieldBackInsertIterator<T>& operator++() { return *this; } |
1958 | | AllocatedRepeatedPtrFieldBackInsertIterator<T>& operator++(int /* unused */) { |
1959 | | return *this; |
1960 | | } |
1961 | | |
1962 | | private: |
1963 | | RepeatedPtrField<T>* field_; |
1964 | | }; |
1965 | | |
1966 | | // Almost identical to AllocatedRepeatedPtrFieldBackInsertIterator. This one |
1967 | | // uses the UnsafeArenaAddAllocated instead. |
1968 | | template <typename T> |
1969 | | class UnsafeArenaAllocatedRepeatedPtrFieldBackInsertIterator { |
1970 | | public: |
1971 | | using iterator_category = std::output_iterator_tag; |
1972 | | using value_type = T; |
1973 | | using pointer = void; |
1974 | | using reference = void; |
1975 | | using difference_type = std::ptrdiff_t; |
1976 | | |
1977 | | explicit UnsafeArenaAllocatedRepeatedPtrFieldBackInsertIterator( |
1978 | | RepeatedPtrField<T>* const mutable_field) |
1979 | | : field_(mutable_field) {} |
1980 | | UnsafeArenaAllocatedRepeatedPtrFieldBackInsertIterator<T>& operator=( |
1981 | | T const* const ptr_to_value) { |
1982 | | field_->UnsafeArenaAddAllocated(const_cast<T*>(ptr_to_value)); |
1983 | | return *this; |
1984 | | } |
1985 | | UnsafeArenaAllocatedRepeatedPtrFieldBackInsertIterator<T>& operator*() { |
1986 | | return *this; |
1987 | | } |
1988 | | UnsafeArenaAllocatedRepeatedPtrFieldBackInsertIterator<T>& operator++() { |
1989 | | return *this; |
1990 | | } |
1991 | | UnsafeArenaAllocatedRepeatedPtrFieldBackInsertIterator<T>& operator++( |
1992 | | int /* unused */) { |
1993 | | return *this; |
1994 | | } |
1995 | | |
1996 | | private: |
1997 | | RepeatedPtrField<T>* field_; |
1998 | | }; |
1999 | | |
2000 | | } // namespace internal |
2001 | | |
2002 | | // Provides a back insert iterator for RepeatedPtrField instances, |
2003 | | // similar to std::back_inserter(). |
2004 | | template <typename T> |
2005 | | internal::RepeatedPtrFieldBackInsertIterator<T> RepeatedPtrFieldBackInserter( |
2006 | | RepeatedPtrField<T>* const mutable_field) { |
2007 | | return internal::RepeatedPtrFieldBackInsertIterator<T>(mutable_field); |
2008 | | } |
2009 | | |
2010 | | // Special back insert iterator for RepeatedPtrField instances, just in |
2011 | | // case someone wants to write generic template code that can access both |
2012 | | // RepeatedFields and RepeatedPtrFields using a common name. |
2013 | | template <typename T> |
2014 | | internal::RepeatedPtrFieldBackInsertIterator<T> RepeatedFieldBackInserter( |
2015 | | RepeatedPtrField<T>* const mutable_field) { |
2016 | | return internal::RepeatedPtrFieldBackInsertIterator<T>(mutable_field); |
2017 | | } |
2018 | | |
2019 | | // Provides a back insert iterator for RepeatedPtrField instances |
2020 | | // similar to std::back_inserter() which transfers the ownership while |
2021 | | // copying elements. |
2022 | | template <typename T> |
2023 | | internal::AllocatedRepeatedPtrFieldBackInsertIterator<T> |
2024 | | AllocatedRepeatedPtrFieldBackInserter( |
2025 | | RepeatedPtrField<T>* const mutable_field) { |
2026 | | return internal::AllocatedRepeatedPtrFieldBackInsertIterator<T>( |
2027 | | mutable_field); |
2028 | | } |
2029 | | |
2030 | | // Similar to AllocatedRepeatedPtrFieldBackInserter, using |
2031 | | // UnsafeArenaAddAllocated instead of AddAllocated. |
2032 | | // This is slightly faster if that matters. It is also useful in legacy code |
2033 | | // that uses temporary ownership to avoid copies. Example: |
2034 | | // RepeatedPtrField<T> temp_field; |
2035 | | // temp_field.UnsafeArenaAddAllocated(new T); |
2036 | | // ... // Do something with temp_field |
2037 | | // temp_field.UnsafeArenaExtractSubrange(0, temp_field.size(), nullptr); |
2038 | | // Putting temp_field on the arena fails because the ownership transfers to the |
2039 | | // arena at the "AddAllocated" call and is not released anymore causing a |
2040 | | // double delete. This function uses UnsafeArenaAddAllocated to prevent this. |
2041 | | template <typename T> |
2042 | | internal::UnsafeArenaAllocatedRepeatedPtrFieldBackInsertIterator<T> |
2043 | | UnsafeArenaAllocatedRepeatedPtrFieldBackInserter( |
2044 | | RepeatedPtrField<T>* const mutable_field) { |
2045 | | return internal::UnsafeArenaAllocatedRepeatedPtrFieldBackInsertIterator<T>( |
2046 | | mutable_field); |
2047 | | } |
2048 | | |
2049 | | } // namespace protobuf |
2050 | | } // namespace google |
2051 | | |
2052 | | #include "google/protobuf/port_undef.inc" |
2053 | | |
2054 | | #endif // GOOGLE_PROTOBUF_REPEATED_PTR_FIELD_H__ |