Line data Source code
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 : // Typically, clients should not need to access RepeatedField objects directly,
43 : // but should instead use the accessor functions generated automatically by the
44 : // protocol compiler.
45 :
46 : #ifndef GOOGLE_PROTOBUF_REPEATED_FIELD_H__
47 : #define GOOGLE_PROTOBUF_REPEATED_FIELD_H__
48 :
49 : #ifdef _MSC_VER
50 : // This is required for min/max on VS2013 only.
51 : #include <algorithm>
52 : #endif
53 :
54 : #include <string>
55 : #include <iterator>
56 : #include <google/protobuf/stubs/casts.h>
57 : #include <google/protobuf/stubs/logging.h>
58 : #include <google/protobuf/stubs/common.h>
59 : #include <google/protobuf/stubs/type_traits.h>
60 : #include <google/protobuf/arena.h>
61 : #include <google/protobuf/generated_message_util.h>
62 : #include <google/protobuf/message_lite.h>
63 :
64 : namespace google {
65 :
66 : namespace upb {
67 : namespace google_opensource {
68 : class GMR_Handlers;
69 : } // namespace google_opensource
70 : } // namespace upb
71 :
72 : namespace protobuf {
73 :
74 : class Message;
75 :
76 : namespace internal {
77 :
78 : static const int kMinRepeatedFieldAllocationSize = 4;
79 :
80 : // A utility function for logging that doesn't need any template types.
81 : void LogIndexOutOfBounds(int index, int size);
82 :
83 : template <typename Iter>
84 : inline int CalculateReserve(Iter begin, Iter end, std::forward_iterator_tag) {
85 : return std::distance(begin, end);
86 : }
87 :
88 : template <typename Iter>
89 : inline int CalculateReserve(Iter /*begin*/, Iter /*end*/,
90 : std::input_iterator_tag /*unused*/) {
91 : return -1;
92 : }
93 :
94 : template <typename Iter>
95 : inline int CalculateReserve(Iter begin, Iter end) {
96 : typedef typename std::iterator_traits<Iter>::iterator_category Category;
97 : return CalculateReserve(begin, end, Category());
98 : }
99 : } // namespace internal
100 :
101 :
102 : // RepeatedField is used to represent repeated fields of a primitive type (in
103 : // other words, everything except strings and nested Messages). Most users will
104 : // not ever use a RepeatedField directly; they will use the get-by-index,
105 : // set-by-index, and add accessors that are generated for all repeated fields.
106 : template <typename Element>
107 : class RepeatedField {
108 : public:
109 : RepeatedField();
110 : explicit RepeatedField(Arena* arena);
111 : RepeatedField(const RepeatedField& other);
112 : template <typename Iter>
113 : RepeatedField(Iter begin, const Iter& end);
114 : ~RepeatedField();
115 :
116 : RepeatedField& operator=(const RepeatedField& other);
117 :
118 : bool empty() const;
119 : int size() const;
120 :
121 : const Element& Get(int index) const;
122 : Element* Mutable(int index);
123 : void Set(int index, const Element& value);
124 : void Add(const Element& value);
125 : Element* Add();
126 : // Remove the last element in the array.
127 : void RemoveLast();
128 :
129 : // Extract elements with indices in "[start .. start+num-1]".
130 : // Copy them into "elements[0 .. num-1]" if "elements" is not NULL.
131 : // Caution: implementation also moves elements with indices [start+num ..].
132 : // Calling this routine inside a loop can cause quadratic behavior.
133 : void ExtractSubrange(int start, int num, Element* elements);
134 :
135 : void Clear();
136 : void MergeFrom(const RepeatedField& other);
137 : void CopyFrom(const RepeatedField& other);
138 :
139 : // Reserve space to expand the field to at least the given size. If the
140 : // array is grown, it will always be at least doubled in size.
141 : void Reserve(int new_size);
142 :
143 : // Resize the RepeatedField to a new, smaller size. This is O(1).
144 : void Truncate(int new_size);
145 :
146 : void AddAlreadyReserved(const Element& value);
147 : Element* AddAlreadyReserved();
148 : int Capacity() const;
149 :
150 : // Like STL resize. Uses value to fill appended elements.
151 : // Like Truncate() if new_size <= size(), otherwise this is
152 : // O(new_size - size()).
153 : void Resize(int new_size, const Element& value);
154 :
155 : // Gets the underlying array. This pointer is possibly invalidated by
156 : // any add or remove operation.
157 : Element* mutable_data();
158 : const Element* data() const;
159 :
160 : // Swap entire contents with "other". If they are separate arenas then, copies
161 : // data between each other.
162 : void Swap(RepeatedField* other);
163 :
164 : // Swap entire contents with "other". Should be called only if the caller can
165 : // guarantee that both repeated fields are on the same arena or are on the
166 : // heap. Swapping between different arenas is disallowed and caught by a
167 : // GOOGLE_DCHECK (see API docs for details).
168 : void UnsafeArenaSwap(RepeatedField* other);
169 :
170 : // Swap two elements.
171 : void SwapElements(int index1, int index2);
172 :
173 : // STL-like iterator support
174 : typedef Element* iterator;
175 : typedef const Element* const_iterator;
176 : typedef Element value_type;
177 : typedef value_type& reference;
178 : typedef const value_type& const_reference;
179 : typedef value_type* pointer;
180 : typedef const value_type* const_pointer;
181 : typedef int size_type;
182 : typedef ptrdiff_t difference_type;
183 :
184 : iterator begin();
185 : const_iterator begin() const;
186 : const_iterator cbegin() const;
187 : iterator end();
188 : const_iterator end() const;
189 : const_iterator cend() const;
190 :
191 : // Reverse iterator support
192 : typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
193 : typedef std::reverse_iterator<iterator> reverse_iterator;
194 : reverse_iterator rbegin() {
195 : return reverse_iterator(end());
196 : }
197 : const_reverse_iterator rbegin() const {
198 : return const_reverse_iterator(end());
199 : }
200 : reverse_iterator rend() {
201 : return reverse_iterator(begin());
202 : }
203 : const_reverse_iterator rend() const {
204 : return const_reverse_iterator(begin());
205 : }
206 :
207 : // Returns the number of bytes used by the repeated field, excluding
208 : // sizeof(*this)
209 : int SpaceUsedExcludingSelf() const;
210 :
211 : // Remove the element referenced by position.
212 : iterator erase(const_iterator position);
213 :
214 : // Remove the elements in the range [first, last).
215 : iterator erase(const_iterator first, const_iterator last);
216 :
217 : // Get the Arena on which this RepeatedField stores its elements.
218 : ::google::protobuf::Arena* GetArena() const {
219 : return GetArenaNoVirtual();
220 : }
221 :
222 : private:
223 : static const int kInitialSize = 0;
224 : // A note on the representation here (see also comment below for
225 : // RepeatedPtrFieldBase's struct Rep):
226 : //
227 : // We maintain the same sizeof(RepeatedField) as before we added arena support
228 : // so that we do not degrade performance by bloating memory usage. Directly
229 : // adding an arena_ element to RepeatedField is quite costly. By using
230 : // indirection in this way, we keep the same size when the RepeatedField is
231 : // empty (common case), and add only an 8-byte header to the elements array
232 : // when non-empty. We make sure to place the size fields directly in the
233 : // RepeatedField class to avoid costly cache misses due to the indirection.
234 : int current_size_;
235 : int total_size_;
236 : struct Rep {
237 : Arena* arena;
238 : Element elements[1];
239 : };
240 : // We can not use sizeof(Rep) - sizeof(Element) due to the trailing padding on
241 : // the struct. We can not use sizeof(Arena*) as well because there might be
242 : // a "gap" after the field arena and before the field elements (e.g., when
243 : // Element is double and pointer is 32bit).
244 : static const size_t kRepHeaderSize;
245 : // Contains arena ptr and the elements array. We also keep the invariant that
246 : // if rep_ is NULL, then arena is NULL.
247 : Rep* rep_;
248 :
249 : friend class Arena;
250 : typedef void InternalArenaConstructable_;
251 :
252 : // Move the contents of |from| into |to|, possibly clobbering |from| in the
253 : // process. For primitive types this is just a memcpy(), but it could be
254 : // specialized for non-primitive types to, say, swap each element instead.
255 : void MoveArray(Element* to, Element* from, int size);
256 :
257 : // Copy the elements of |from| into |to|.
258 : void CopyArray(Element* to, const Element* from, int size);
259 :
260 : inline void InternalSwap(RepeatedField* other);
261 :
262 : // Internal helper expected by Arena methods.
263 276 : inline Arena* GetArenaNoVirtual() const {
264 118272 : return (rep_ == NULL) ? NULL : rep_->arena;
265 : }
266 : };
267 :
268 : template<typename Element>
269 : const size_t RepeatedField<Element>::kRepHeaderSize =
270 : reinterpret_cast<size_t>(&reinterpret_cast<Rep*>(16)->elements[0]) - 16;
271 :
272 : namespace internal {
273 : template <typename It> class RepeatedPtrIterator;
274 : template <typename It, typename VoidPtr> class RepeatedPtrOverPtrsIterator;
275 : } // namespace internal
276 :
277 : namespace internal {
278 :
279 : // This is a helper template to copy an array of elements effeciently when they
280 : // have a trivial copy constructor, and correctly otherwise. This really
281 : // shouldn't be necessary, but our compiler doesn't optimize std::copy very
282 : // effectively.
283 : template <typename Element,
284 : bool HasTrivialCopy = has_trivial_copy<Element>::value>
285 : struct ElementCopier {
286 : void operator()(Element* to, const Element* from, int array_size);
287 : };
288 :
289 : } // namespace internal
290 :
291 : namespace internal {
292 :
293 : // type-traits helper for RepeatedPtrFieldBase: we only want to invoke
294 : // arena-related "copy if on different arena" behavior if the necessary methods
295 : // exist on the contained type. In particular, we rely on MergeFrom() existing
296 : // as a general proxy for the fact that a copy will work, and we also provide a
297 : // specific override for string*.
298 : template<typename T>
299 : struct TypeImplementsMergeBehavior {
300 : typedef char HasMerge;
301 : typedef long HasNoMerge;
302 :
303 : // We accept either of:
304 : // - void MergeFrom(const T& other)
305 : // - bool MergeFrom(const T& other)
306 : //
307 : // We mangle these names a bit to avoid compatibility issues in 'unclean'
308 : // include environments that may have, e.g., "#define test ..." (yes, this
309 : // exists).
310 : template<typename U, typename RetType, RetType (U::*)(const U& arg)>
311 : struct CheckType;
312 : template<typename U> static HasMerge Check(
313 : CheckType<U, void, &U::MergeFrom>*);
314 : template<typename U> static HasMerge Check(
315 : CheckType<U, bool, &U::MergeFrom>*);
316 : template<typename U> static HasNoMerge Check(...);
317 :
318 : // Resovles to either google::protobuf::internal::true_type or google::protobuf::internal::false_type.
319 : typedef google::protobuf::internal::integral_constant<bool,
320 : (sizeof(Check<T>(0)) == sizeof(HasMerge))> type;
321 : };
322 :
323 : template<>
324 : struct TypeImplementsMergeBehavior< ::std::string > {
325 : typedef google::protobuf::internal::true_type type;
326 : };
327 :
328 : // This is the common base class for RepeatedPtrFields. It deals only in void*
329 : // pointers. Users should not use this interface directly.
330 : //
331 : // The methods of this interface correspond to the methods of RepeatedPtrField,
332 : // but may have a template argument called TypeHandler. Its signature is:
333 : // class TypeHandler {
334 : // public:
335 : // typedef MyType Type;
336 : // static Type* New();
337 : // static void Delete(Type*);
338 : // static void Clear(Type*);
339 : // static void Merge(const Type& from, Type* to);
340 : //
341 : // // Only needs to be implemented if SpaceUsedExcludingSelf() is called.
342 : // static int SpaceUsed(const Type&);
343 : // };
344 : class LIBPROTOBUF_EXPORT RepeatedPtrFieldBase {
345 : protected:
346 : // The reflection implementation needs to call protected methods directly,
347 : // reinterpreting pointers as being to Message instead of a specific Message
348 : // subclass.
349 : friend class GeneratedMessageReflection;
350 :
351 : // ExtensionSet stores repeated message extensions as
352 : // RepeatedPtrField<MessageLite>, but non-lite ExtensionSets need to
353 : // implement SpaceUsed(), and thus need to call SpaceUsedExcludingSelf()
354 : // reinterpreting MessageLite as Message. ExtensionSet also needs to make
355 : // use of AddFromCleared(), which is not part of the public interface.
356 : friend class ExtensionSet;
357 :
358 : // The MapFieldBase implementation needs to call protected methods directly,
359 : // reinterpreting pointers as being to Message instead of a specific Message
360 : // subclass.
361 : friend class MapFieldBase;
362 :
363 : // To parse directly into a proto2 generated class, the upb class GMR_Handlers
364 : // needs to be able to modify a RepeatedPtrFieldBase directly.
365 : friend class upb::google_opensource::GMR_Handlers;
366 :
367 : RepeatedPtrFieldBase();
368 : explicit RepeatedPtrFieldBase(::google::protobuf::Arena* arena);
369 56 : ~RepeatedPtrFieldBase() {}
370 :
371 : // Must be called from destructor.
372 : template <typename TypeHandler>
373 : void Destroy();
374 :
375 : bool empty() const;
376 : int size() const;
377 :
378 : template <typename TypeHandler>
379 : const typename TypeHandler::Type& Get(int index) const;
380 : template <typename TypeHandler>
381 : typename TypeHandler::Type* Mutable(int index);
382 : template <typename TypeHandler>
383 : void Delete(int index);
384 : template <typename TypeHandler>
385 : typename TypeHandler::Type* Add(typename TypeHandler::Type* prototype = NULL);
386 :
387 : template <typename TypeHandler>
388 : void RemoveLast();
389 : template <typename TypeHandler>
390 : void Clear();
391 : template <typename TypeHandler>
392 : void MergeFrom(const RepeatedPtrFieldBase& other);
393 : template <typename TypeHandler>
394 : void CopyFrom(const RepeatedPtrFieldBase& other);
395 :
396 : void CloseGap(int start, int num);
397 :
398 : void Reserve(int new_size);
399 :
400 : int Capacity() const;
401 :
402 : // Used for constructing iterators.
403 : void* const* raw_data() const;
404 : void** raw_mutable_data() const;
405 :
406 : template <typename TypeHandler>
407 : typename TypeHandler::Type** mutable_data();
408 : template <typename TypeHandler>
409 : const typename TypeHandler::Type* const* data() const;
410 :
411 : template <typename TypeHandler>
412 : GOOGLE_ATTRIBUTE_ALWAYS_INLINE void Swap(RepeatedPtrFieldBase* other);
413 :
414 : void SwapElements(int index1, int index2);
415 :
416 : template <typename TypeHandler>
417 : int SpaceUsedExcludingSelf() const;
418 :
419 :
420 : // Advanced memory management --------------------------------------
421 :
422 : // Like Add(), but if there are no cleared objects to use, returns NULL.
423 : template <typename TypeHandler>
424 : typename TypeHandler::Type* AddFromCleared();
425 :
426 : template<typename TypeHandler>
427 : void AddAllocated(typename TypeHandler::Type* value) {
428 : typename TypeImplementsMergeBehavior<typename TypeHandler::Type>::type t;
429 0 : AddAllocatedInternal<TypeHandler>(value, t);
430 : }
431 :
432 : template <typename TypeHandler>
433 : void UnsafeArenaAddAllocated(typename TypeHandler::Type* value);
434 :
435 : template <typename TypeHandler>
436 : typename TypeHandler::Type* ReleaseLast() {
437 : typename TypeImplementsMergeBehavior<typename TypeHandler::Type>::type t;
438 0 : return ReleaseLastInternal<TypeHandler>(t);
439 : }
440 :
441 : // Releases last element and returns it, but does not do out-of-arena copy.
442 : // And just returns the raw pointer to the contained element in the arena.
443 : template <typename TypeHandler>
444 : typename TypeHandler::Type* UnsafeArenaReleaseLast();
445 :
446 : int ClearedCount() const;
447 : template <typename TypeHandler>
448 : void AddCleared(typename TypeHandler::Type* value);
449 : template <typename TypeHandler>
450 : typename TypeHandler::Type* ReleaseCleared();
451 :
452 : protected:
453 : inline void InternalSwap(RepeatedPtrFieldBase* other);
454 :
455 : template <typename TypeHandler>
456 : void AddAllocatedInternal(typename TypeHandler::Type* value,
457 : google::protobuf::internal::true_type);
458 : template <typename TypeHandler>
459 : void AddAllocatedInternal(typename TypeHandler::Type* value,
460 : google::protobuf::internal::false_type);
461 :
462 : template <typename TypeHandler> GOOGLE_ATTRIBUTE_NOINLINE
463 : void AddAllocatedSlowWithCopy(typename TypeHandler::Type* value,
464 : Arena* value_arena,
465 : Arena* my_arena);
466 : template <typename TypeHandler> GOOGLE_ATTRIBUTE_NOINLINE
467 : void AddAllocatedSlowWithoutCopy(typename TypeHandler::Type* value);
468 :
469 : template <typename TypeHandler>
470 : typename TypeHandler::Type* ReleaseLastInternal(google::protobuf::internal::true_type);
471 : template <typename TypeHandler>
472 : typename TypeHandler::Type* ReleaseLastInternal(google::protobuf::internal::false_type);
473 :
474 : template<typename TypeHandler> GOOGLE_ATTRIBUTE_NOINLINE
475 : void SwapFallback(RepeatedPtrFieldBase* other);
476 :
477 18 : inline Arena* GetArenaNoVirtual() const {
478 18 : return arena_;
479 : }
480 :
481 : private:
482 : static const int kInitialSize = 0;
483 : // A few notes on internal representation:
484 : //
485 : // We use an indirected approach, with struct Rep, to keep
486 : // sizeof(RepeatedPtrFieldBase) equivalent to what it was before arena support
487 : // was added, namely, 3 8-byte machine words on x86-64. An instance of Rep is
488 : // allocated only when the repeated field is non-empty, and it is a
489 : // dynamically-sized struct (the header is directly followed by elements[]).
490 : // We place arena_ and current_size_ directly in the object to avoid cache
491 : // misses due to the indirection, because these fields are checked frequently.
492 : // Placing all fields directly in the RepeatedPtrFieldBase instance costs
493 : // significant performance for memory-sensitive workloads.
494 : Arena* arena_;
495 : int current_size_;
496 : int total_size_;
497 : struct Rep {
498 : int allocated_size;
499 : void* elements[1];
500 : };
501 : static const size_t kRepHeaderSize = sizeof(Rep) - sizeof(void*);
502 : // Contains arena ptr and the elements array. We also keep the invariant that
503 : // if rep_ is NULL, then arena is NULL.
504 : Rep* rep_;
505 :
506 : template <typename TypeHandler>
507 86 : static inline typename TypeHandler::Type* cast(void* element) {
508 86 : return reinterpret_cast<typename TypeHandler::Type*>(element);
509 : }
510 : template <typename TypeHandler>
511 : static inline const typename TypeHandler::Type* cast(const void* element) {
512 : return reinterpret_cast<const typename TypeHandler::Type*>(element);
513 : }
514 :
515 : // Non-templated inner function to avoid code duplication. Takes a function
516 : // pointer to the type-specific (templated) inner allocate/merge loop.
517 : void MergeFromInternal(
518 : const RepeatedPtrFieldBase& other,
519 : void (RepeatedPtrFieldBase::*inner_loop)(void**, void**, int, int));
520 :
521 : template<typename TypeHandler>
522 : void MergeFromInnerLoop(
523 : void** our_elems, void** other_elems, int length, int already_allocated);
524 :
525 : // Internal helper: extend array space if necessary to contain |extend_amount|
526 : // more elements, and return a pointer to the element immediately following
527 : // the old list of elements. This interface factors out common behavior from
528 : // Reserve() and MergeFrom() to reduce code size. |extend_amount| must be > 0.
529 : void** InternalExtend(int extend_amount);
530 :
531 : GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RepeatedPtrFieldBase);
532 : };
533 :
534 : template <typename GenericType>
535 : class GenericTypeHandler {
536 : public:
537 : typedef GenericType Type;
538 69910 : static inline GenericType* New(Arena* arena) {
539 : return ::google::protobuf::Arena::CreateMaybeMessage<Type>(
540 69910 : arena, static_cast<GenericType*>(0));
541 : }
542 : // We force NewFromPrototype() and Delete() to be non-inline to reduce code
543 : // size: else, several other methods get inlined copies of message types'
544 : // constructors and destructors.
545 : GOOGLE_ATTRIBUTE_NOINLINE static GenericType* NewFromPrototype(
546 : const GenericType* prototype, ::google::protobuf::Arena* arena = NULL);
547 : GOOGLE_ATTRIBUTE_NOINLINE static void Delete(GenericType* value, Arena* arena);
548 : static inline ::google::protobuf::Arena* GetArena(GenericType* value) {
549 : return ::google::protobuf::Arena::GetArena<Type>(value);
550 : }
551 : static inline void* GetMaybeArenaPointer(GenericType* value) {
552 : return ::google::protobuf::Arena::GetArena<Type>(value);
553 : }
554 :
555 841 : static inline void Clear(GenericType* value) { value->Clear(); }
556 : GOOGLE_ATTRIBUTE_NOINLINE static void Merge(const GenericType& from,
557 : GenericType* to);
558 : static inline int SpaceUsed(const GenericType& value) {
559 0 : return value.SpaceUsed();
560 : }
561 : static inline const Type& default_instance() {
562 : return Type::default_instance();
563 : }
564 : };
565 :
566 : template <typename GenericType>
567 69910 : GenericType* GenericTypeHandler<GenericType>::NewFromPrototype(
568 : const GenericType* prototype, ::google::protobuf::Arena* arena) {
569 69910 : return New(arena);
570 : }
571 : template <typename GenericType>
572 70315 : void GenericTypeHandler<GenericType>::Delete(GenericType* value, Arena* arena) {
573 70315 : if (arena == NULL) {
574 70315 : delete value;
575 : }
576 70315 : }
577 : template <typename GenericType>
578 25994 : void GenericTypeHandler<GenericType>::Merge(const GenericType& from,
579 : GenericType* to) {
580 25994 : to->MergeFrom(from);
581 25994 : }
582 :
583 : // NewFromPrototype() and Merge() cannot be defined here; if they're declared
584 : // inline the compiler will complain about not matching GOOGLE_ATTRIBUTE_NOINLINE
585 : // above, and if not, compilation will result in multiple definitions. These
586 : // are therefore declared as specializations here and defined in
587 : // message_lite.cc.
588 : template<>
589 : MessageLite* GenericTypeHandler<MessageLite>::NewFromPrototype(
590 : const MessageLite* prototype, google::protobuf::Arena* arena);
591 : template<>
592 : inline google::protobuf::Arena* GenericTypeHandler<MessageLite>::GetArena(
593 : MessageLite* value) {
594 : return value->GetArena();
595 : }
596 : template<>
597 : inline void* GenericTypeHandler<MessageLite>::GetMaybeArenaPointer(
598 : MessageLite* value) {
599 : return value->GetMaybeArenaPointer();
600 : }
601 : template <>
602 : void GenericTypeHandler<MessageLite>::Merge(const MessageLite& from,
603 : MessageLite* to);
604 :
605 : // Declarations of the specialization as we cannot define them here, as the
606 : // header that defines ProtocolMessage depends on types defined in this header.
607 : #define DECLARE_SPECIALIZATIONS_FOR_BASE_PROTO_TYPES(TypeName) \
608 : template<> \
609 : TypeName* GenericTypeHandler<TypeName>::NewFromPrototype( \
610 : const TypeName* prototype, google::protobuf::Arena* arena); \
611 : template<> \
612 : google::protobuf::Arena* GenericTypeHandler<TypeName>::GetArena( \
613 : TypeName* value); \
614 : template<> \
615 : void* GenericTypeHandler<TypeName>::GetMaybeArenaPointer( \
616 : TypeName* value);
617 :
618 : // Message specialization bodies defined in message.cc. This split is necessary
619 : // to allow proto2-lite (which includes this header) to be independent of
620 : // Message.
621 : DECLARE_SPECIALIZATIONS_FOR_BASE_PROTO_TYPES(Message);
622 :
623 :
624 : #undef DECLARE_SPECIALIZATIONS_FOR_BASE_PROTO_TYPES
625 :
626 : template <>
627 : inline const MessageLite& GenericTypeHandler<MessageLite>::default_instance() {
628 : // Yes, the behavior of the code is undefined, but this function is only
629 : // called when we're already deep into the world of undefined, because the
630 : // caller called Get(index) out of bounds.
631 : MessageLite* null = NULL;
632 : return *null;
633 : }
634 :
635 : template <>
636 : inline const Message& GenericTypeHandler<Message>::default_instance() {
637 : // Yes, the behavior of the code is undefined, but this function is only
638 : // called when we're already deep into the world of undefined, because the
639 : // caller called Get(index) out of bounds.
640 : Message* null = NULL;
641 : return *null;
642 : }
643 :
644 :
645 : // HACK: If a class is declared as DLL-exported in MSVC, it insists on
646 : // generating copies of all its methods -- even inline ones -- to include
647 : // in the DLL. But SpaceUsed() calls StringSpaceUsedExcludingSelf() which
648 : // isn't in the lite library, therefore the lite library cannot link if
649 : // StringTypeHandler is exported. So, we factor out StringTypeHandlerBase,
650 : // export that, then make StringTypeHandler be a subclass which is NOT
651 : // exported.
652 : // TODO(kenton): There has to be a better way.
653 : class LIBPROTOBUF_EXPORT StringTypeHandlerBase {
654 : public:
655 : typedef string Type;
656 :
657 476 : static inline string* New(Arena* arena) {
658 506 : return Arena::Create<string>(arena);
659 : }
660 30 : static inline string* NewFromPrototype(const string*,
661 : ::google::protobuf::Arena* arena) {
662 476 : return New(arena);
663 : }
664 : static inline ::google::protobuf::Arena* GetArena(string*) {
665 : return NULL;
666 : }
667 : static inline void* GetMaybeArenaPointer(string* value) {
668 : return NULL;
669 : }
670 476 : static inline void Delete(string* value, Arena* arena) {
671 476 : if (arena == NULL) {
672 922 : delete value;
673 : }
674 476 : }
675 0 : static inline void Clear(string* value) { value->clear(); }
676 18 : static inline void Merge(const string& from, string* to) { *to = from; }
677 : static inline const Type& default_instance() {
678 : return ::google::protobuf::internal::GetEmptyString();
679 : }
680 : };
681 :
682 : class StringTypeHandler : public StringTypeHandlerBase {
683 : public:
684 : static int SpaceUsed(const string& value) {
685 0 : return sizeof(value) + StringSpaceUsedExcludingSelf(value);
686 : }
687 : };
688 :
689 :
690 : } // namespace internal
691 :
692 : // RepeatedPtrField is like RepeatedField, but used for repeated strings or
693 : // Messages.
694 : template <typename Element>
695 : class RepeatedPtrField : public internal::RepeatedPtrFieldBase {
696 : public:
697 : RepeatedPtrField();
698 : explicit RepeatedPtrField(::google::protobuf::Arena* arena);
699 :
700 : RepeatedPtrField(const RepeatedPtrField& other);
701 : template <typename Iter>
702 : RepeatedPtrField(Iter begin, const Iter& end);
703 : ~RepeatedPtrField();
704 :
705 : RepeatedPtrField& operator=(const RepeatedPtrField& other);
706 :
707 : bool empty() const;
708 : int size() const;
709 :
710 : const Element& Get(int index) const;
711 : Element* Mutable(int index);
712 : Element* Add();
713 :
714 : // Remove the last element in the array.
715 : // Ownership of the element is retained by the array.
716 : void RemoveLast();
717 :
718 : // Delete elements with indices in the range [start .. start+num-1].
719 : // Caution: implementation moves all elements with indices [start+num .. ].
720 : // Calling this routine inside a loop can cause quadratic behavior.
721 : void DeleteSubrange(int start, int num);
722 :
723 : void Clear();
724 : void MergeFrom(const RepeatedPtrField& other);
725 : void CopyFrom(const RepeatedPtrField& other);
726 :
727 : // Reserve space to expand the field to at least the given size. This only
728 : // resizes the pointer array; it doesn't allocate any objects. If the
729 : // array is grown, it will always be at least doubled in size.
730 : void Reserve(int new_size);
731 :
732 : int Capacity() const;
733 :
734 : // Gets the underlying array. This pointer is possibly invalidated by
735 : // any add or remove operation.
736 : Element** mutable_data();
737 : const Element* const* data() const;
738 :
739 : // Swap entire contents with "other". If they are on separate arenas, then
740 : // copies data.
741 : void Swap(RepeatedPtrField* other);
742 :
743 : // Swap entire contents with "other". Caller should guarantee that either both
744 : // fields are on the same arena or both are on the heap. Swapping between
745 : // different arenas with this function is disallowed and is caught via
746 : // GOOGLE_DCHECK.
747 : void UnsafeArenaSwap(RepeatedPtrField* other);
748 :
749 : // Swap two elements.
750 : void SwapElements(int index1, int index2);
751 :
752 : // STL-like iterator support
753 : typedef internal::RepeatedPtrIterator<Element> iterator;
754 : typedef internal::RepeatedPtrIterator<const Element> const_iterator;
755 : typedef Element value_type;
756 : typedef value_type& reference;
757 : typedef const value_type& const_reference;
758 : typedef value_type* pointer;
759 : typedef const value_type* const_pointer;
760 : typedef int size_type;
761 : typedef ptrdiff_t difference_type;
762 :
763 : iterator begin();
764 : const_iterator begin() const;
765 : const_iterator cbegin() const;
766 : iterator end();
767 : const_iterator end() const;
768 : const_iterator cend() const;
769 :
770 : // Reverse iterator support
771 : typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
772 : typedef std::reverse_iterator<iterator> reverse_iterator;
773 : reverse_iterator rbegin() {
774 : return reverse_iterator(end());
775 : }
776 : const_reverse_iterator rbegin() const {
777 : return const_reverse_iterator(end());
778 : }
779 : reverse_iterator rend() {
780 : return reverse_iterator(begin());
781 : }
782 : const_reverse_iterator rend() const {
783 : return const_reverse_iterator(begin());
784 : }
785 :
786 : // Custom STL-like iterator that iterates over and returns the underlying
787 : // pointers to Element rather than Element itself.
788 : typedef internal::RepeatedPtrOverPtrsIterator<Element, void*>
789 : pointer_iterator;
790 : typedef internal::RepeatedPtrOverPtrsIterator<const Element, const void*>
791 : const_pointer_iterator;
792 : pointer_iterator pointer_begin();
793 : const_pointer_iterator pointer_begin() const;
794 : pointer_iterator pointer_end();
795 : const_pointer_iterator pointer_end() const;
796 :
797 : // Returns (an estimate of) the number of bytes used by the repeated field,
798 : // excluding sizeof(*this).
799 : int SpaceUsedExcludingSelf() const;
800 :
801 : // Advanced memory management --------------------------------------
802 : // When hardcore memory management becomes necessary -- as it sometimes
803 : // does here at Google -- the following methods may be useful.
804 :
805 : // Add an already-allocated object, passing ownership to the
806 : // RepeatedPtrField.
807 : //
808 : // Note that some special behavior occurs with respect to arenas:
809 : //
810 : // (i) if this field holds submessages, the new submessage will be copied if
811 : // the original is in an arena and this RepeatedPtrField is either in a
812 : // different arena, or on the heap.
813 : // (ii) if this field holds strings, the passed-in string *must* be
814 : // heap-allocated, not arena-allocated. There is no way to dynamically check
815 : // this at runtime, so User Beware.
816 : void AddAllocated(Element* value);
817 :
818 : // Remove the last element and return it, passing ownership to the caller.
819 : // Requires: size() > 0
820 : //
821 : // If this RepeatedPtrField is on an arena, an object copy is required to pass
822 : // ownership back to the user (for compatible semantics). Use
823 : // UnsafeArenaReleaseLast() if this behavior is undesired.
824 : Element* ReleaseLast();
825 :
826 : // Add an already-allocated object, skipping arena-ownership checks. The user
827 : // must guarantee that the given object is in the same arena as this
828 : // RepeatedPtrField.
829 : void UnsafeArenaAddAllocated(Element* value);
830 :
831 : // Remove the last element and return it. Works only when operating on an
832 : // arena. The returned pointer is to the original object in the arena, hence
833 : // has the arena's lifetime.
834 : // Requires: current_size_ > 0
835 : Element* UnsafeArenaReleaseLast();
836 :
837 : // Extract elements with indices in the range "[start .. start+num-1]".
838 : // The caller assumes ownership of the extracted elements and is responsible
839 : // for deleting them when they are no longer needed.
840 : // If "elements" is non-NULL, then pointers to the extracted elements
841 : // are stored in "elements[0 .. num-1]" for the convenience of the caller.
842 : // If "elements" is NULL, then the caller must use some other mechanism
843 : // to perform any further operations (like deletion) on these elements.
844 : // Caution: implementation also moves elements with indices [start+num ..].
845 : // Calling this routine inside a loop can cause quadratic behavior.
846 : //
847 : // Memory copying behavior is identical to ReleaseLast(), described above: if
848 : // this RepeatedPtrField is on an arena, an object copy is performed for each
849 : // returned element, so that all returned element pointers are to
850 : // heap-allocated copies. If this copy is not desired, the user should call
851 : // UnsafeArenaExtractSubrange().
852 : void ExtractSubrange(int start, int num, Element** elements);
853 :
854 : // Identical to ExtractSubrange() described above, except that when this
855 : // repeated field is on an arena, no object copies are performed. Instead, the
856 : // raw object pointers are returned. Thus, if on an arena, the returned
857 : // objects must not be freed, because they will not be heap-allocated objects.
858 : void UnsafeArenaExtractSubrange(int start, int num, Element** elements);
859 :
860 : // When elements are removed by calls to RemoveLast() or Clear(), they
861 : // are not actually freed. Instead, they are cleared and kept so that
862 : // they can be reused later. This can save lots of CPU time when
863 : // repeatedly reusing a protocol message for similar purposes.
864 : //
865 : // Hardcore programs may choose to manipulate these cleared objects
866 : // to better optimize memory management using the following routines.
867 :
868 : // Get the number of cleared objects that are currently being kept
869 : // around for reuse.
870 : int ClearedCount() const;
871 : // Add an element to the pool of cleared objects, passing ownership to
872 : // the RepeatedPtrField. The element must be cleared prior to calling
873 : // this method.
874 : //
875 : // This method cannot be called when the repeated field is on an arena or when
876 : // |value| is; both cases will trigger a GOOGLE_DCHECK-failure.
877 : void AddCleared(Element* value);
878 : // Remove a single element from the cleared pool and return it, passing
879 : // ownership to the caller. The element is guaranteed to be cleared.
880 : // Requires: ClearedCount() > 0
881 : //
882 : //
883 : // This method cannot be called when the repeated field is on an arena; doing
884 : // so will trigger a GOOGLE_DCHECK-failure.
885 : Element* ReleaseCleared();
886 :
887 : // Remove the element referenced by position.
888 : iterator erase(const_iterator position);
889 :
890 : // Removes the elements in the range [first, last).
891 : iterator erase(const_iterator first, const_iterator last);
892 :
893 : // Gets the arena on which this RepeatedPtrField stores its elements.
894 : ::google::protobuf::Arena* GetArena() const {
895 : return GetArenaNoVirtual();
896 : }
897 :
898 : protected:
899 : // Note: RepeatedPtrField SHOULD NOT be subclassed by users. We only
900 : // subclass it in one place as a hack for compatibility with proto1. The
901 : // subclass needs to know about TypeHandler in order to call protected
902 : // methods on RepeatedPtrFieldBase.
903 : class TypeHandler;
904 :
905 : // Internal arena accessor expected by helpers in Arena.
906 : inline Arena* GetArenaNoVirtual() const;
907 :
908 : private:
909 : // Implementations for ExtractSubrange(). The copying behavior must be
910 : // included only if the type supports the necessary operations (e.g.,
911 : // MergeFrom()), so we must resolve this at compile time. ExtractSubrange()
912 : // uses SFINAE to choose one of the below implementations.
913 : void ExtractSubrangeInternal(int start, int num, Element** elements,
914 : google::protobuf::internal::true_type);
915 : void ExtractSubrangeInternal(int start, int num, Element** elements,
916 : google::protobuf::internal::false_type);
917 :
918 : friend class Arena;
919 : typedef void InternalArenaConstructable_;
920 :
921 : };
922 :
923 : // implementation ====================================================
924 :
925 : template <typename Element>
926 47 : inline RepeatedField<Element>::RepeatedField()
927 : : current_size_(0),
928 : total_size_(0),
929 102997 : rep_(NULL) {
930 47 : }
931 :
932 : template <typename Element>
933 0 : inline RepeatedField<Element>::RepeatedField(Arena* arena)
934 : : current_size_(0),
935 : total_size_(0),
936 0 : rep_(NULL) {
937 : // In case arena is NULL, then we do not create rep_, as code has an invariant
938 : // `rep_ == NULL then arena == NULL`.
939 0 : if (arena != NULL) {
940 0 : rep_ = reinterpret_cast<Rep*>(
941 : ::google::protobuf::Arena::CreateArray<char>(arena, kRepHeaderSize));
942 0 : rep_->arena = arena;
943 : }
944 0 : }
945 :
946 : template <typename Element>
947 : inline RepeatedField<Element>::RepeatedField(const RepeatedField& other)
948 : : current_size_(0),
949 : total_size_(0),
950 : rep_(NULL) {
951 : CopyFrom(other);
952 : }
953 :
954 : template <typename Element>
955 : template <typename Iter>
956 : RepeatedField<Element>::RepeatedField(Iter begin, const Iter& end)
957 : : current_size_(0),
958 : total_size_(0),
959 : rep_(NULL) {
960 : int reserve = internal::CalculateReserve(begin, end);
961 : if (reserve != -1) {
962 : Reserve(reserve);
963 : for (; begin != end; ++begin) {
964 : AddAlreadyReserved(*begin);
965 : }
966 : } else {
967 : for (; begin != end; ++begin) {
968 : Add(*begin);
969 : }
970 : }
971 : }
972 :
973 : template <typename Element>
974 102480 : RepeatedField<Element>::~RepeatedField() {
975 : // See explanation in Reserve(): we need to invoke destructors here for the
976 : // case that Element has a non-trivial destructor. If Element has a trivial
977 : // destructor (for example, if it's a primitive type, like int32), this entire
978 : // loop will be removed by the optimizer.
979 102480 : if (rep_ != NULL) {
980 100666 : Element* e = &rep_->elements[0];
981 100666 : Element* limit = &rep_->elements[total_size_];
982 36 : for (; e < limit; e++) {
983 : e->Element::~Element();
984 : }
985 100666 : if (rep_->arena == NULL) {
986 100666 : delete[] reinterpret_cast<char*>(rep_);
987 : }
988 : }
989 102480 : }
990 :
991 : template <typename Element>
992 : inline RepeatedField<Element>&
993 : RepeatedField<Element>::operator=(const RepeatedField& other) {
994 : if (this != &other)
995 : CopyFrom(other);
996 : return *this;
997 : }
998 :
999 : template <typename Element>
1000 : inline bool RepeatedField<Element>::empty() const {
1001 0 : return current_size_ == 0;
1002 : }
1003 :
1004 : template <typename Element>
1005 59922 : inline int RepeatedField<Element>::size() const {
1006 59922 : return current_size_;
1007 : }
1008 :
1009 : template <typename Element>
1010 0 : inline int RepeatedField<Element>::Capacity() const {
1011 0 : return total_size_;
1012 : }
1013 :
1014 : template<typename Element>
1015 0 : inline void RepeatedField<Element>::AddAlreadyReserved(const Element& value) {
1016 0 : GOOGLE_DCHECK_LT(current_size_, total_size_);
1017 0 : rep_->elements[current_size_++] = value;
1018 0 : }
1019 :
1020 : template<typename Element>
1021 : inline Element* RepeatedField<Element>::AddAlreadyReserved() {
1022 : GOOGLE_DCHECK_LT(current_size_, total_size_);
1023 : return &rep_->elements[current_size_++];
1024 : }
1025 :
1026 : template<typename Element>
1027 : inline void RepeatedField<Element>::Resize(int new_size, const Element& value) {
1028 : GOOGLE_DCHECK_GE(new_size, 0);
1029 : if (new_size > current_size_) {
1030 : Reserve(new_size);
1031 : std::fill(&rep_->elements[current_size_],
1032 : &rep_->elements[new_size], value);
1033 : }
1034 : current_size_ = new_size;
1035 : }
1036 :
1037 : template <typename Element>
1038 59880 : inline const Element& RepeatedField<Element>::Get(int index) const {
1039 59880 : GOOGLE_DCHECK_GE(index, 0);
1040 59880 : GOOGLE_DCHECK_LT(index, current_size_);
1041 59880 : return rep_->elements[index];
1042 : }
1043 :
1044 : template <typename Element>
1045 : inline Element* RepeatedField<Element>::Mutable(int index) {
1046 : GOOGLE_DCHECK_GE(index, 0);
1047 : GOOGLE_DCHECK_LT(index, current_size_);
1048 : return &rep_->elements[index];
1049 : }
1050 :
1051 : template <typename Element>
1052 : inline void RepeatedField<Element>::Set(int index, const Element& value) {
1053 : GOOGLE_DCHECK_GE(index, 0);
1054 : GOOGLE_DCHECK_LT(index, current_size_);
1055 678 : rep_->elements[index] = value;
1056 : }
1057 :
1058 : template <typename Element>
1059 168819 : inline void RepeatedField<Element>::Add(const Element& value) {
1060 168819 : if (current_size_ == total_size_) Reserve(total_size_ + 1);
1061 168819 : rep_->elements[current_size_++] = value;
1062 168819 : }
1063 :
1064 : template <typename Element>
1065 2 : inline Element* RepeatedField<Element>::Add() {
1066 2 : if (current_size_ == total_size_) Reserve(total_size_ + 1);
1067 2 : return &rep_->elements[current_size_++];
1068 : }
1069 :
1070 : template <typename Element>
1071 : inline void RepeatedField<Element>::RemoveLast() {
1072 : GOOGLE_DCHECK_GT(current_size_, 0);
1073 0 : current_size_--;
1074 : }
1075 :
1076 : template <typename Element>
1077 : void RepeatedField<Element>::ExtractSubrange(
1078 : int start, int num, Element* elements) {
1079 : GOOGLE_DCHECK_GE(start, 0);
1080 : GOOGLE_DCHECK_GE(num, 0);
1081 : GOOGLE_DCHECK_LE(start + num, this->current_size_);
1082 :
1083 : // Save the values of the removed elements if requested.
1084 : if (elements != NULL) {
1085 : for (int i = 0; i < num; ++i)
1086 : elements[i] = this->Get(i + start);
1087 : }
1088 :
1089 : // Slide remaining elements down to fill the gap.
1090 : if (num > 0) {
1091 : for (int i = start + num; i < this->current_size_; ++i)
1092 : this->Set(i - num, this->Get(i));
1093 : this->Truncate(this->current_size_ - num);
1094 : }
1095 : }
1096 :
1097 : template <typename Element>
1098 0 : inline void RepeatedField<Element>::Clear() {
1099 22978 : current_size_ = 0;
1100 0 : }
1101 :
1102 : template <typename Element>
1103 74762 : inline void RepeatedField<Element>::MergeFrom(const RepeatedField& other) {
1104 74762 : GOOGLE_CHECK_NE(&other, this);
1105 74762 : if (other.current_size_ != 0) {
1106 73807 : Reserve(current_size_ + other.current_size_);
1107 147614 : CopyArray(rep_->elements + current_size_,
1108 147614 : other.rep_->elements, other.current_size_);
1109 73807 : current_size_ += other.current_size_;
1110 : }
1111 74762 : }
1112 :
1113 : template <typename Element>
1114 : inline void RepeatedField<Element>::CopyFrom(const RepeatedField& other) {
1115 22762 : if (&other == this) return;
1116 22762 : Clear();
1117 22762 : MergeFrom(other);
1118 : }
1119 :
1120 : template <typename Element>
1121 : inline typename RepeatedField<Element>::iterator RepeatedField<Element>::erase(
1122 : const_iterator position) {
1123 : return erase(position, position + 1);
1124 : }
1125 :
1126 : template <typename Element>
1127 : inline typename RepeatedField<Element>::iterator RepeatedField<Element>::erase(
1128 : const_iterator first, const_iterator last) {
1129 : size_type first_offset = first - cbegin();
1130 : if (first != last) {
1131 : Truncate(std::copy(last, cend(), begin() + first_offset) - cbegin());
1132 : }
1133 : return begin() + first_offset;
1134 : }
1135 :
1136 : template <typename Element>
1137 : inline Element* RepeatedField<Element>::mutable_data() {
1138 : return rep_ ? rep_->elements : NULL;
1139 : }
1140 :
1141 : template <typename Element>
1142 : inline const Element* RepeatedField<Element>::data() const {
1143 : return rep_ ? rep_->elements : NULL;
1144 : }
1145 :
1146 :
1147 : template <typename Element>
1148 0 : inline void RepeatedField<Element>::InternalSwap(RepeatedField* other) {
1149 0 : std::swap(rep_, other->rep_);
1150 0 : std::swap(current_size_, other->current_size_);
1151 0 : std::swap(total_size_, other->total_size_);
1152 0 : }
1153 :
1154 : template <typename Element>
1155 0 : void RepeatedField<Element>::Swap(RepeatedField* other) {
1156 0 : if (this == other) return;
1157 0 : if (GetArenaNoVirtual() == other->GetArenaNoVirtual()) {
1158 : InternalSwap(other);
1159 : } else {
1160 0 : RepeatedField<Element> temp(other->GetArenaNoVirtual());
1161 0 : temp.MergeFrom(*this);
1162 : CopyFrom(*other);
1163 0 : other->UnsafeArenaSwap(&temp);
1164 : }
1165 : }
1166 :
1167 : template <typename Element>
1168 0 : void RepeatedField<Element>::UnsafeArenaSwap(RepeatedField* other) {
1169 0 : if (this == other) return;
1170 0 : GOOGLE_DCHECK(GetArenaNoVirtual() == other->GetArenaNoVirtual());
1171 0 : InternalSwap(other);
1172 : }
1173 :
1174 : template <typename Element>
1175 : void RepeatedField<Element>::SwapElements(int index1, int index2) {
1176 : using std::swap; // enable ADL with fallback
1177 0 : swap(rep_->elements[index1], rep_->elements[index2]);
1178 : }
1179 :
1180 : template <typename Element>
1181 : inline typename RepeatedField<Element>::iterator
1182 : RepeatedField<Element>::begin() {
1183 : return rep_ ? rep_->elements : NULL;
1184 : }
1185 : template <typename Element>
1186 : inline typename RepeatedField<Element>::const_iterator
1187 6 : RepeatedField<Element>::begin() const {
1188 6 : return rep_ ? rep_->elements : NULL;
1189 : }
1190 : template <typename Element>
1191 : inline typename RepeatedField<Element>::const_iterator
1192 : RepeatedField<Element>::cbegin() const {
1193 : return rep_ ? rep_->elements : NULL;
1194 : }
1195 : template <typename Element>
1196 : inline typename RepeatedField<Element>::iterator
1197 : RepeatedField<Element>::end() {
1198 : return rep_ ? rep_->elements + current_size_ : NULL;
1199 : }
1200 : template <typename Element>
1201 : inline typename RepeatedField<Element>::const_iterator
1202 : RepeatedField<Element>::end() const {
1203 0 : return rep_ ? rep_->elements + current_size_ : NULL;
1204 : }
1205 : template <typename Element>
1206 : inline typename RepeatedField<Element>::const_iterator
1207 : RepeatedField<Element>::cend() const {
1208 : return rep_ ? rep_->elements + current_size_ : NULL;
1209 : }
1210 :
1211 : template <typename Element>
1212 : inline int RepeatedField<Element>::SpaceUsedExcludingSelf() const {
1213 : return rep_ ?
1214 0 : (total_size_ * sizeof(Element) + kRepHeaderSize) : 0;
1215 : }
1216 :
1217 : // Avoid inlining of Reserve(): new, copy, and delete[] lead to a significant
1218 : // amount of code bloat.
1219 : template <typename Element>
1220 118272 : void RepeatedField<Element>::Reserve(int new_size) {
1221 236544 : if (total_size_ >= new_size) return;
1222 118272 : Rep* old_rep = rep_;
1223 236268 : Arena* arena = GetArenaNoVirtual();
1224 118272 : new_size = max(google::protobuf::internal::kMinRepeatedFieldAllocationSize,
1225 354540 : max(total_size_ * 2, new_size));
1226 118272 : GOOGLE_CHECK_LE(static_cast<size_t>(new_size),
1227 : (std::numeric_limits<size_t>::max() - kRepHeaderSize) /
1228 : sizeof(Element))
1229 0 : << "Requested size is too large to fit into size_t.";
1230 118272 : if (arena == NULL) {
1231 118272 : rep_ = reinterpret_cast<Rep*>(
1232 : new char[kRepHeaderSize + sizeof(Element) * new_size]);
1233 : } else {
1234 0 : rep_ = reinterpret_cast<Rep*>(
1235 : ::google::protobuf::Arena::CreateArray<char>(arena,
1236 0 : kRepHeaderSize + sizeof(Element) * new_size));
1237 : }
1238 118272 : rep_->arena = arena;
1239 118272 : int old_total_size = total_size_;
1240 118272 : total_size_ = new_size;
1241 : // Invoke placement-new on newly allocated elements. We shouldn't have to do
1242 : // this, since Element is supposed to be POD, but a previous version of this
1243 : // code allocated storage with "new Element[size]" and some code uses
1244 : // RepeatedField with non-POD types, relying on constructor invocation. If
1245 : // Element has a trivial constructor (e.g., int32), gcc (tested with -O2)
1246 : // completely removes this loop because the loop body is empty, so this has no
1247 : // effect unless its side-effects are required for correctness.
1248 : // Note that we do this before MoveArray() below because Element's copy
1249 : // assignment implementation will want an initialized instance first.
1250 118272 : Element* e = &rep_->elements[0];
1251 118272 : Element* limit = &rep_->elements[total_size_];
1252 924581 : for (; e < limit; e++) {
1253 806309 : new (e) Element();
1254 : }
1255 118272 : if (current_size_ > 0) {
1256 17606 : MoveArray(rep_->elements, old_rep->elements, current_size_);
1257 : }
1258 118272 : if (old_rep) {
1259 : // Likewise, we need to invoke destructors on the old array. If Element has
1260 : // no destructor, this loop will disappear.
1261 17606 : e = &old_rep->elements[0];
1262 17606 : limit = &old_rep->elements[old_total_size];
1263 240 : for (; e < limit; e++) {
1264 : e->Element::~Element();
1265 : }
1266 17606 : if (arena == NULL) {
1267 17606 : delete[] reinterpret_cast<char*>(old_rep);
1268 : }
1269 : }
1270 : }
1271 :
1272 : template <typename Element>
1273 : inline void RepeatedField<Element>::Truncate(int new_size) {
1274 : GOOGLE_DCHECK_LE(new_size, current_size_);
1275 : if (current_size_ > 0) {
1276 : current_size_ = new_size;
1277 : }
1278 : }
1279 :
1280 : template <typename Element>
1281 240 : inline void RepeatedField<Element>::MoveArray(
1282 : Element* to, Element* from, int array_size) {
1283 17606 : CopyArray(to, from, array_size);
1284 240 : }
1285 :
1286 : template <typename Element>
1287 252 : inline void RepeatedField<Element>::CopyArray(
1288 : Element* to, const Element* from, int array_size) {
1289 91413 : internal::ElementCopier<Element>()(to, from, array_size);
1290 252 : }
1291 :
1292 : namespace internal {
1293 :
1294 : template <typename Element, bool HasTrivialCopy>
1295 : void ElementCopier<Element, HasTrivialCopy>::operator()(
1296 : Element* to, const Element* from, int array_size) {
1297 : std::copy(from, from + array_size, to);
1298 : }
1299 :
1300 : template <typename Element>
1301 : struct ElementCopier<Element, true> {
1302 252 : void operator()(Element* to, const Element* from, int array_size) {
1303 91413 : memcpy(to, from, array_size * sizeof(Element));
1304 252 : }
1305 : };
1306 :
1307 : } // namespace internal
1308 :
1309 :
1310 : // -------------------------------------------------------------------
1311 :
1312 : namespace internal {
1313 :
1314 67 : inline RepeatedPtrFieldBase::RepeatedPtrFieldBase()
1315 : : arena_(NULL),
1316 : current_size_(0),
1317 : total_size_(0),
1318 78779 : rep_(NULL) {
1319 67 : }
1320 :
1321 : inline RepeatedPtrFieldBase::RepeatedPtrFieldBase(::google::protobuf::Arena* arena)
1322 : : arena_(arena),
1323 : current_size_(0),
1324 : total_size_(0),
1325 0 : rep_(NULL) {
1326 : }
1327 :
1328 : template <typename TypeHandler>
1329 77390 : void RepeatedPtrFieldBase::Destroy() {
1330 77390 : if (rep_ != NULL) {
1331 70821 : for (int i = 0; i < rep_->allocated_size; i++) {
1332 70791 : TypeHandler::Delete(cast<TypeHandler>(rep_->elements[i]), arena_);
1333 : }
1334 6177 : if (arena_ == NULL) {
1335 6177 : delete [] reinterpret_cast<char*>(rep_);
1336 : }
1337 : }
1338 77390 : rep_ = NULL;
1339 77390 : }
1340 :
1341 : template <typename TypeHandler>
1342 0 : inline void RepeatedPtrFieldBase::Swap(RepeatedPtrFieldBase* other) {
1343 0 : if (other->GetArenaNoVirtual() == GetArenaNoVirtual()) {
1344 0 : InternalSwap(other);
1345 : } else {
1346 0 : SwapFallback<TypeHandler>(other);
1347 : }
1348 : }
1349 :
1350 : template <typename TypeHandler>
1351 0 : void RepeatedPtrFieldBase::SwapFallback(RepeatedPtrFieldBase* other) {
1352 : GOOGLE_DCHECK(other->GetArenaNoVirtual() != GetArenaNoVirtual());
1353 :
1354 : // Copy semantics in this case. We try to improve efficiency by placing the
1355 : // temporary on |other|'s arena so that messages are copied cross-arena only
1356 : // once, not twice.
1357 0 : RepeatedPtrFieldBase temp(other->GetArenaNoVirtual());
1358 0 : temp.MergeFrom<TypeHandler>(*this);
1359 0 : this->Clear<TypeHandler>();
1360 0 : this->MergeFrom<TypeHandler>(*other);
1361 0 : other->Clear<TypeHandler>();
1362 : other->InternalSwap(&temp);
1363 0 : temp.Destroy<TypeHandler>(); // Frees rep_ if `other` had no arena.
1364 0 : }
1365 :
1366 : inline bool RepeatedPtrFieldBase::empty() const {
1367 0 : return current_size_ == 0;
1368 : }
1369 :
1370 62 : inline int RepeatedPtrFieldBase::size() const {
1371 62 : return current_size_;
1372 : }
1373 :
1374 : template <typename TypeHandler>
1375 : inline const typename TypeHandler::Type&
1376 56 : RepeatedPtrFieldBase::Get(int index) const {
1377 56 : GOOGLE_DCHECK_GE(index, 0);
1378 56 : GOOGLE_DCHECK_LT(index, current_size_);
1379 46038 : return *cast<TypeHandler>(rep_->elements[index]);
1380 : }
1381 :
1382 :
1383 : template <typename TypeHandler>
1384 : inline typename TypeHandler::Type*
1385 : RepeatedPtrFieldBase::Mutable(int index) {
1386 : GOOGLE_DCHECK_GE(index, 0);
1387 : GOOGLE_DCHECK_LT(index, current_size_);
1388 24 : return cast<TypeHandler>(rep_->elements[index]);
1389 : }
1390 :
1391 : template <typename TypeHandler>
1392 : inline void RepeatedPtrFieldBase::Delete(int index) {
1393 : GOOGLE_DCHECK_GE(index, 0);
1394 : GOOGLE_DCHECK_LT(index, current_size_);
1395 : TypeHandler::Delete(cast<TypeHandler>(rep_->elements[index]), arena_);
1396 : }
1397 :
1398 : template <typename TypeHandler>
1399 44226 : inline typename TypeHandler::Type* RepeatedPtrFieldBase::Add(
1400 : typename TypeHandler::Type* prototype) {
1401 44226 : if (rep_ != NULL && current_size_ < rep_->allocated_size) {
1402 0 : return cast<TypeHandler>(rep_->elements[current_size_++]);
1403 : }
1404 44226 : if (!rep_ || rep_->allocated_size == total_size_) {
1405 7689 : Reserve(total_size_ + 1);
1406 : }
1407 44226 : ++rep_->allocated_size;
1408 : typename TypeHandler::Type* result =
1409 44524 : TypeHandler::NewFromPrototype(prototype, arena_);
1410 44226 : rep_->elements[current_size_++] = result;
1411 44226 : return result;
1412 : }
1413 :
1414 : template <typename TypeHandler>
1415 0 : inline void RepeatedPtrFieldBase::RemoveLast() {
1416 : GOOGLE_DCHECK_GT(current_size_, 0);
1417 0 : TypeHandler::Clear(cast<TypeHandler>(rep_->elements[--current_size_]));
1418 0 : }
1419 :
1420 : template <typename TypeHandler>
1421 2348 : void RepeatedPtrFieldBase::Clear() {
1422 2348 : const int n = current_size_;
1423 18 : GOOGLE_DCHECK_GE(n, 0);
1424 2348 : if (n > 0) {
1425 679 : void* const* elements = rep_->elements;
1426 679 : int i = 0;
1427 841 : do {
1428 841 : TypeHandler::Clear(cast<TypeHandler>(elements[i++]));
1429 : } while (i < n);
1430 679 : current_size_ = 0;
1431 : }
1432 2348 : }
1433 :
1434 : // To avoid unnecessary code duplication and reduce binary size, we use a
1435 : // layered approach to implementing MergeFrom(). The toplevel method is
1436 : // templated, so we get a small thunk per concrete message type in the binary.
1437 : // This calls a shared implementation with most of the logic, passing a function
1438 : // pointer to another type-specific piece of code that calls the object-allocate
1439 : // and merge handlers.
1440 : template <typename TypeHandler>
1441 26415 : inline void RepeatedPtrFieldBase::MergeFrom(const RepeatedPtrFieldBase& other) {
1442 24 : GOOGLE_DCHECK_NE(&other, this);
1443 52830 : if (other.current_size_ == 0) return;
1444 233 : MergeFromInternal(
1445 : other, &RepeatedPtrFieldBase::MergeFromInnerLoop<TypeHandler>);
1446 : }
1447 :
1448 233 : inline void RepeatedPtrFieldBase::MergeFromInternal(
1449 : const RepeatedPtrFieldBase& other,
1450 : void (RepeatedPtrFieldBase::*inner_loop)(void**, void**, int, int)) {
1451 : // Note: wrapper has already guaranteed that other.rep_ != NULL here.
1452 233 : int other_size = other.current_size_;
1453 233 : void** other_elements = other.rep_->elements;
1454 233 : void** new_elements = InternalExtend(other_size);
1455 233 : int allocated_elems = rep_->allocated_size - current_size_;
1456 : (this->*inner_loop)(new_elements, other_elements,
1457 233 : other_size, allocated_elems);
1458 233 : current_size_ += other_size;
1459 233 : if (rep_->allocated_size < current_size_) {
1460 233 : rep_->allocated_size = current_size_;
1461 : }
1462 233 : }
1463 :
1464 : // Merges other_elems to our_elems.
1465 : template<typename TypeHandler>
1466 233 : void RepeatedPtrFieldBase::MergeFromInnerLoop(
1467 215 : void** our_elems, void** other_elems, int length, int already_allocated) {
1468 : // Split into two loops, over ranges [0, allocated) and [allocated, length),
1469 : // to avoid a branch within the loop.
1470 233 : for (int i = 0; i < already_allocated && i < length; i++) {
1471 : // Already allocated: use existing element.
1472 : typename TypeHandler::Type* other_elem =
1473 0 : reinterpret_cast<typename TypeHandler::Type*>(other_elems[i]);
1474 : typename TypeHandler::Type* new_elem =
1475 0 : reinterpret_cast<typename TypeHandler::Type*>(our_elems[i]);
1476 0 : TypeHandler::Merge(*other_elem, new_elem);
1477 : }
1478 233 : Arena* arena = GetArenaNoVirtual();
1479 26393 : for (int i = already_allocated; i < length; i++) {
1480 : // Not allocated: alloc a new element first, then merge it.
1481 : typename TypeHandler::Type* other_elem =
1482 26160 : reinterpret_cast<typename TypeHandler::Type*>(other_elems[i]);
1483 : typename TypeHandler::Type* new_elem =
1484 26308 : TypeHandler::NewFromPrototype(other_elem, arena);
1485 26012 : TypeHandler::Merge(*other_elem, new_elem);
1486 26160 : our_elems[i] = new_elem;
1487 : }
1488 233 : }
1489 :
1490 : template <typename TypeHandler>
1491 : inline void RepeatedPtrFieldBase::CopyFrom(const RepeatedPtrFieldBase& other) {
1492 : if (&other == this) return;
1493 : RepeatedPtrFieldBase::Clear<TypeHandler>();
1494 : RepeatedPtrFieldBase::MergeFrom<TypeHandler>(other);
1495 : }
1496 :
1497 : inline int RepeatedPtrFieldBase::Capacity() const {
1498 : return total_size_;
1499 : }
1500 :
1501 : inline void* const* RepeatedPtrFieldBase::raw_data() const {
1502 0 : return rep_ ? rep_->elements : NULL;
1503 : }
1504 :
1505 : inline void** RepeatedPtrFieldBase::raw_mutable_data() const {
1506 0 : return rep_ ? const_cast<void**>(rep_->elements) : NULL;
1507 : }
1508 :
1509 : template <typename TypeHandler>
1510 : inline typename TypeHandler::Type** RepeatedPtrFieldBase::mutable_data() {
1511 : // TODO(kenton): Breaks C++ aliasing rules. We should probably remove this
1512 : // method entirely.
1513 : return reinterpret_cast<typename TypeHandler::Type**>(raw_mutable_data());
1514 : }
1515 :
1516 : template <typename TypeHandler>
1517 : inline const typename TypeHandler::Type* const*
1518 : RepeatedPtrFieldBase::data() const {
1519 : // TODO(kenton): Breaks C++ aliasing rules. We should probably remove this
1520 : // method entirely.
1521 : return reinterpret_cast<const typename TypeHandler::Type* const*>(raw_data());
1522 : }
1523 :
1524 : inline void RepeatedPtrFieldBase::SwapElements(int index1, int index2) {
1525 : using std::swap; // enable ADL with fallback
1526 0 : swap(rep_->elements[index1], rep_->elements[index2]);
1527 : }
1528 :
1529 : template <typename TypeHandler>
1530 0 : inline int RepeatedPtrFieldBase::SpaceUsedExcludingSelf() const {
1531 0 : int allocated_bytes = total_size_ * sizeof(void*);
1532 0 : if (rep_ != NULL) {
1533 0 : for (int i = 0; i < rep_->allocated_size; ++i) {
1534 0 : allocated_bytes += TypeHandler::SpaceUsed(
1535 0 : *cast<TypeHandler>(rep_->elements[i]));
1536 : }
1537 0 : allocated_bytes += kRepHeaderSize;
1538 : }
1539 0 : return allocated_bytes;
1540 : }
1541 :
1542 : template <typename TypeHandler>
1543 : inline typename TypeHandler::Type* RepeatedPtrFieldBase::AddFromCleared() {
1544 405 : if (rep_ != NULL && current_size_ < rep_->allocated_size) {
1545 0 : return cast<TypeHandler>(rep_->elements[current_size_++]);
1546 : } else {
1547 : return NULL;
1548 : }
1549 : }
1550 :
1551 : // AddAllocated version that implements arena-safe copying behavior.
1552 : template <typename TypeHandler>
1553 0 : void RepeatedPtrFieldBase::AddAllocatedInternal(
1554 : typename TypeHandler::Type* value,
1555 0 : google::protobuf::internal::true_type) {
1556 : Arena* element_arena = reinterpret_cast<Arena*>(
1557 0 : TypeHandler::GetMaybeArenaPointer(value));
1558 0 : Arena* arena = GetArenaNoVirtual();
1559 0 : if (arena == element_arena && rep_ &&
1560 : rep_->allocated_size < total_size_) {
1561 : // Fast path: underlying arena representation (tagged pointer) is equal to
1562 : // our arena pointer, and we can add to array without resizing it (at least
1563 : // one slot that is not allocated).
1564 0 : void** elems = rep_->elements;
1565 0 : if (current_size_ < rep_->allocated_size) {
1566 : // Make space at [current] by moving first allocated element to end of
1567 : // allocated list.
1568 0 : elems[rep_->allocated_size] = elems[current_size_];
1569 : }
1570 0 : elems[current_size_] = value;
1571 0 : current_size_ = current_size_ + 1;
1572 0 : rep_->allocated_size = rep_->allocated_size + 1;
1573 0 : return;
1574 : } else {
1575 0 : AddAllocatedSlowWithCopy<TypeHandler>(
1576 0 : value, TypeHandler::GetArena(value), arena);
1577 : }
1578 : }
1579 :
1580 : // Slowpath handles all cases, copying if necessary.
1581 : template<typename TypeHandler>
1582 0 : void RepeatedPtrFieldBase::AddAllocatedSlowWithCopy(
1583 : // Pass value_arena and my_arena to avoid duplicate virtual call (value) or
1584 : // load (mine).
1585 : typename TypeHandler::Type* value, Arena* value_arena, Arena* my_arena) {
1586 : // Ensure that either the value is in the same arena, or if not, we do the
1587 : // appropriate thing: Own() it (if it's on heap and we're in an arena) or copy
1588 : // it to our arena/heap (otherwise).
1589 0 : if (my_arena != NULL && value_arena == NULL) {
1590 0 : my_arena->Own(value);
1591 0 : } else if (my_arena != value_arena) {
1592 : typename TypeHandler::Type* new_value =
1593 0 : TypeHandler::NewFromPrototype(value, my_arena);
1594 0 : TypeHandler::Merge(*value, new_value);
1595 0 : TypeHandler::Delete(value, value_arena);
1596 0 : value = new_value;
1597 : }
1598 :
1599 0 : UnsafeArenaAddAllocated<TypeHandler>(value);
1600 0 : }
1601 :
1602 : // AddAllocated version that does not implement arena-safe copying behavior.
1603 : template <typename TypeHandler>
1604 0 : void RepeatedPtrFieldBase::AddAllocatedInternal(
1605 : typename TypeHandler::Type* value,
1606 : google::protobuf::internal::false_type) {
1607 0 : if (rep_ && rep_->allocated_size < total_size_) {
1608 : // Fast path: underlying arena representation (tagged pointer) is equal to
1609 : // our arena pointer, and we can add to array without resizing it (at least
1610 : // one slot that is not allocated).
1611 0 : void** elems = rep_->elements;
1612 0 : if (current_size_ < rep_->allocated_size) {
1613 : // Make space at [current] by moving first allocated element to end of
1614 : // allocated list.
1615 0 : elems[rep_->allocated_size] = elems[current_size_];
1616 : }
1617 0 : elems[current_size_] = value;
1618 0 : current_size_ = current_size_ + 1;
1619 0 : ++rep_->allocated_size;
1620 0 : return;
1621 : } else {
1622 0 : UnsafeArenaAddAllocated<TypeHandler>(value);
1623 : }
1624 : }
1625 :
1626 : template <typename TypeHandler>
1627 405 : void RepeatedPtrFieldBase::UnsafeArenaAddAllocated(
1628 : typename TypeHandler::Type* value) {
1629 : // Make room for the new pointer.
1630 405 : if (!rep_ || current_size_ == total_size_) {
1631 : // The array is completely full with no cleared objects, so grow it.
1632 296 : Reserve(total_size_ + 1);
1633 296 : ++rep_->allocated_size;
1634 109 : } else if (rep_->allocated_size == total_size_) {
1635 : // There is no more space in the pointer array because it contains some
1636 : // cleared objects awaiting reuse. We don't want to grow the array in this
1637 : // case because otherwise a loop calling AddAllocated() followed by Clear()
1638 : // would leak memory.
1639 0 : TypeHandler::Delete(
1640 0 : cast<TypeHandler>(rep_->elements[current_size_]), arena_);
1641 109 : } else if (current_size_ < rep_->allocated_size) {
1642 : // We have some cleared objects. We don't care about their order, so we
1643 : // can just move the first one to the end to make space.
1644 0 : rep_->elements[rep_->allocated_size] = rep_->elements[current_size_];
1645 0 : ++rep_->allocated_size;
1646 : } else {
1647 : // There are no cleared objects.
1648 109 : ++rep_->allocated_size;
1649 : }
1650 :
1651 405 : rep_->elements[current_size_++] = value;
1652 405 : }
1653 :
1654 : // ReleaseLast() for types that implement merge/copy behavior.
1655 : template <typename TypeHandler>
1656 : inline typename TypeHandler::Type*
1657 0 : RepeatedPtrFieldBase::ReleaseLastInternal(google::protobuf::internal::true_type) {
1658 : // First, release an element.
1659 0 : typename TypeHandler::Type* result = UnsafeArenaReleaseLast<TypeHandler>();
1660 : // Now perform a copy if we're on an arena.
1661 0 : Arena* arena = GetArenaNoVirtual();
1662 0 : if (arena == NULL) {
1663 : return result;
1664 : } else {
1665 : typename TypeHandler::Type* new_result =
1666 0 : TypeHandler::NewFromPrototype(result, NULL);
1667 0 : TypeHandler::Merge(*result, new_result);
1668 : return new_result;
1669 : }
1670 : }
1671 :
1672 : // ReleaseLast() for types that *do not* implement merge/copy behavior -- this
1673 : // is the same as UnsafeArenaReleaseLast(). Note that we GOOGLE_DCHECK-fail if we're on
1674 : // an arena, since the user really should implement the copy operation in this
1675 : // case.
1676 : template <typename TypeHandler>
1677 : inline typename TypeHandler::Type*
1678 0 : RepeatedPtrFieldBase::ReleaseLastInternal(google::protobuf::internal::false_type) {
1679 : GOOGLE_DCHECK(GetArenaNoVirtual() == NULL)
1680 : << "ReleaseLast() called on a RepeatedPtrField that is on an arena, "
1681 : << "with a type that does not implement MergeFrom. This is unsafe; "
1682 : << "please implement MergeFrom for your type.";
1683 0 : return UnsafeArenaReleaseLast<TypeHandler>();
1684 : }
1685 :
1686 : template <typename TypeHandler>
1687 : inline typename TypeHandler::Type*
1688 : RepeatedPtrFieldBase::UnsafeArenaReleaseLast() {
1689 : GOOGLE_DCHECK_GT(current_size_, 0);
1690 : typename TypeHandler::Type* result =
1691 0 : cast<TypeHandler>(rep_->elements[--current_size_]);
1692 0 : --rep_->allocated_size;
1693 0 : if (current_size_ < rep_->allocated_size) {
1694 : // There are cleared elements on the end; replace the removed element
1695 : // with the last allocated element.
1696 0 : rep_->elements[current_size_] = rep_->elements[rep_->allocated_size];
1697 : }
1698 : return result;
1699 : }
1700 :
1701 : inline int RepeatedPtrFieldBase::ClearedCount() const {
1702 : return rep_ ? (rep_->allocated_size - current_size_) : 0;
1703 : }
1704 :
1705 : template <typename TypeHandler>
1706 : inline void RepeatedPtrFieldBase::AddCleared(
1707 : typename TypeHandler::Type* value) {
1708 : GOOGLE_DCHECK(GetArenaNoVirtual() == NULL)
1709 : << "AddCleared() can only be used on a RepeatedPtrField not on an arena.";
1710 : GOOGLE_DCHECK(TypeHandler::GetArena(value) == NULL)
1711 : << "AddCleared() can only accept values not on an arena.";
1712 : if (!rep_ || rep_->allocated_size == total_size_) {
1713 : Reserve(total_size_ + 1);
1714 : }
1715 : rep_->elements[rep_->allocated_size++] = value;
1716 : }
1717 :
1718 : template <typename TypeHandler>
1719 : inline typename TypeHandler::Type* RepeatedPtrFieldBase::ReleaseCleared() {
1720 : GOOGLE_DCHECK(GetArenaNoVirtual() == NULL)
1721 : << "ReleaseCleared() can only be used on a RepeatedPtrField not on "
1722 : << "an arena.";
1723 : GOOGLE_DCHECK(GetArenaNoVirtual() == NULL);
1724 : GOOGLE_DCHECK(rep_ != NULL);
1725 : GOOGLE_DCHECK_GT(rep_->allocated_size, current_size_);
1726 : return cast<TypeHandler>(rep_->elements[--rep_->allocated_size]);
1727 : }
1728 :
1729 : } // namespace internal
1730 :
1731 : // -------------------------------------------------------------------
1732 :
1733 : template <typename Element>
1734 : class RepeatedPtrField<Element>::TypeHandler
1735 : : public internal::GenericTypeHandler<Element> {
1736 : };
1737 :
1738 : template <>
1739 : class RepeatedPtrField<string>::TypeHandler
1740 : : public internal::StringTypeHandler {
1741 : };
1742 :
1743 :
1744 : template <typename Element>
1745 67 : inline RepeatedPtrField<Element>::RepeatedPtrField()
1746 78779 : : RepeatedPtrFieldBase() {}
1747 :
1748 : template <typename Element>
1749 0 : inline RepeatedPtrField<Element>::RepeatedPtrField(::google::protobuf::Arena* arena) :
1750 0 : RepeatedPtrFieldBase(arena) {}
1751 :
1752 : template <typename Element>
1753 : inline RepeatedPtrField<Element>::RepeatedPtrField(
1754 : const RepeatedPtrField& other)
1755 : : RepeatedPtrFieldBase() {
1756 : CopyFrom(other);
1757 : }
1758 :
1759 : template <typename Element>
1760 : template <typename Iter>
1761 : inline RepeatedPtrField<Element>::RepeatedPtrField(
1762 : Iter begin, const Iter& end) {
1763 : int reserve = internal::CalculateReserve(begin, end);
1764 : if (reserve != -1) {
1765 : Reserve(reserve);
1766 : }
1767 : for (; begin != end; ++begin) {
1768 : *Add() = *begin;
1769 : }
1770 : }
1771 :
1772 : template <typename Element>
1773 56 : RepeatedPtrField<Element>::~RepeatedPtrField() {
1774 77390 : Destroy<TypeHandler>();
1775 77388 : }
1776 :
1777 : template <typename Element>
1778 : inline RepeatedPtrField<Element>& RepeatedPtrField<Element>::operator=(
1779 : const RepeatedPtrField& other) {
1780 : if (this != &other)
1781 : CopyFrom(other);
1782 : return *this;
1783 : }
1784 :
1785 : template <typename Element>
1786 : inline bool RepeatedPtrField<Element>::empty() const {
1787 0 : return RepeatedPtrFieldBase::empty();
1788 : }
1789 :
1790 : template <typename Element>
1791 62 : inline int RepeatedPtrField<Element>::size() const {
1792 72207 : return RepeatedPtrFieldBase::size();
1793 : }
1794 :
1795 : template <typename Element>
1796 56 : inline const Element& RepeatedPtrField<Element>::Get(int index) const {
1797 45502 : return RepeatedPtrFieldBase::Get<TypeHandler>(index);
1798 : }
1799 :
1800 :
1801 : template <typename Element>
1802 : inline Element* RepeatedPtrField<Element>::Mutable(int index) {
1803 24 : return RepeatedPtrFieldBase::Mutable<TypeHandler>(index);
1804 : }
1805 :
1806 : template <typename Element>
1807 12 : inline Element* RepeatedPtrField<Element>::Add() {
1808 44226 : return RepeatedPtrFieldBase::Add<TypeHandler>();
1809 : }
1810 :
1811 : template <typename Element>
1812 : inline void RepeatedPtrField<Element>::RemoveLast() {
1813 0 : RepeatedPtrFieldBase::RemoveLast<TypeHandler>();
1814 : }
1815 :
1816 : template <typename Element>
1817 : inline void RepeatedPtrField<Element>::DeleteSubrange(int start, int num) {
1818 : GOOGLE_DCHECK_GE(start, 0);
1819 : GOOGLE_DCHECK_GE(num, 0);
1820 : GOOGLE_DCHECK_LE(start + num, size());
1821 : for (int i = 0; i < num; ++i) {
1822 : RepeatedPtrFieldBase::Delete<TypeHandler>(start + i);
1823 : }
1824 : ExtractSubrange(start, num, NULL);
1825 : }
1826 :
1827 : template <typename Element>
1828 : inline void RepeatedPtrField<Element>::ExtractSubrange(
1829 : int start, int num, Element** elements) {
1830 : typename internal::TypeImplementsMergeBehavior<
1831 : typename TypeHandler::Type>::type t;
1832 : ExtractSubrangeInternal(start, num, elements, t);
1833 : }
1834 :
1835 : // ExtractSubrange() implementation for types that implement merge/copy
1836 : // behavior.
1837 : template <typename Element>
1838 : inline void RepeatedPtrField<Element>::ExtractSubrangeInternal(
1839 : int start, int num, Element** elements, google::protobuf::internal::true_type) {
1840 : GOOGLE_DCHECK_GE(start, 0);
1841 : GOOGLE_DCHECK_GE(num, 0);
1842 : GOOGLE_DCHECK_LE(start + num, size());
1843 :
1844 : if (num > 0) {
1845 : // Save the values of the removed elements if requested.
1846 : if (elements != NULL) {
1847 : if (GetArenaNoVirtual() != NULL) {
1848 : // If we're on an arena, we perform a copy for each element so that the
1849 : // returned elements are heap-allocated.
1850 : for (int i = 0; i < num; ++i) {
1851 : Element* element = RepeatedPtrFieldBase::
1852 : Mutable<TypeHandler>(i + start);
1853 : typename TypeHandler::Type* new_value =
1854 : TypeHandler::NewFromPrototype(element, NULL);
1855 : TypeHandler::Merge(*element, new_value);
1856 : elements[i] = new_value;
1857 : }
1858 : } else {
1859 : for (int i = 0; i < num; ++i) {
1860 : elements[i] = RepeatedPtrFieldBase::Mutable<TypeHandler>(i + start);
1861 : }
1862 : }
1863 : }
1864 : CloseGap(start, num);
1865 : }
1866 : }
1867 :
1868 : // ExtractSubrange() implementation for types that do not implement merge/copy
1869 : // behavior.
1870 : template<typename Element>
1871 : inline void RepeatedPtrField<Element>::ExtractSubrangeInternal(
1872 : int start, int num, Element** elements, google::protobuf::internal::false_type) {
1873 : // This case is identical to UnsafeArenaExtractSubrange(). However, since
1874 : // ExtractSubrange() must return heap-allocated objects by contract, and we
1875 : // cannot fulfill this contract if we are an on arena, we must GOOGLE_DCHECK() that
1876 : // we are not on an arena.
1877 : GOOGLE_DCHECK(GetArenaNoVirtual() == NULL)
1878 : << "ExtractSubrange() when arena is non-NULL is only supported when "
1879 : << "the Element type supplies a MergeFrom() operation to make copies.";
1880 : UnsafeArenaExtractSubrange(start, num, elements);
1881 : }
1882 :
1883 : template <typename Element>
1884 : inline void RepeatedPtrField<Element>::UnsafeArenaExtractSubrange(
1885 : int start, int num, Element** elements) {
1886 : GOOGLE_DCHECK_GE(start, 0);
1887 : GOOGLE_DCHECK_GE(num, 0);
1888 : GOOGLE_DCHECK_LE(start + num, size());
1889 :
1890 : if (num > 0) {
1891 : // Save the values of the removed elements if requested.
1892 : if (elements != NULL) {
1893 : for (int i = 0; i < num; ++i) {
1894 : elements[i] = RepeatedPtrFieldBase::Mutable<TypeHandler>(i + start);
1895 : }
1896 : }
1897 : CloseGap(start, num);
1898 : }
1899 : }
1900 :
1901 : template <typename Element>
1902 18 : inline void RepeatedPtrField<Element>::Clear() {
1903 2074 : RepeatedPtrFieldBase::Clear<TypeHandler>();
1904 18 : }
1905 :
1906 : template <typename Element>
1907 24 : inline void RepeatedPtrField<Element>::MergeFrom(
1908 : const RepeatedPtrField& other) {
1909 26415 : RepeatedPtrFieldBase::MergeFrom<TypeHandler>(other);
1910 24 : }
1911 :
1912 : template <typename Element>
1913 : inline void RepeatedPtrField<Element>::CopyFrom(
1914 : const RepeatedPtrField& other) {
1915 : RepeatedPtrFieldBase::CopyFrom<TypeHandler>(other);
1916 : }
1917 :
1918 : template <typename Element>
1919 : inline typename RepeatedPtrField<Element>::iterator
1920 : RepeatedPtrField<Element>::erase(const_iterator position) {
1921 : return erase(position, position + 1);
1922 : }
1923 :
1924 : template <typename Element>
1925 : inline typename RepeatedPtrField<Element>::iterator
1926 : RepeatedPtrField<Element>::erase(const_iterator first, const_iterator last) {
1927 : size_type pos_offset = std::distance(cbegin(), first);
1928 : size_type last_offset = std::distance(cbegin(), last);
1929 : DeleteSubrange(pos_offset, last_offset - pos_offset);
1930 : return begin() + pos_offset;
1931 : }
1932 :
1933 : template <typename Element>
1934 : inline Element** RepeatedPtrField<Element>::mutable_data() {
1935 : return RepeatedPtrFieldBase::mutable_data<TypeHandler>();
1936 : }
1937 :
1938 : template <typename Element>
1939 : inline const Element* const* RepeatedPtrField<Element>::data() const {
1940 : return RepeatedPtrFieldBase::data<TypeHandler>();
1941 : }
1942 :
1943 : template <typename Element>
1944 0 : inline void RepeatedPtrField<Element>::Swap(RepeatedPtrField* other) {
1945 0 : if (this == other)
1946 0 : return;
1947 0 : RepeatedPtrFieldBase::Swap<TypeHandler>(other);
1948 : }
1949 :
1950 : template <typename Element>
1951 0 : inline void RepeatedPtrField<Element>::UnsafeArenaSwap(
1952 : RepeatedPtrField* other) {
1953 0 : GOOGLE_DCHECK(GetArenaNoVirtual() == other->GetArenaNoVirtual());
1954 78 : if (this == other)
1955 0 : return;
1956 78 : RepeatedPtrFieldBase::InternalSwap(other);
1957 : }
1958 :
1959 : template <typename Element>
1960 : inline void RepeatedPtrField<Element>::SwapElements(int index1, int index2) {
1961 0 : RepeatedPtrFieldBase::SwapElements(index1, index2);
1962 : }
1963 :
1964 : template <typename Element>
1965 0 : inline Arena* RepeatedPtrField<Element>::GetArenaNoVirtual() const {
1966 0 : return RepeatedPtrFieldBase::GetArenaNoVirtual();
1967 : }
1968 :
1969 : template <typename Element>
1970 : inline int RepeatedPtrField<Element>::SpaceUsedExcludingSelf() const {
1971 0 : return RepeatedPtrFieldBase::SpaceUsedExcludingSelf<TypeHandler>();
1972 : }
1973 :
1974 : template <typename Element>
1975 : inline void RepeatedPtrField<Element>::AddAllocated(Element* value) {
1976 0 : RepeatedPtrFieldBase::AddAllocated<TypeHandler>(value);
1977 : }
1978 :
1979 : template <typename Element>
1980 : inline void RepeatedPtrField<Element>::UnsafeArenaAddAllocated(Element* value) {
1981 : RepeatedPtrFieldBase::UnsafeArenaAddAllocated<TypeHandler>(value);
1982 : }
1983 :
1984 : template <typename Element>
1985 : inline Element* RepeatedPtrField<Element>::ReleaseLast() {
1986 0 : return RepeatedPtrFieldBase::ReleaseLast<TypeHandler>();
1987 : }
1988 :
1989 : template <typename Element>
1990 : inline Element* RepeatedPtrField<Element>::UnsafeArenaReleaseLast() {
1991 : return RepeatedPtrFieldBase::UnsafeArenaReleaseLast<TypeHandler>();
1992 : }
1993 :
1994 : template <typename Element>
1995 : inline int RepeatedPtrField<Element>::ClearedCount() const {
1996 : return RepeatedPtrFieldBase::ClearedCount();
1997 : }
1998 :
1999 : template <typename Element>
2000 : inline void RepeatedPtrField<Element>::AddCleared(Element* value) {
2001 : return RepeatedPtrFieldBase::AddCleared<TypeHandler>(value);
2002 : }
2003 :
2004 : template <typename Element>
2005 : inline Element* RepeatedPtrField<Element>::ReleaseCleared() {
2006 : return RepeatedPtrFieldBase::ReleaseCleared<TypeHandler>();
2007 : }
2008 :
2009 : template <typename Element>
2010 : inline void RepeatedPtrField<Element>::Reserve(int new_size) {
2011 : return RepeatedPtrFieldBase::Reserve(new_size);
2012 : }
2013 :
2014 : template <typename Element>
2015 : inline int RepeatedPtrField<Element>::Capacity() const {
2016 : return RepeatedPtrFieldBase::Capacity();
2017 : }
2018 :
2019 : // -------------------------------------------------------------------
2020 :
2021 : namespace internal {
2022 :
2023 : // STL-like iterator implementation for RepeatedPtrField. You should not
2024 : // refer to this class directly; use RepeatedPtrField<T>::iterator instead.
2025 : //
2026 : // The iterator for RepeatedPtrField<T>, RepeatedPtrIterator<T>, is
2027 : // very similar to iterator_ptr<T**> in util/gtl/iterator_adaptors.h,
2028 : // but adds random-access operators and is modified to wrap a void** base
2029 : // iterator (since RepeatedPtrField stores its array as a void* array and
2030 : // casting void** to T** would violate C++ aliasing rules).
2031 : //
2032 : // This code based on net/proto/proto-array-internal.h by Jeffrey Yasskin
2033 : // (jyasskin@google.com).
2034 : template<typename Element>
2035 : class RepeatedPtrIterator
2036 : : public std::iterator<
2037 : std::random_access_iterator_tag, Element> {
2038 : public:
2039 : typedef RepeatedPtrIterator<Element> iterator;
2040 : typedef std::iterator<
2041 : std::random_access_iterator_tag, Element> superclass;
2042 :
2043 : // Shadow the value_type in std::iterator<> because const_iterator::value_type
2044 : // needs to be T, not const T.
2045 : typedef typename remove_const<Element>::type value_type;
2046 :
2047 : // Let the compiler know that these are type names, so we don't have to
2048 : // write "typename" in front of them everywhere.
2049 : typedef typename superclass::reference reference;
2050 : typedef typename superclass::pointer pointer;
2051 : typedef typename superclass::difference_type difference_type;
2052 :
2053 : RepeatedPtrIterator() : it_(NULL) {}
2054 : explicit RepeatedPtrIterator(void* const* it) : it_(it) {}
2055 :
2056 : // Allow "upcasting" from RepeatedPtrIterator<T**> to
2057 : // RepeatedPtrIterator<const T*const*>.
2058 : template<typename OtherElement>
2059 : RepeatedPtrIterator(const RepeatedPtrIterator<OtherElement>& other)
2060 : : it_(other.it_) {
2061 : // Force a compiler error if the other type is not convertible to ours.
2062 : if (false) {
2063 : implicit_cast<Element*, OtherElement*>(0);
2064 : }
2065 : }
2066 :
2067 : // dereferenceable
2068 0 : reference operator*() const { return *reinterpret_cast<Element*>(*it_); }
2069 : pointer operator->() const { return &(operator*()); }
2070 :
2071 : // {inc,dec}rementable
2072 0 : iterator& operator++() { ++it_; return *this; }
2073 : iterator operator++(int) { return iterator(it_++); }
2074 : iterator& operator--() { --it_; return *this; }
2075 : iterator operator--(int) { return iterator(it_--); }
2076 :
2077 : // equality_comparable
2078 : bool operator==(const iterator& x) const { return it_ == x.it_; }
2079 0 : bool operator!=(const iterator& x) const { return it_ != x.it_; }
2080 :
2081 : // less_than_comparable
2082 : bool operator<(const iterator& x) const { return it_ < x.it_; }
2083 : bool operator<=(const iterator& x) const { return it_ <= x.it_; }
2084 : bool operator>(const iterator& x) const { return it_ > x.it_; }
2085 : bool operator>=(const iterator& x) const { return it_ >= x.it_; }
2086 :
2087 : // addable, subtractable
2088 : iterator& operator+=(difference_type d) {
2089 0 : it_ += d;
2090 : return *this;
2091 : }
2092 : friend iterator operator+(iterator it, const difference_type d) {
2093 : it += d;
2094 : return it;
2095 : }
2096 : friend iterator operator+(const difference_type d, iterator it) {
2097 : it += d;
2098 : return it;
2099 : }
2100 : iterator& operator-=(difference_type d) {
2101 : it_ -= d;
2102 : return *this;
2103 : }
2104 : friend iterator operator-(iterator it, difference_type d) {
2105 : it -= d;
2106 : return it;
2107 : }
2108 :
2109 : // indexable
2110 : reference operator[](difference_type d) const { return *(*this + d); }
2111 :
2112 : // random access iterator
2113 0 : difference_type operator-(const iterator& x) const { return it_ - x.it_; }
2114 :
2115 : private:
2116 : template<typename OtherElement>
2117 : friend class RepeatedPtrIterator;
2118 :
2119 : // The internal iterator.
2120 : void* const* it_;
2121 : };
2122 :
2123 : // Provide an iterator that operates on pointers to the underlying objects
2124 : // rather than the objects themselves as RepeatedPtrIterator does.
2125 : // Consider using this when working with stl algorithms that change
2126 : // the array.
2127 : // The VoidPtr template parameter holds the type-agnostic pointer value
2128 : // referenced by the iterator. It should either be "void *" for a mutable
2129 : // iterator, or "const void *" for a constant iterator.
2130 : template<typename Element, typename VoidPtr>
2131 : class RepeatedPtrOverPtrsIterator
2132 : : public std::iterator<std::random_access_iterator_tag, Element*> {
2133 : public:
2134 : typedef RepeatedPtrOverPtrsIterator<Element, VoidPtr> iterator;
2135 : typedef std::iterator<
2136 : std::random_access_iterator_tag, Element*> superclass;
2137 :
2138 : // Shadow the value_type in std::iterator<> because const_iterator::value_type
2139 : // needs to be T, not const T.
2140 : typedef typename remove_const<Element*>::type value_type;
2141 :
2142 : // Let the compiler know that these are type names, so we don't have to
2143 : // write "typename" in front of them everywhere.
2144 : typedef typename superclass::reference reference;
2145 : typedef typename superclass::pointer pointer;
2146 : typedef typename superclass::difference_type difference_type;
2147 :
2148 : RepeatedPtrOverPtrsIterator() : it_(NULL) {}
2149 : explicit RepeatedPtrOverPtrsIterator(VoidPtr* it) : it_(it) {}
2150 :
2151 : // dereferenceable
2152 : reference operator*() const { return *reinterpret_cast<Element**>(it_); }
2153 : pointer operator->() const { return &(operator*()); }
2154 :
2155 : // {inc,dec}rementable
2156 0 : iterator& operator++() { ++it_; return *this; }
2157 : iterator operator++(int) { return iterator(it_++); }
2158 : iterator& operator--() { --it_; return *this; }
2159 : iterator operator--(int) { return iterator(it_--); }
2160 :
2161 : // equality_comparable
2162 : bool operator==(const iterator& x) const { return it_ == x.it_; }
2163 : bool operator!=(const iterator& x) const { return it_ != x.it_; }
2164 :
2165 : // less_than_comparable
2166 : bool operator<(const iterator& x) const { return it_ < x.it_; }
2167 : bool operator<=(const iterator& x) const { return it_ <= x.it_; }
2168 : bool operator>(const iterator& x) const { return it_ > x.it_; }
2169 : bool operator>=(const iterator& x) const { return it_ >= x.it_; }
2170 :
2171 : // addable, subtractable
2172 : iterator& operator+=(difference_type d) {
2173 : it_ += d;
2174 : return *this;
2175 : }
2176 : friend iterator operator+(iterator it, difference_type d) {
2177 : it += d;
2178 : return it;
2179 : }
2180 : friend iterator operator+(difference_type d, iterator it) {
2181 : it += d;
2182 : return it;
2183 : }
2184 : iterator& operator-=(difference_type d) {
2185 : it_ -= d;
2186 : return *this;
2187 : }
2188 : friend iterator operator-(iterator it, difference_type d) {
2189 : it -= d;
2190 : return it;
2191 : }
2192 :
2193 : // indexable
2194 : reference operator[](difference_type d) const { return *(*this + d); }
2195 :
2196 : // random access iterator
2197 : difference_type operator-(const iterator& x) const { return it_ - x.it_; }
2198 :
2199 : private:
2200 : template<typename OtherElement>
2201 : friend class RepeatedPtrIterator;
2202 :
2203 : // The internal iterator.
2204 : VoidPtr* it_;
2205 : };
2206 :
2207 0 : void RepeatedPtrFieldBase::InternalSwap(RepeatedPtrFieldBase* other) {
2208 78 : std::swap(rep_, other->rep_);
2209 78 : std::swap(current_size_, other->current_size_);
2210 78 : std::swap(total_size_, other->total_size_);
2211 0 : }
2212 :
2213 : } // namespace internal
2214 :
2215 : template <typename Element>
2216 : inline typename RepeatedPtrField<Element>::iterator
2217 : RepeatedPtrField<Element>::begin() {
2218 0 : return iterator(raw_data());
2219 : }
2220 : template <typename Element>
2221 : inline typename RepeatedPtrField<Element>::const_iterator
2222 : RepeatedPtrField<Element>::begin() const {
2223 0 : return iterator(raw_data());
2224 : }
2225 : template <typename Element>
2226 : inline typename RepeatedPtrField<Element>::const_iterator
2227 : RepeatedPtrField<Element>::cbegin() const {
2228 : return begin();
2229 : }
2230 : template <typename Element>
2231 : inline typename RepeatedPtrField<Element>::iterator
2232 : RepeatedPtrField<Element>::end() {
2233 0 : return iterator(raw_data() + size());
2234 : }
2235 : template <typename Element>
2236 : inline typename RepeatedPtrField<Element>::const_iterator
2237 : RepeatedPtrField<Element>::end() const {
2238 0 : return iterator(raw_data() + size());
2239 : }
2240 : template <typename Element>
2241 : inline typename RepeatedPtrField<Element>::const_iterator
2242 : RepeatedPtrField<Element>::cend() const {
2243 : return end();
2244 : }
2245 :
2246 : template <typename Element>
2247 : inline typename RepeatedPtrField<Element>::pointer_iterator
2248 : RepeatedPtrField<Element>::pointer_begin() {
2249 : return pointer_iterator(raw_mutable_data());
2250 : }
2251 : template <typename Element>
2252 : inline typename RepeatedPtrField<Element>::const_pointer_iterator
2253 : RepeatedPtrField<Element>::pointer_begin() const {
2254 0 : return const_pointer_iterator(const_cast<const void**>(raw_mutable_data()));
2255 : }
2256 : template <typename Element>
2257 : inline typename RepeatedPtrField<Element>::pointer_iterator
2258 : RepeatedPtrField<Element>::pointer_end() {
2259 : return pointer_iterator(raw_mutable_data() + size());
2260 : }
2261 : template <typename Element>
2262 : inline typename RepeatedPtrField<Element>::const_pointer_iterator
2263 : RepeatedPtrField<Element>::pointer_end() const {
2264 : return const_pointer_iterator(
2265 0 : const_cast<const void**>(raw_mutable_data() + size()));
2266 : }
2267 :
2268 :
2269 : // Iterators and helper functions that follow the spirit of the STL
2270 : // std::back_insert_iterator and std::back_inserter but are tailor-made
2271 : // for RepeatedField and RepeatedPtrField. Typical usage would be:
2272 : //
2273 : // std::copy(some_sequence.begin(), some_sequence.end(),
2274 : // google::protobuf::RepeatedFieldBackInserter(proto.mutable_sequence()));
2275 : //
2276 : // Ported by johannes from util/gtl/proto-array-iterators.h
2277 :
2278 : namespace internal {
2279 : // A back inserter for RepeatedField objects.
2280 : template<typename T> class RepeatedFieldBackInsertIterator
2281 : : public std::iterator<std::output_iterator_tag, T> {
2282 : public:
2283 : explicit RepeatedFieldBackInsertIterator(
2284 : RepeatedField<T>* const mutable_field)
2285 : : field_(mutable_field) {
2286 : }
2287 : RepeatedFieldBackInsertIterator<T>& operator=(const T& value) {
2288 : field_->Add(value);
2289 : return *this;
2290 : }
2291 : RepeatedFieldBackInsertIterator<T>& operator*() {
2292 : return *this;
2293 : }
2294 : RepeatedFieldBackInsertIterator<T>& operator++() {
2295 : return *this;
2296 : }
2297 : RepeatedFieldBackInsertIterator<T>& operator++(int /* unused */) {
2298 : return *this;
2299 : }
2300 :
2301 : private:
2302 : RepeatedField<T>* field_;
2303 : };
2304 :
2305 : // A back inserter for RepeatedPtrField objects.
2306 : template<typename T> class RepeatedPtrFieldBackInsertIterator
2307 : : public std::iterator<std::output_iterator_tag, T> {
2308 : public:
2309 : RepeatedPtrFieldBackInsertIterator(
2310 : RepeatedPtrField<T>* const mutable_field)
2311 : : field_(mutable_field) {
2312 : }
2313 : RepeatedPtrFieldBackInsertIterator<T>& operator=(const T& value) {
2314 : *field_->Add() = value;
2315 : return *this;
2316 : }
2317 : RepeatedPtrFieldBackInsertIterator<T>& operator=(
2318 : const T* const ptr_to_value) {
2319 : *field_->Add() = *ptr_to_value;
2320 : return *this;
2321 : }
2322 : RepeatedPtrFieldBackInsertIterator<T>& operator*() {
2323 : return *this;
2324 : }
2325 : RepeatedPtrFieldBackInsertIterator<T>& operator++() {
2326 : return *this;
2327 : }
2328 : RepeatedPtrFieldBackInsertIterator<T>& operator++(int /* unused */) {
2329 : return *this;
2330 : }
2331 :
2332 : private:
2333 : RepeatedPtrField<T>* field_;
2334 : };
2335 :
2336 : // A back inserter for RepeatedPtrFields that inserts by transfering ownership
2337 : // of a pointer.
2338 : template<typename T> class AllocatedRepeatedPtrFieldBackInsertIterator
2339 : : public std::iterator<std::output_iterator_tag, T> {
2340 : public:
2341 : explicit AllocatedRepeatedPtrFieldBackInsertIterator(
2342 : RepeatedPtrField<T>* const mutable_field)
2343 : : field_(mutable_field) {
2344 : }
2345 : AllocatedRepeatedPtrFieldBackInsertIterator<T>& operator=(
2346 : T* const ptr_to_value) {
2347 : field_->AddAllocated(ptr_to_value);
2348 : return *this;
2349 : }
2350 : AllocatedRepeatedPtrFieldBackInsertIterator<T>& operator*() {
2351 : return *this;
2352 : }
2353 : AllocatedRepeatedPtrFieldBackInsertIterator<T>& operator++() {
2354 : return *this;
2355 : }
2356 : AllocatedRepeatedPtrFieldBackInsertIterator<T>& operator++(
2357 : int /* unused */) {
2358 : return *this;
2359 : }
2360 :
2361 : private:
2362 : RepeatedPtrField<T>* field_;
2363 : };
2364 : } // namespace internal
2365 :
2366 : // Provides a back insert iterator for RepeatedField instances,
2367 : // similar to std::back_inserter().
2368 : template<typename T> internal::RepeatedFieldBackInsertIterator<T>
2369 : RepeatedFieldBackInserter(RepeatedField<T>* const mutable_field) {
2370 : return internal::RepeatedFieldBackInsertIterator<T>(mutable_field);
2371 : }
2372 :
2373 : // Provides a back insert iterator for RepeatedPtrField instances,
2374 : // similar to std::back_inserter().
2375 : template<typename T> internal::RepeatedPtrFieldBackInsertIterator<T>
2376 : RepeatedPtrFieldBackInserter(RepeatedPtrField<T>* const mutable_field) {
2377 : return internal::RepeatedPtrFieldBackInsertIterator<T>(mutable_field);
2378 : }
2379 :
2380 : // Special back insert iterator for RepeatedPtrField instances, just in
2381 : // case someone wants to write generic template code that can access both
2382 : // RepeatedFields and RepeatedPtrFields using a common name.
2383 : template<typename T> internal::RepeatedPtrFieldBackInsertIterator<T>
2384 : RepeatedFieldBackInserter(RepeatedPtrField<T>* const mutable_field) {
2385 : return internal::RepeatedPtrFieldBackInsertIterator<T>(mutable_field);
2386 : }
2387 :
2388 : // Provides a back insert iterator for RepeatedPtrField instances
2389 : // similar to std::back_inserter() which transfers the ownership while
2390 : // copying elements.
2391 : template<typename T> internal::AllocatedRepeatedPtrFieldBackInsertIterator<T>
2392 : AllocatedRepeatedPtrFieldBackInserter(
2393 : RepeatedPtrField<T>* const mutable_field) {
2394 : return internal::AllocatedRepeatedPtrFieldBackInsertIterator<T>(
2395 : mutable_field);
2396 : }
2397 :
2398 : } // namespace protobuf
2399 :
2400 : } // namespace google
2401 : #endif // GOOGLE_PROTOBUF_REPEATED_FIELD_H__
|