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