Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(822)

Side by Side Diff: third_party/protobuf/src/google/protobuf/repeated_field.h

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

Powered by Google App Engine
This is Rietveld 408576698