Line data Source code
1 : // Protocol Buffers - Google's data interchange format
2 : // Copyright 2008 Google Inc. All rights reserved.
3 : // https://developers.google.com/protocol-buffers/
4 : //
5 : // Redistribution and use in source and binary forms, with or without
6 : // modification, are permitted provided that the following conditions are
7 : // met:
8 : //
9 : // * Redistributions of source code must retain the above copyright
10 : // notice, this list of conditions and the following disclaimer.
11 : // * Redistributions in binary form must reproduce the above
12 : // copyright notice, this list of conditions and the following disclaimer
13 : // in the documentation and/or other materials provided with the
14 : // distribution.
15 : // * Neither the name of Google Inc. nor the names of its
16 : // contributors may be used to endorse or promote products derived from
17 : // this software without specific prior written permission.
18 : //
19 : // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 : // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 : // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 : // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23 : // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 : // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 : // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 : // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 : // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 : // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 : // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 :
31 : // Author: kenton@google.com (Kenton Varda)
32 : // Based on original Protocol Buffers design by
33 : // Sanjay Ghemawat, Jeff Dean, and others.
34 : //
35 : // RepeatedField and RepeatedPtrField are used by generated protocol message
36 : // classes to manipulate repeated fields. These classes are very similar to
37 : // STL's vector, but include a number of optimizations found to be useful
38 : // specifically in the case of Protocol Buffers. RepeatedPtrField is
39 : // particularly different from STL vector as it manages ownership of the
40 : // pointers that it contains.
41 : //
42 : // Typically, clients should not need to access RepeatedField objects directly,
43 : // but should instead use the accessor functions generated automatically by the
44 : // protocol compiler.
45 :
46 : #ifndef GOOGLE_PROTOBUF_REPEATED_FIELD_H__
47 : #define GOOGLE_PROTOBUF_REPEATED_FIELD_H__
48 :
49 : #ifdef _MSC_VER
50 : // This is required for min/max on VS2013 only.
51 : #include <algorithm>
52 : #endif
53 :
54 : #include <string>
55 : #include <iterator>
56 : #include <google/protobuf/stubs/common.h>
57 : #include <google/protobuf/stubs/type_traits.h>
58 : #include <google/protobuf/generated_message_util.h>
59 : #include <google/protobuf/message_lite.h>
60 :
61 : namespace google {
62 :
63 : namespace upb {
64 : namespace google_opensource {
65 : class GMR_Handlers;
66 : } // namespace google_opensource
67 : } // namespace upb
68 :
69 : namespace protobuf {
70 :
71 : class Message;
72 :
73 : namespace internal {
74 :
75 : static const int kMinRepeatedFieldAllocationSize = 4;
76 :
77 : // A utility function for logging that doesn't need any template types.
78 : void LogIndexOutOfBounds(int index, int size);
79 :
80 : template <typename Iter>
81 : inline int CalculateReserve(Iter begin, Iter end, std::forward_iterator_tag) {
82 : return std::distance(begin, end);
83 : }
84 :
85 : template <typename Iter>
86 : inline int CalculateReserve(Iter begin, Iter end, std::input_iterator_tag) {
87 : return -1;
88 : }
89 :
90 : template <typename Iter>
91 : inline int CalculateReserve(Iter begin, Iter end) {
92 : typedef typename std::iterator_traits<Iter>::iterator_category Category;
93 : return CalculateReserve(begin, end, Category());
94 : }
95 : } // namespace internal
96 :
97 :
98 : // RepeatedField is used to represent repeated fields of a primitive type (in
99 : // other words, everything except strings and nested Messages). Most users will
100 : // not ever use a RepeatedField directly; they will use the get-by-index,
101 : // set-by-index, and add accessors that are generated for all repeated fields.
102 : template <typename Element>
103 : class RepeatedField {
104 : public:
105 : RepeatedField();
106 : RepeatedField(const RepeatedField& other);
107 : template <typename Iter>
108 : RepeatedField(Iter begin, const Iter& end);
109 : ~RepeatedField();
110 :
111 : RepeatedField& operator=(const RepeatedField& other);
112 :
113 : bool empty() const;
114 : int size() const;
115 :
116 : const Element& Get(int index) const;
117 : Element* Mutable(int index);
118 : void Set(int index, const Element& value);
119 : void Add(const Element& value);
120 : Element* Add();
121 : // Remove the last element in the array.
122 : void RemoveLast();
123 :
124 : // Extract elements with indices in "[start .. start+num-1]".
125 : // Copy them into "elements[0 .. num-1]" if "elements" is not NULL.
126 : // Caution: implementation also moves elements with indices [start+num ..].
127 : // Calling this routine inside a loop can cause quadratic behavior.
128 : void ExtractSubrange(int start, int num, Element* elements);
129 :
130 : void Clear();
131 : void MergeFrom(const RepeatedField& other);
132 : void CopyFrom(const RepeatedField& other);
133 :
134 : // Reserve space to expand the field to at least the given size. If the
135 : // array is grown, it will always be at least doubled in size.
136 : void Reserve(int new_size);
137 :
138 : // Resize the RepeatedField to a new, smaller size. This is O(1).
139 : void Truncate(int new_size);
140 :
141 : void AddAlreadyReserved(const Element& value);
142 : Element* AddAlreadyReserved();
143 : int Capacity() const;
144 :
145 : // Like STL resize. Uses value to fill appended elements.
146 : // Like Truncate() if new_size <= size(), otherwise this is
147 : // O(new_size - size()).
148 : void Resize(int new_size, const Element& value);
149 :
150 : // Gets the underlying array. This pointer is possibly invalidated by
151 : // any add or remove operation.
152 : Element* mutable_data();
153 : const Element* data() const;
154 :
155 : // Swap entire contents with "other".
156 : void Swap(RepeatedField* other);
157 :
158 : // Swap two elements.
159 : void SwapElements(int index1, int index2);
160 :
161 : // STL-like iterator support
162 : typedef Element* iterator;
163 : typedef const Element* const_iterator;
164 : typedef Element value_type;
165 : typedef value_type& reference;
166 : typedef const value_type& const_reference;
167 : typedef value_type* pointer;
168 : typedef const value_type* const_pointer;
169 : typedef int size_type;
170 : typedef ptrdiff_t difference_type;
171 :
172 : iterator begin();
173 : const_iterator begin() const;
174 : iterator end();
175 : const_iterator end() const;
176 :
177 : // Reverse iterator support
178 : typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
179 : typedef std::reverse_iterator<iterator> reverse_iterator;
180 : reverse_iterator rbegin() {
181 : return reverse_iterator(end());
182 : }
183 : const_reverse_iterator rbegin() const {
184 : return const_reverse_iterator(end());
185 : }
186 : reverse_iterator rend() {
187 : return reverse_iterator(begin());
188 : }
189 : const_reverse_iterator rend() const {
190 : return const_reverse_iterator(begin());
191 : }
192 :
193 : // Returns the number of bytes used by the repeated field, excluding
194 : // sizeof(*this)
195 : int SpaceUsedExcludingSelf() const;
196 :
197 : private:
198 : static const int kInitialSize = 0;
199 :
200 : Element* elements_;
201 : int current_size_;
202 : int total_size_;
203 :
204 : // Move the contents of |from| into |to|, possibly clobbering |from| in the
205 : // process. For primitive types this is just a memcpy(), but it could be
206 : // specialized for non-primitive types to, say, swap each element instead.
207 : void MoveArray(Element to[], Element from[], int size);
208 :
209 : // Copy the elements of |from| into |to|.
210 : void CopyArray(Element to[], const Element from[], int size);
211 : };
212 :
213 : namespace internal {
214 : template <typename It> class RepeatedPtrIterator;
215 : template <typename It, typename VoidPtr> class RepeatedPtrOverPtrsIterator;
216 : } // namespace internal
217 :
218 : namespace internal {
219 :
220 : // This is a helper template to copy an array of elements effeciently when they
221 : // have a trivial copy constructor, and correctly otherwise. This really
222 : // shouldn't be necessary, but our compiler doesn't optimize std::copy very
223 : // effectively.
224 : template <typename Element,
225 : bool HasTrivialCopy = has_trivial_copy<Element>::value>
226 : struct ElementCopier {
227 : void operator()(Element to[], const Element from[], int array_size);
228 : };
229 :
230 : } // namespace internal
231 :
232 : namespace internal {
233 :
234 : // This is the common base class for RepeatedPtrFields. It deals only in void*
235 : // pointers. Users should not use this interface directly.
236 : //
237 : // The methods of this interface correspond to the methods of RepeatedPtrField,
238 : // but may have a template argument called TypeHandler. Its signature is:
239 : // class TypeHandler {
240 : // public:
241 : // typedef MyType Type;
242 : // static Type* New();
243 : // static void Delete(Type*);
244 : // static void Clear(Type*);
245 : // static void Merge(const Type& from, Type* to);
246 : //
247 : // // Only needs to be implemented if SpaceUsedExcludingSelf() is called.
248 : // static int SpaceUsed(const Type&);
249 : // };
250 : class LIBPROTOBUF_EXPORT RepeatedPtrFieldBase {
251 : protected:
252 : // The reflection implementation needs to call protected methods directly,
253 : // reinterpreting pointers as being to Message instead of a specific Message
254 : // subclass.
255 : friend class GeneratedMessageReflection;
256 :
257 : // ExtensionSet stores repeated message extensions as
258 : // RepeatedPtrField<MessageLite>, but non-lite ExtensionSets need to
259 : // implement SpaceUsed(), and thus need to call SpaceUsedExcludingSelf()
260 : // reinterpreting MessageLite as Message. ExtensionSet also needs to make
261 : // use of AddFromCleared(), which is not part of the public interface.
262 : friend class ExtensionSet;
263 :
264 : // To parse directly into a proto2 generated class, the upb class GMR_Handlers
265 : // needs to be able to modify a RepeatedPtrFieldBase directly.
266 : friend class LIBPROTOBUF_EXPORT upb::google_opensource::GMR_Handlers;
267 :
268 : RepeatedPtrFieldBase();
269 :
270 : // Must be called from destructor.
271 : template <typename TypeHandler>
272 : void Destroy();
273 :
274 : bool empty() const;
275 : int size() const;
276 :
277 : template <typename TypeHandler>
278 : const typename TypeHandler::Type& Get(int index) const;
279 : template <typename TypeHandler>
280 : typename TypeHandler::Type* Mutable(int index);
281 : template <typename TypeHandler>
282 : typename TypeHandler::Type* Add();
283 : template <typename TypeHandler>
284 : void RemoveLast();
285 : template <typename TypeHandler>
286 : void Clear();
287 : template <typename TypeHandler>
288 : void MergeFrom(const RepeatedPtrFieldBase& other);
289 : template <typename TypeHandler>
290 : void CopyFrom(const RepeatedPtrFieldBase& other);
291 :
292 : void CloseGap(int start, int num) {
293 : // Close up a gap of "num" elements starting at offset "start".
294 : for (int i = start + num; i < allocated_size_; ++i)
295 : elements_[i - num] = elements_[i];
296 : current_size_ -= num;
297 : allocated_size_ -= num;
298 : }
299 :
300 : void Reserve(int new_size);
301 :
302 : int Capacity() const;
303 :
304 : // Used for constructing iterators.
305 : void* const* raw_data() const;
306 : void** raw_mutable_data() const;
307 :
308 : template <typename TypeHandler>
309 : typename TypeHandler::Type** mutable_data();
310 : template <typename TypeHandler>
311 : const typename TypeHandler::Type* const* data() const;
312 :
313 : void Swap(RepeatedPtrFieldBase* other);
314 :
315 : void SwapElements(int index1, int index2);
316 :
317 : template <typename TypeHandler>
318 : int SpaceUsedExcludingSelf() const;
319 :
320 :
321 : // Advanced memory management --------------------------------------
322 :
323 : // Like Add(), but if there are no cleared objects to use, returns NULL.
324 : template <typename TypeHandler>
325 : typename TypeHandler::Type* AddFromCleared();
326 :
327 : template <typename TypeHandler>
328 : void AddAllocated(typename TypeHandler::Type* value);
329 : template <typename TypeHandler>
330 : typename TypeHandler::Type* ReleaseLast();
331 :
332 : int ClearedCount() const;
333 : template <typename TypeHandler>
334 : void AddCleared(typename TypeHandler::Type* value);
335 : template <typename TypeHandler>
336 : typename TypeHandler::Type* ReleaseCleared();
337 :
338 : private:
339 : static const int kInitialSize = 0;
340 :
341 : void** elements_;
342 : int current_size_;
343 : int allocated_size_;
344 : int total_size_;
345 :
346 : template <typename TypeHandler>
347 1236 : static inline typename TypeHandler::Type* cast(void* element) {
348 1236 : return reinterpret_cast<typename TypeHandler::Type*>(element);
349 : }
350 : template <typename TypeHandler>
351 : static inline const typename TypeHandler::Type* cast(const void* element) {
352 : return reinterpret_cast<const typename TypeHandler::Type*>(element);
353 : }
354 :
355 : GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RepeatedPtrFieldBase);
356 : };
357 :
358 : template <typename GenericType>
359 : class GenericTypeHandler {
360 : public:
361 : typedef GenericType Type;
362 1134 : static GenericType* New() { return new GenericType; }
363 567 : static void Delete(GenericType* value) { delete value; }
364 0 : static void Clear(GenericType* value) { value->Clear(); }
365 0 : static void Merge(const GenericType& from, GenericType* to) {
366 0 : to->MergeFrom(from);
367 0 : }
368 0 : static int SpaceUsed(const GenericType& value) { return value.SpaceUsed(); }
369 : static const Type& default_instance() { return Type::default_instance(); }
370 : };
371 :
372 : template <>
373 : inline void GenericTypeHandler<MessageLite>::Merge(
374 : const MessageLite& from, MessageLite* to) {
375 : to->CheckTypeAndMergeFrom(from);
376 : }
377 :
378 : template <>
379 : inline const MessageLite& GenericTypeHandler<MessageLite>::default_instance() {
380 : // Yes, the behavior of the code is undefined, but this function is only
381 : // called when we're already deep into the world of undefined, because the
382 : // caller called Get(index) out of bounds.
383 : MessageLite* null = NULL;
384 : return *null;
385 : }
386 :
387 : template <>
388 : inline const Message& GenericTypeHandler<Message>::default_instance() {
389 : // Yes, the behavior of the code is undefined, but this function is only
390 : // called when we're already deep into the world of undefined, because the
391 : // caller called Get(index) out of bounds.
392 : Message* null = NULL;
393 : return *null;
394 : }
395 :
396 :
397 : // HACK: If a class is declared as DLL-exported in MSVC, it insists on
398 : // generating copies of all its methods -- even inline ones -- to include
399 : // in the DLL. But SpaceUsed() calls StringSpaceUsedExcludingSelf() which
400 : // isn't in the lite library, therefore the lite library cannot link if
401 : // StringTypeHandler is exported. So, we factor out StringTypeHandlerBase,
402 : // export that, then make StringTypeHandler be a subclass which is NOT
403 : // exported.
404 : // TODO(kenton): There has to be a better way.
405 : class LIBPROTOBUF_EXPORT StringTypeHandlerBase {
406 : public:
407 : typedef string Type;
408 : static string* New();
409 : static void Delete(string* value);
410 0 : static void Clear(string* value) { value->clear(); }
411 0 : static void Merge(const string& from, string* to) { *to = from; }
412 : static const Type& default_instance() {
413 : return ::google::protobuf::internal::GetEmptyString();
414 : }
415 : };
416 :
417 : class StringTypeHandler : public StringTypeHandlerBase {
418 : public:
419 0 : static int SpaceUsed(const string& value) {
420 0 : return sizeof(value) + StringSpaceUsedExcludingSelf(value);
421 : }
422 : };
423 :
424 :
425 : } // namespace internal
426 :
427 : // RepeatedPtrField is like RepeatedField, but used for repeated strings or
428 : // Messages.
429 : template <typename Element>
430 : class RepeatedPtrField : public internal::RepeatedPtrFieldBase {
431 : public:
432 : RepeatedPtrField();
433 : RepeatedPtrField(const RepeatedPtrField& other);
434 : template <typename Iter>
435 : RepeatedPtrField(Iter begin, const Iter& end);
436 : ~RepeatedPtrField();
437 :
438 : RepeatedPtrField& operator=(const RepeatedPtrField& other);
439 :
440 : bool empty() const;
441 : int size() const;
442 :
443 : const Element& Get(int index) const;
444 : Element* Mutable(int index);
445 : Element* Add();
446 :
447 : // Remove the last element in the array.
448 : // Ownership of the element is retained by the array.
449 : void RemoveLast();
450 :
451 : // Delete elements with indices in the range [start .. start+num-1].
452 : // Caution: implementation moves all elements with indices [start+num .. ].
453 : // Calling this routine inside a loop can cause quadratic behavior.
454 : void DeleteSubrange(int start, int num);
455 :
456 : void Clear();
457 : void MergeFrom(const RepeatedPtrField& other);
458 : void CopyFrom(const RepeatedPtrField& other);
459 :
460 : // Reserve space to expand the field to at least the given size. This only
461 : // resizes the pointer array; it doesn't allocate any objects. If the
462 : // array is grown, it will always be at least doubled in size.
463 : void Reserve(int new_size);
464 :
465 : int Capacity() const;
466 :
467 : // Gets the underlying array. This pointer is possibly invalidated by
468 : // any add or remove operation.
469 : Element** mutable_data();
470 : const Element* const* data() const;
471 :
472 : // Swap entire contents with "other".
473 : void Swap(RepeatedPtrField* other);
474 :
475 : // Swap two elements.
476 : void SwapElements(int index1, int index2);
477 :
478 : // STL-like iterator support
479 : typedef internal::RepeatedPtrIterator<Element> iterator;
480 : typedef internal::RepeatedPtrIterator<const Element> const_iterator;
481 : typedef Element value_type;
482 : typedef value_type& reference;
483 : typedef const value_type& const_reference;
484 : typedef value_type* pointer;
485 : typedef const value_type* const_pointer;
486 : typedef int size_type;
487 : typedef ptrdiff_t difference_type;
488 :
489 : iterator begin();
490 : const_iterator begin() const;
491 : iterator end();
492 : const_iterator end() const;
493 :
494 : // Reverse iterator support
495 : typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
496 : typedef std::reverse_iterator<iterator> reverse_iterator;
497 : reverse_iterator rbegin() {
498 : return reverse_iterator(end());
499 : }
500 : const_reverse_iterator rbegin() const {
501 : return const_reverse_iterator(end());
502 : }
503 : reverse_iterator rend() {
504 : return reverse_iterator(begin());
505 : }
506 : const_reverse_iterator rend() const {
507 : return const_reverse_iterator(begin());
508 : }
509 :
510 : // Custom STL-like iterator that iterates over and returns the underlying
511 : // pointers to Element rather than Element itself.
512 : typedef internal::RepeatedPtrOverPtrsIterator<Element, void*>
513 : pointer_iterator;
514 : typedef internal::RepeatedPtrOverPtrsIterator<const Element, const void*>
515 : const_pointer_iterator;
516 : pointer_iterator pointer_begin();
517 : const_pointer_iterator pointer_begin() const;
518 : pointer_iterator pointer_end();
519 : const_pointer_iterator pointer_end() const;
520 :
521 : // Returns (an estimate of) the number of bytes used by the repeated field,
522 : // excluding sizeof(*this).
523 : int SpaceUsedExcludingSelf() const;
524 :
525 : // Advanced memory management --------------------------------------
526 : // When hardcore memory management becomes necessary -- as it sometimes
527 : // does here at Google -- the following methods may be useful.
528 :
529 : // Add an already-allocated object, passing ownership to the
530 : // RepeatedPtrField.
531 : void AddAllocated(Element* value);
532 : // Remove the last element and return it, passing ownership to the caller.
533 : // Requires: size() > 0
534 : Element* ReleaseLast();
535 :
536 : // Extract elements with indices in the range "[start .. start+num-1]".
537 : // The caller assumes ownership of the extracted elements and is responsible
538 : // for deleting them when they are no longer needed.
539 : // If "elements" is non-NULL, then pointers to the extracted elements
540 : // are stored in "elements[0 .. num-1]" for the convenience of the caller.
541 : // If "elements" is NULL, then the caller must use some other mechanism
542 : // to perform any further operations (like deletion) on these elements.
543 : // Caution: implementation also moves elements with indices [start+num ..].
544 : // Calling this routine inside a loop can cause quadratic behavior.
545 : void ExtractSubrange(int start, int num, Element** elements);
546 :
547 : // When elements are removed by calls to RemoveLast() or Clear(), they
548 : // are not actually freed. Instead, they are cleared and kept so that
549 : // they can be reused later. This can save lots of CPU time when
550 : // repeatedly reusing a protocol message for similar purposes.
551 : //
552 : // Hardcore programs may choose to manipulate these cleared objects
553 : // to better optimize memory management using the following routines.
554 :
555 : // Get the number of cleared objects that are currently being kept
556 : // around for reuse.
557 : int ClearedCount() const;
558 : // Add an element to the pool of cleared objects, passing ownership to
559 : // the RepeatedPtrField. The element must be cleared prior to calling
560 : // this method.
561 : void AddCleared(Element* value);
562 : // Remove a single element from the cleared pool and return it, passing
563 : // ownership to the caller. The element is guaranteed to be cleared.
564 : // Requires: ClearedCount() > 0
565 : Element* ReleaseCleared();
566 :
567 : protected:
568 : // Note: RepeatedPtrField SHOULD NOT be subclassed by users. We only
569 : // subclass it in one place as a hack for compatibility with proto1. The
570 : // subclass needs to know about TypeHandler in order to call protected
571 : // methods on RepeatedPtrFieldBase.
572 : class TypeHandler;
573 :
574 : };
575 :
576 : // implementation ====================================================
577 :
578 : template <typename Element>
579 72 : inline RepeatedField<Element>::RepeatedField()
580 : : elements_(NULL),
581 : current_size_(0),
582 72 : total_size_(kInitialSize) {
583 72 : }
584 :
585 : template <typename Element>
586 0 : inline RepeatedField<Element>::RepeatedField(const RepeatedField& other)
587 : : elements_(NULL),
588 : current_size_(0),
589 0 : total_size_(kInitialSize) {
590 0 : CopyFrom(other);
591 0 : }
592 :
593 : template <typename Element>
594 : template <typename Iter>
595 : inline RepeatedField<Element>::RepeatedField(Iter begin, const Iter& end)
596 : : elements_(NULL),
597 : current_size_(0),
598 : total_size_(kInitialSize) {
599 : int reserve = internal::CalculateReserve(begin, end);
600 : if (reserve != -1) {
601 : Reserve(reserve);
602 : for (; begin != end; ++begin) {
603 : AddAlreadyReserved(*begin);
604 : }
605 : } else {
606 : for (; begin != end; ++begin) {
607 : Add(*begin);
608 : }
609 : }
610 : }
611 :
612 : template <typename Element>
613 12 : RepeatedField<Element>::~RepeatedField() {
614 12 : delete [] elements_;
615 12 : }
616 :
617 : template <typename Element>
618 : inline RepeatedField<Element>&
619 : RepeatedField<Element>::operator=(const RepeatedField& other) {
620 : if (this != &other)
621 : CopyFrom(other);
622 : return *this;
623 : }
624 :
625 : template <typename Element>
626 : inline bool RepeatedField<Element>::empty() const {
627 : return current_size_ == 0;
628 : }
629 :
630 : template <typename Element>
631 0 : inline int RepeatedField<Element>::size() const {
632 0 : return current_size_;
633 : }
634 :
635 : template <typename Element>
636 0 : inline int RepeatedField<Element>::Capacity() const {
637 0 : return total_size_;
638 : }
639 :
640 : template<typename Element>
641 0 : inline void RepeatedField<Element>::AddAlreadyReserved(const Element& value) {
642 0 : GOOGLE_DCHECK_LT(size(), Capacity());
643 0 : elements_[current_size_++] = value;
644 0 : }
645 :
646 : template<typename Element>
647 : inline Element* RepeatedField<Element>::AddAlreadyReserved() {
648 : GOOGLE_DCHECK_LT(size(), Capacity());
649 : return &elements_[current_size_++];
650 : }
651 :
652 : template<typename Element>
653 0 : inline void RepeatedField<Element>::Resize(int new_size, const Element& value) {
654 0 : GOOGLE_DCHECK_GE(new_size, 0);
655 0 : if (new_size > size()) {
656 0 : Reserve(new_size);
657 0 : std::fill(&elements_[current_size_], &elements_[new_size], value);
658 : }
659 0 : current_size_ = new_size;
660 0 : }
661 :
662 : template <typename Element>
663 0 : inline const Element& RepeatedField<Element>::Get(int index) const {
664 0 : GOOGLE_DCHECK_GE(index, 0);
665 0 : GOOGLE_DCHECK_LT(index, size());
666 0 : return elements_[index];
667 : }
668 :
669 : template <typename Element>
670 : inline Element* RepeatedField<Element>::Mutable(int index) {
671 : GOOGLE_DCHECK_GE(index, 0);
672 : GOOGLE_DCHECK_LT(index, size());
673 : return elements_ + index;
674 : }
675 :
676 : template <typename Element>
677 0 : inline void RepeatedField<Element>::Set(int index, const Element& value) {
678 0 : GOOGLE_DCHECK_GE(index, 0);
679 0 : GOOGLE_DCHECK_LT(index, size());
680 0 : elements_[index] = value;
681 0 : }
682 :
683 : template <typename Element>
684 0 : inline void RepeatedField<Element>::Add(const Element& value) {
685 0 : if (current_size_ == total_size_) Reserve(total_size_ + 1);
686 0 : elements_[current_size_++] = value;
687 0 : }
688 :
689 : template <typename Element>
690 : inline Element* RepeatedField<Element>::Add() {
691 : if (current_size_ == total_size_) Reserve(total_size_ + 1);
692 : return &elements_[current_size_++];
693 : }
694 :
695 : template <typename Element>
696 0 : inline void RepeatedField<Element>::RemoveLast() {
697 0 : GOOGLE_DCHECK_GT(current_size_, 0);
698 0 : --current_size_;
699 0 : }
700 :
701 : template <typename Element>
702 : void RepeatedField<Element>::ExtractSubrange(
703 : int start, int num, Element* elements) {
704 : GOOGLE_DCHECK_GE(start, 0);
705 : GOOGLE_DCHECK_GE(num, 0);
706 : GOOGLE_DCHECK_LE(start + num, this->size());
707 :
708 : // Save the values of the removed elements if requested.
709 : if (elements != NULL) {
710 : for (int i = 0; i < num; ++i)
711 : elements[i] = this->Get(i + start);
712 : }
713 :
714 : // Slide remaining elements down to fill the gap.
715 : if (num > 0) {
716 : for (int i = start + num; i < this->size(); ++i)
717 : this->Set(i - num, this->Get(i));
718 : this->Truncate(this->size() - num);
719 : }
720 : }
721 :
722 : template <typename Element>
723 12 : inline void RepeatedField<Element>::Clear() {
724 12 : current_size_ = 0;
725 12 : }
726 :
727 : template <typename Element>
728 0 : inline void RepeatedField<Element>::MergeFrom(const RepeatedField& other) {
729 0 : GOOGLE_CHECK_NE(&other, this);
730 0 : if (other.current_size_ != 0) {
731 0 : Reserve(current_size_ + other.current_size_);
732 0 : CopyArray(elements_ + current_size_, other.elements_, other.current_size_);
733 0 : current_size_ += other.current_size_;
734 : }
735 0 : }
736 :
737 : template <typename Element>
738 0 : inline void RepeatedField<Element>::CopyFrom(const RepeatedField& other) {
739 0 : if (&other == this) return;
740 0 : Clear();
741 0 : MergeFrom(other);
742 : }
743 :
744 : template <typename Element>
745 0 : inline Element* RepeatedField<Element>::mutable_data() {
746 0 : return elements_;
747 : }
748 :
749 : template <typename Element>
750 0 : inline const Element* RepeatedField<Element>::data() const {
751 0 : return elements_;
752 : }
753 :
754 :
755 : template <typename Element>
756 0 : void RepeatedField<Element>::Swap(RepeatedField* other) {
757 0 : if (this == other) return;
758 0 : Element* swap_elements = elements_;
759 0 : int swap_current_size = current_size_;
760 0 : int swap_total_size = total_size_;
761 :
762 0 : elements_ = other->elements_;
763 0 : current_size_ = other->current_size_;
764 0 : total_size_ = other->total_size_;
765 :
766 0 : other->elements_ = swap_elements;
767 0 : other->current_size_ = swap_current_size;
768 0 : other->total_size_ = swap_total_size;
769 : }
770 :
771 : template <typename Element>
772 0 : void RepeatedField<Element>::SwapElements(int index1, int index2) {
773 : using std::swap; // enable ADL with fallback
774 0 : swap(elements_[index1], elements_[index2]);
775 0 : }
776 :
777 : template <typename Element>
778 : inline typename RepeatedField<Element>::iterator
779 : RepeatedField<Element>::begin() {
780 : return elements_;
781 : }
782 : template <typename Element>
783 : inline typename RepeatedField<Element>::const_iterator
784 0 : RepeatedField<Element>::begin() const {
785 0 : return elements_;
786 : }
787 : template <typename Element>
788 : inline typename RepeatedField<Element>::iterator
789 : RepeatedField<Element>::end() {
790 : return elements_ + current_size_;
791 : }
792 : template <typename Element>
793 : inline typename RepeatedField<Element>::const_iterator
794 0 : RepeatedField<Element>::end() const {
795 0 : return elements_ + current_size_;
796 : }
797 :
798 : template <typename Element>
799 0 : inline int RepeatedField<Element>::SpaceUsedExcludingSelf() const {
800 0 : return (elements_ != NULL) ? total_size_ * sizeof(elements_[0]) : 0;
801 : }
802 :
803 : // Avoid inlining of Reserve(): new, copy, and delete[] lead to a significant
804 : // amount of code bloat.
805 : template <typename Element>
806 0 : void RepeatedField<Element>::Reserve(int new_size) {
807 0 : if (total_size_ >= new_size) return;
808 :
809 0 : Element* old_elements = elements_;
810 0 : total_size_ = max(google::protobuf::internal::kMinRepeatedFieldAllocationSize,
811 0 : max(total_size_ * 2, new_size));
812 0 : elements_ = new Element[total_size_];
813 0 : if (old_elements != NULL) {
814 0 : MoveArray(elements_, old_elements, current_size_);
815 0 : delete [] old_elements;
816 : }
817 : }
818 :
819 : template <typename Element>
820 0 : inline void RepeatedField<Element>::Truncate(int new_size) {
821 0 : GOOGLE_DCHECK_LE(new_size, current_size_);
822 0 : current_size_ = new_size;
823 0 : }
824 :
825 : template <typename Element>
826 0 : inline void RepeatedField<Element>::MoveArray(
827 : Element to[], Element from[], int array_size) {
828 0 : CopyArray(to, from, array_size);
829 0 : }
830 :
831 : template <typename Element>
832 0 : inline void RepeatedField<Element>::CopyArray(
833 : Element to[], const Element from[], int array_size) {
834 0 : internal::ElementCopier<Element>()(to, from, array_size);
835 0 : }
836 :
837 : namespace internal {
838 :
839 : template <typename Element, bool HasTrivialCopy>
840 : void ElementCopier<Element, HasTrivialCopy>::operator()(
841 : Element to[], const Element from[], int array_size) {
842 : std::copy(from, from + array_size, to);
843 : }
844 :
845 : template <typename Element>
846 : struct ElementCopier<Element, true> {
847 0 : void operator()(Element to[], const Element from[], int array_size) {
848 0 : memcpy(to, from, array_size * sizeof(Element));
849 0 : }
850 : };
851 :
852 : } // namespace internal
853 :
854 :
855 : // -------------------------------------------------------------------
856 :
857 : namespace internal {
858 :
859 642 : inline RepeatedPtrFieldBase::RepeatedPtrFieldBase()
860 : : elements_(NULL),
861 : current_size_(0),
862 : allocated_size_(0),
863 642 : total_size_(kInitialSize) {
864 642 : }
865 :
866 : template <typename TypeHandler>
867 519 : void RepeatedPtrFieldBase::Destroy() {
868 1086 : for (int i = 0; i < allocated_size_; i++) {
869 567 : TypeHandler::Delete(cast<TypeHandler>(elements_[i]));
870 : }
871 519 : delete [] elements_;
872 519 : }
873 :
874 : inline bool RepeatedPtrFieldBase::empty() const {
875 : return current_size_ == 0;
876 : }
877 :
878 1284 : inline int RepeatedPtrFieldBase::size() const {
879 1284 : return current_size_;
880 : }
881 :
882 : template <typename TypeHandler>
883 : inline const typename TypeHandler::Type&
884 669 : RepeatedPtrFieldBase::Get(int index) const {
885 669 : GOOGLE_DCHECK_GE(index, 0);
886 669 : GOOGLE_DCHECK_LT(index, size());
887 669 : return *cast<TypeHandler>(elements_[index]);
888 : }
889 :
890 :
891 : template <typename TypeHandler>
892 : inline typename TypeHandler::Type*
893 0 : RepeatedPtrFieldBase::Mutable(int index) {
894 0 : GOOGLE_DCHECK_GE(index, 0);
895 0 : GOOGLE_DCHECK_LT(index, size());
896 0 : return cast<TypeHandler>(elements_[index]);
897 : }
898 :
899 : template <typename TypeHandler>
900 567 : inline typename TypeHandler::Type* RepeatedPtrFieldBase::Add() {
901 567 : if (current_size_ < allocated_size_) {
902 0 : return cast<TypeHandler>(elements_[current_size_++]);
903 : }
904 567 : if (allocated_size_ == total_size_) Reserve(total_size_ + 1);
905 567 : typename TypeHandler::Type* result = TypeHandler::New();
906 567 : ++allocated_size_;
907 567 : elements_[current_size_++] = result;
908 567 : return result;
909 : }
910 :
911 : template <typename TypeHandler>
912 0 : inline void RepeatedPtrFieldBase::RemoveLast() {
913 0 : GOOGLE_DCHECK_GT(current_size_, 0);
914 0 : TypeHandler::Clear(cast<TypeHandler>(elements_[--current_size_]));
915 0 : }
916 :
917 : template <typename TypeHandler>
918 30 : void RepeatedPtrFieldBase::Clear() {
919 30 : for (int i = 0; i < current_size_; i++) {
920 0 : TypeHandler::Clear(cast<TypeHandler>(elements_[i]));
921 : }
922 30 : current_size_ = 0;
923 30 : }
924 :
925 : template <typename TypeHandler>
926 0 : inline void RepeatedPtrFieldBase::MergeFrom(const RepeatedPtrFieldBase& other) {
927 0 : GOOGLE_CHECK_NE(&other, this);
928 0 : Reserve(current_size_ + other.current_size_);
929 0 : for (int i = 0; i < other.current_size_; i++) {
930 0 : TypeHandler::Merge(other.template Get<TypeHandler>(i), Add<TypeHandler>());
931 : }
932 0 : }
933 :
934 : template <typename TypeHandler>
935 : inline void RepeatedPtrFieldBase::CopyFrom(const RepeatedPtrFieldBase& other) {
936 : if (&other == this) return;
937 : RepeatedPtrFieldBase::Clear<TypeHandler>();
938 : RepeatedPtrFieldBase::MergeFrom<TypeHandler>(other);
939 : }
940 :
941 : inline int RepeatedPtrFieldBase::Capacity() const {
942 : return total_size_;
943 : }
944 :
945 0 : inline void* const* RepeatedPtrFieldBase::raw_data() const {
946 0 : return elements_;
947 : }
948 :
949 : inline void** RepeatedPtrFieldBase::raw_mutable_data() const {
950 : return elements_;
951 : }
952 :
953 : template <typename TypeHandler>
954 : inline typename TypeHandler::Type** RepeatedPtrFieldBase::mutable_data() {
955 : // TODO(kenton): Breaks C++ aliasing rules. We should probably remove this
956 : // method entirely.
957 : return reinterpret_cast<typename TypeHandler::Type**>(elements_);
958 : }
959 :
960 : template <typename TypeHandler>
961 : inline const typename TypeHandler::Type* const*
962 : RepeatedPtrFieldBase::data() const {
963 : // TODO(kenton): Breaks C++ aliasing rules. We should probably remove this
964 : // method entirely.
965 : return reinterpret_cast<const typename TypeHandler::Type* const*>(elements_);
966 : }
967 :
968 0 : inline void RepeatedPtrFieldBase::SwapElements(int index1, int index2) {
969 : using std::swap; // enable ADL with fallback
970 0 : swap(elements_[index1], elements_[index2]);
971 0 : }
972 :
973 : template <typename TypeHandler>
974 0 : inline int RepeatedPtrFieldBase::SpaceUsedExcludingSelf() const {
975 : int allocated_bytes =
976 0 : (elements_ != NULL) ? total_size_ * sizeof(elements_[0]) : 0;
977 0 : for (int i = 0; i < allocated_size_; ++i) {
978 0 : allocated_bytes += TypeHandler::SpaceUsed(*cast<TypeHandler>(elements_[i]));
979 : }
980 0 : return allocated_bytes;
981 : }
982 :
983 : template <typename TypeHandler>
984 0 : inline typename TypeHandler::Type* RepeatedPtrFieldBase::AddFromCleared() {
985 0 : if (current_size_ < allocated_size_) {
986 0 : return cast<TypeHandler>(elements_[current_size_++]);
987 : } else {
988 0 : return NULL;
989 : }
990 : }
991 :
992 : template <typename TypeHandler>
993 0 : void RepeatedPtrFieldBase::AddAllocated(
994 : typename TypeHandler::Type* value) {
995 : // Make room for the new pointer.
996 0 : if (current_size_ == total_size_) {
997 : // The array is completely full with no cleared objects, so grow it.
998 0 : Reserve(total_size_ + 1);
999 0 : ++allocated_size_;
1000 0 : } else if (allocated_size_ == total_size_) {
1001 : // There is no more space in the pointer array because it contains some
1002 : // cleared objects awaiting reuse. We don't want to grow the array in this
1003 : // case because otherwise a loop calling AddAllocated() followed by Clear()
1004 : // would leak memory.
1005 0 : TypeHandler::Delete(cast<TypeHandler>(elements_[current_size_]));
1006 0 : } else if (current_size_ < allocated_size_) {
1007 : // We have some cleared objects. We don't care about their order, so we
1008 : // can just move the first one to the end to make space.
1009 0 : elements_[allocated_size_] = elements_[current_size_];
1010 0 : ++allocated_size_;
1011 : } else {
1012 : // There are no cleared objects.
1013 0 : ++allocated_size_;
1014 : }
1015 :
1016 0 : elements_[current_size_++] = value;
1017 0 : }
1018 :
1019 : template <typename TypeHandler>
1020 0 : inline typename TypeHandler::Type* RepeatedPtrFieldBase::ReleaseLast() {
1021 0 : GOOGLE_DCHECK_GT(current_size_, 0);
1022 : typename TypeHandler::Type* result =
1023 0 : cast<TypeHandler>(elements_[--current_size_]);
1024 0 : --allocated_size_;
1025 0 : if (current_size_ < allocated_size_) {
1026 : // There are cleared elements on the end; replace the removed element
1027 : // with the last allocated element.
1028 0 : elements_[current_size_] = elements_[allocated_size_];
1029 : }
1030 0 : return result;
1031 : }
1032 :
1033 : inline int RepeatedPtrFieldBase::ClearedCount() const {
1034 : return allocated_size_ - current_size_;
1035 : }
1036 :
1037 : template <typename TypeHandler>
1038 : inline void RepeatedPtrFieldBase::AddCleared(
1039 : typename TypeHandler::Type* value) {
1040 : if (allocated_size_ == total_size_) Reserve(total_size_ + 1);
1041 : elements_[allocated_size_++] = value;
1042 : }
1043 :
1044 : template <typename TypeHandler>
1045 : inline typename TypeHandler::Type* RepeatedPtrFieldBase::ReleaseCleared() {
1046 : GOOGLE_DCHECK_GT(allocated_size_, current_size_);
1047 : return cast<TypeHandler>(elements_[--allocated_size_]);
1048 : }
1049 :
1050 : } // namespace internal
1051 :
1052 : // -------------------------------------------------------------------
1053 :
1054 : template <typename Element>
1055 : class RepeatedPtrField<Element>::TypeHandler
1056 : : public internal::GenericTypeHandler<Element> {
1057 : };
1058 :
1059 : template <>
1060 : class RepeatedPtrField<string>::TypeHandler
1061 : : public internal::StringTypeHandler {
1062 : };
1063 :
1064 :
1065 : template <typename Element>
1066 642 : inline RepeatedPtrField<Element>::RepeatedPtrField() {}
1067 :
1068 : template <typename Element>
1069 : inline RepeatedPtrField<Element>::RepeatedPtrField(
1070 : const RepeatedPtrField& other)
1071 : : RepeatedPtrFieldBase() {
1072 : CopyFrom(other);
1073 : }
1074 :
1075 : template <typename Element>
1076 : template <typename Iter>
1077 : inline RepeatedPtrField<Element>::RepeatedPtrField(
1078 : Iter begin, const Iter& end) {
1079 : int reserve = internal::CalculateReserve(begin, end);
1080 : if (reserve != -1) {
1081 : Reserve(reserve);
1082 : }
1083 : for (; begin != end; ++begin) {
1084 : *Add() = *begin;
1085 : }
1086 : }
1087 :
1088 : template <typename Element>
1089 519 : RepeatedPtrField<Element>::~RepeatedPtrField() {
1090 519 : Destroy<TypeHandler>();
1091 519 : }
1092 :
1093 : template <typename Element>
1094 : inline RepeatedPtrField<Element>& RepeatedPtrField<Element>::operator=(
1095 : const RepeatedPtrField& other) {
1096 : if (this != &other)
1097 : CopyFrom(other);
1098 : return *this;
1099 : }
1100 :
1101 : template <typename Element>
1102 : inline bool RepeatedPtrField<Element>::empty() const {
1103 : return RepeatedPtrFieldBase::empty();
1104 : }
1105 :
1106 : template <typename Element>
1107 615 : inline int RepeatedPtrField<Element>::size() const {
1108 615 : return RepeatedPtrFieldBase::size();
1109 : }
1110 :
1111 : template <typename Element>
1112 669 : inline const Element& RepeatedPtrField<Element>::Get(int index) const {
1113 669 : return RepeatedPtrFieldBase::Get<TypeHandler>(index);
1114 : }
1115 :
1116 :
1117 : template <typename Element>
1118 0 : inline Element* RepeatedPtrField<Element>::Mutable(int index) {
1119 0 : return RepeatedPtrFieldBase::Mutable<TypeHandler>(index);
1120 : }
1121 :
1122 : template <typename Element>
1123 567 : inline Element* RepeatedPtrField<Element>::Add() {
1124 567 : return RepeatedPtrFieldBase::Add<TypeHandler>();
1125 : }
1126 :
1127 : template <typename Element>
1128 0 : inline void RepeatedPtrField<Element>::RemoveLast() {
1129 0 : RepeatedPtrFieldBase::RemoveLast<TypeHandler>();
1130 0 : }
1131 :
1132 : template <typename Element>
1133 : inline void RepeatedPtrField<Element>::DeleteSubrange(int start, int num) {
1134 : GOOGLE_DCHECK_GE(start, 0);
1135 : GOOGLE_DCHECK_GE(num, 0);
1136 : GOOGLE_DCHECK_LE(start + num, size());
1137 : for (int i = 0; i < num; ++i)
1138 : delete RepeatedPtrFieldBase::Mutable<TypeHandler>(start + i);
1139 : ExtractSubrange(start, num, NULL);
1140 : }
1141 :
1142 : template <typename Element>
1143 : inline void RepeatedPtrField<Element>::ExtractSubrange(
1144 : int start, int num, Element** elements) {
1145 : GOOGLE_DCHECK_GE(start, 0);
1146 : GOOGLE_DCHECK_GE(num, 0);
1147 : GOOGLE_DCHECK_LE(start + num, size());
1148 :
1149 : if (num > 0) {
1150 : // Save the values of the removed elements if requested.
1151 : if (elements != NULL) {
1152 : for (int i = 0; i < num; ++i)
1153 : elements[i] = RepeatedPtrFieldBase::Mutable<TypeHandler>(i + start);
1154 : }
1155 : CloseGap(start, num);
1156 : }
1157 : }
1158 :
1159 : template <typename Element>
1160 30 : inline void RepeatedPtrField<Element>::Clear() {
1161 30 : RepeatedPtrFieldBase::Clear<TypeHandler>();
1162 30 : }
1163 :
1164 : template <typename Element>
1165 0 : inline void RepeatedPtrField<Element>::MergeFrom(
1166 : const RepeatedPtrField& other) {
1167 0 : RepeatedPtrFieldBase::MergeFrom<TypeHandler>(other);
1168 0 : }
1169 :
1170 : template <typename Element>
1171 : inline void RepeatedPtrField<Element>::CopyFrom(
1172 : const RepeatedPtrField& other) {
1173 : RepeatedPtrFieldBase::CopyFrom<TypeHandler>(other);
1174 : }
1175 :
1176 : template <typename Element>
1177 : inline Element** RepeatedPtrField<Element>::mutable_data() {
1178 : return RepeatedPtrFieldBase::mutable_data<TypeHandler>();
1179 : }
1180 :
1181 : template <typename Element>
1182 : inline const Element* const* RepeatedPtrField<Element>::data() const {
1183 : return RepeatedPtrFieldBase::data<TypeHandler>();
1184 : }
1185 :
1186 : template <typename Element>
1187 0 : void RepeatedPtrField<Element>::Swap(RepeatedPtrField* other) {
1188 0 : RepeatedPtrFieldBase::Swap(other);
1189 0 : }
1190 :
1191 : template <typename Element>
1192 0 : void RepeatedPtrField<Element>::SwapElements(int index1, int index2) {
1193 0 : RepeatedPtrFieldBase::SwapElements(index1, index2);
1194 0 : }
1195 :
1196 : template <typename Element>
1197 0 : inline int RepeatedPtrField<Element>::SpaceUsedExcludingSelf() const {
1198 0 : return RepeatedPtrFieldBase::SpaceUsedExcludingSelf<TypeHandler>();
1199 : }
1200 :
1201 : template <typename Element>
1202 0 : inline void RepeatedPtrField<Element>::AddAllocated(Element* value) {
1203 0 : RepeatedPtrFieldBase::AddAllocated<TypeHandler>(value);
1204 0 : }
1205 :
1206 : template <typename Element>
1207 0 : inline Element* RepeatedPtrField<Element>::ReleaseLast() {
1208 0 : return RepeatedPtrFieldBase::ReleaseLast<TypeHandler>();
1209 : }
1210 :
1211 :
1212 : template <typename Element>
1213 : inline int RepeatedPtrField<Element>::ClearedCount() const {
1214 : return RepeatedPtrFieldBase::ClearedCount();
1215 : }
1216 :
1217 : template <typename Element>
1218 : inline void RepeatedPtrField<Element>::AddCleared(Element* value) {
1219 : return RepeatedPtrFieldBase::AddCleared<TypeHandler>(value);
1220 : }
1221 :
1222 : template <typename Element>
1223 : inline Element* RepeatedPtrField<Element>::ReleaseCleared() {
1224 : return RepeatedPtrFieldBase::ReleaseCleared<TypeHandler>();
1225 : }
1226 :
1227 : template <typename Element>
1228 : inline void RepeatedPtrField<Element>::Reserve(int new_size) {
1229 : return RepeatedPtrFieldBase::Reserve(new_size);
1230 : }
1231 :
1232 : template <typename Element>
1233 : inline int RepeatedPtrField<Element>::Capacity() const {
1234 : return RepeatedPtrFieldBase::Capacity();
1235 : }
1236 :
1237 : // -------------------------------------------------------------------
1238 :
1239 : namespace internal {
1240 :
1241 : // STL-like iterator implementation for RepeatedPtrField. You should not
1242 : // refer to this class directly; use RepeatedPtrField<T>::iterator instead.
1243 : //
1244 : // The iterator for RepeatedPtrField<T>, RepeatedPtrIterator<T>, is
1245 : // very similar to iterator_ptr<T**> in util/gtl/iterator_adaptors.h,
1246 : // but adds random-access operators and is modified to wrap a void** base
1247 : // iterator (since RepeatedPtrField stores its array as a void* array and
1248 : // casting void** to T** would violate C++ aliasing rules).
1249 : //
1250 : // This code based on net/proto/proto-array-internal.h by Jeffrey Yasskin
1251 : // (jyasskin@google.com).
1252 : template<typename Element>
1253 : class RepeatedPtrIterator
1254 : : public std::iterator<
1255 : std::random_access_iterator_tag, Element> {
1256 : public:
1257 : typedef RepeatedPtrIterator<Element> iterator;
1258 : typedef std::iterator<
1259 : std::random_access_iterator_tag, Element> superclass;
1260 :
1261 : // Shadow the value_type in std::iterator<> because const_iterator::value_type
1262 : // needs to be T, not const T.
1263 : typedef typename remove_const<Element>::type value_type;
1264 :
1265 : // Let the compiler know that these are type names, so we don't have to
1266 : // write "typename" in front of them everywhere.
1267 : typedef typename superclass::reference reference;
1268 : typedef typename superclass::pointer pointer;
1269 : typedef typename superclass::difference_type difference_type;
1270 :
1271 : RepeatedPtrIterator() : it_(NULL) {}
1272 0 : explicit RepeatedPtrIterator(void* const* it) : it_(it) {}
1273 :
1274 : // Allow "upcasting" from RepeatedPtrIterator<T**> to
1275 : // RepeatedPtrIterator<const T*const*>.
1276 : template<typename OtherElement>
1277 0 : RepeatedPtrIterator(const RepeatedPtrIterator<OtherElement>& other)
1278 0 : : it_(other.it_) {
1279 : // Force a compiler error if the other type is not convertible to ours.
1280 : if (false) {
1281 : implicit_cast<Element*, OtherElement*>(0);
1282 : }
1283 0 : }
1284 :
1285 : // dereferenceable
1286 0 : reference operator*() const { return *reinterpret_cast<Element*>(*it_); }
1287 : pointer operator->() const { return &(operator*()); }
1288 :
1289 : // {inc,dec}rementable
1290 0 : iterator& operator++() { ++it_; return *this; }
1291 : iterator operator++(int) { return iterator(it_++); }
1292 : iterator& operator--() { --it_; return *this; }
1293 : iterator operator--(int) { return iterator(it_--); }
1294 :
1295 : // equality_comparable
1296 : bool operator==(const iterator& x) const { return it_ == x.it_; }
1297 0 : bool operator!=(const iterator& x) const { return it_ != x.it_; }
1298 :
1299 : // less_than_comparable
1300 : bool operator<(const iterator& x) const { return it_ < x.it_; }
1301 : bool operator<=(const iterator& x) const { return it_ <= x.it_; }
1302 : bool operator>(const iterator& x) const { return it_ > x.it_; }
1303 : bool operator>=(const iterator& x) const { return it_ >= x.it_; }
1304 :
1305 : // addable, subtractable
1306 : iterator& operator+=(difference_type d) {
1307 : it_ += d;
1308 : return *this;
1309 : }
1310 : friend iterator operator+(iterator it, difference_type d) {
1311 : it += d;
1312 : return it;
1313 : }
1314 : friend iterator operator+(difference_type d, iterator it) {
1315 : it += d;
1316 : return it;
1317 : }
1318 : iterator& operator-=(difference_type d) {
1319 : it_ -= d;
1320 : return *this;
1321 : }
1322 : friend iterator operator-(iterator it, difference_type d) {
1323 : it -= d;
1324 : return it;
1325 : }
1326 :
1327 : // indexable
1328 : reference operator[](difference_type d) const { return *(*this + d); }
1329 :
1330 : // random access iterator
1331 : difference_type operator-(const iterator& x) const { return it_ - x.it_; }
1332 :
1333 : private:
1334 : template<typename OtherElement>
1335 : friend class RepeatedPtrIterator;
1336 :
1337 : // The internal iterator.
1338 : void* const* it_;
1339 : };
1340 :
1341 : // Provide an iterator that operates on pointers to the underlying objects
1342 : // rather than the objects themselves as RepeatedPtrIterator does.
1343 : // Consider using this when working with stl algorithms that change
1344 : // the array.
1345 : // The VoidPtr template parameter holds the type-agnostic pointer value
1346 : // referenced by the iterator. It should either be "void *" for a mutable
1347 : // iterator, or "const void *" for a constant iterator.
1348 : template<typename Element, typename VoidPtr>
1349 : class RepeatedPtrOverPtrsIterator
1350 : : public std::iterator<std::random_access_iterator_tag, Element*> {
1351 : public:
1352 : typedef RepeatedPtrOverPtrsIterator<Element, VoidPtr> iterator;
1353 : typedef std::iterator<
1354 : std::random_access_iterator_tag, Element*> superclass;
1355 :
1356 : // Shadow the value_type in std::iterator<> because const_iterator::value_type
1357 : // needs to be T, not const T.
1358 : typedef typename remove_const<Element*>::type value_type;
1359 :
1360 : // Let the compiler know that these are type names, so we don't have to
1361 : // write "typename" in front of them everywhere.
1362 : typedef typename superclass::reference reference;
1363 : typedef typename superclass::pointer pointer;
1364 : typedef typename superclass::difference_type difference_type;
1365 :
1366 : RepeatedPtrOverPtrsIterator() : it_(NULL) {}
1367 : explicit RepeatedPtrOverPtrsIterator(VoidPtr* it) : it_(it) {}
1368 :
1369 : // dereferenceable
1370 : reference operator*() const { return *reinterpret_cast<Element**>(it_); }
1371 : pointer operator->() const { return &(operator*()); }
1372 :
1373 : // {inc,dec}rementable
1374 : iterator& operator++() { ++it_; return *this; }
1375 : iterator operator++(int) { return iterator(it_++); }
1376 : iterator& operator--() { --it_; return *this; }
1377 : iterator operator--(int) { return iterator(it_--); }
1378 :
1379 : // equality_comparable
1380 : bool operator==(const iterator& x) const { return it_ == x.it_; }
1381 : bool operator!=(const iterator& x) const { return it_ != x.it_; }
1382 :
1383 : // less_than_comparable
1384 : bool operator<(const iterator& x) const { return it_ < x.it_; }
1385 : bool operator<=(const iterator& x) const { return it_ <= x.it_; }
1386 : bool operator>(const iterator& x) const { return it_ > x.it_; }
1387 : bool operator>=(const iterator& x) const { return it_ >= x.it_; }
1388 :
1389 : // addable, subtractable
1390 : iterator& operator+=(difference_type d) {
1391 : it_ += d;
1392 : return *this;
1393 : }
1394 : friend iterator operator+(iterator it, difference_type d) {
1395 : it += d;
1396 : return it;
1397 : }
1398 : friend iterator operator+(difference_type d, iterator it) {
1399 : it += d;
1400 : return it;
1401 : }
1402 : iterator& operator-=(difference_type d) {
1403 : it_ -= d;
1404 : return *this;
1405 : }
1406 : friend iterator operator-(iterator it, difference_type d) {
1407 : it -= d;
1408 : return it;
1409 : }
1410 :
1411 : // indexable
1412 : reference operator[](difference_type d) const { return *(*this + d); }
1413 :
1414 : // random access iterator
1415 : difference_type operator-(const iterator& x) const { return it_ - x.it_; }
1416 :
1417 : private:
1418 : template<typename OtherElement>
1419 : friend class RepeatedPtrIterator;
1420 :
1421 : // The internal iterator.
1422 : VoidPtr* it_;
1423 : };
1424 :
1425 : } // namespace internal
1426 :
1427 : template <typename Element>
1428 : inline typename RepeatedPtrField<Element>::iterator
1429 : RepeatedPtrField<Element>::begin() {
1430 : return iterator(raw_data());
1431 : }
1432 : template <typename Element>
1433 : inline typename RepeatedPtrField<Element>::const_iterator
1434 0 : RepeatedPtrField<Element>::begin() const {
1435 0 : return iterator(raw_data());
1436 : }
1437 : template <typename Element>
1438 : inline typename RepeatedPtrField<Element>::iterator
1439 : RepeatedPtrField<Element>::end() {
1440 : return iterator(raw_data() + size());
1441 : }
1442 : template <typename Element>
1443 : inline typename RepeatedPtrField<Element>::const_iterator
1444 0 : RepeatedPtrField<Element>::end() const {
1445 0 : return iterator(raw_data() + size());
1446 : }
1447 :
1448 : template <typename Element>
1449 : inline typename RepeatedPtrField<Element>::pointer_iterator
1450 : RepeatedPtrField<Element>::pointer_begin() {
1451 : return pointer_iterator(raw_mutable_data());
1452 : }
1453 : template <typename Element>
1454 : inline typename RepeatedPtrField<Element>::const_pointer_iterator
1455 : RepeatedPtrField<Element>::pointer_begin() const {
1456 : return const_pointer_iterator(const_cast<const void**>(raw_mutable_data()));
1457 : }
1458 : template <typename Element>
1459 : inline typename RepeatedPtrField<Element>::pointer_iterator
1460 : RepeatedPtrField<Element>::pointer_end() {
1461 : return pointer_iterator(raw_mutable_data() + size());
1462 : }
1463 : template <typename Element>
1464 : inline typename RepeatedPtrField<Element>::const_pointer_iterator
1465 : RepeatedPtrField<Element>::pointer_end() const {
1466 : return const_pointer_iterator(
1467 : const_cast<const void**>(raw_mutable_data() + size()));
1468 : }
1469 :
1470 :
1471 : // Iterators and helper functions that follow the spirit of the STL
1472 : // std::back_insert_iterator and std::back_inserter but are tailor-made
1473 : // for RepeatedField and RepatedPtrField. Typical usage would be:
1474 : //
1475 : // std::copy(some_sequence.begin(), some_sequence.end(),
1476 : // google::protobuf::RepeatedFieldBackInserter(proto.mutable_sequence()));
1477 : //
1478 : // Ported by johannes from util/gtl/proto-array-iterators.h
1479 :
1480 : namespace internal {
1481 : // A back inserter for RepeatedField objects.
1482 : template<typename T> class RepeatedFieldBackInsertIterator
1483 : : public std::iterator<std::output_iterator_tag, T> {
1484 : public:
1485 : explicit RepeatedFieldBackInsertIterator(
1486 : RepeatedField<T>* const mutable_field)
1487 : : field_(mutable_field) {
1488 : }
1489 : RepeatedFieldBackInsertIterator<T>& operator=(const T& value) {
1490 : field_->Add(value);
1491 : return *this;
1492 : }
1493 : RepeatedFieldBackInsertIterator<T>& operator*() {
1494 : return *this;
1495 : }
1496 : RepeatedFieldBackInsertIterator<T>& operator++() {
1497 : return *this;
1498 : }
1499 : RepeatedFieldBackInsertIterator<T>& operator++(int /* unused */) {
1500 : return *this;
1501 : }
1502 :
1503 : private:
1504 : RepeatedField<T>* field_;
1505 : };
1506 :
1507 : // A back inserter for RepeatedPtrField objects.
1508 : template<typename T> class RepeatedPtrFieldBackInsertIterator
1509 : : public std::iterator<std::output_iterator_tag, T> {
1510 : public:
1511 : RepeatedPtrFieldBackInsertIterator(
1512 : RepeatedPtrField<T>* const mutable_field)
1513 : : field_(mutable_field) {
1514 : }
1515 : RepeatedPtrFieldBackInsertIterator<T>& operator=(const T& value) {
1516 : *field_->Add() = value;
1517 : return *this;
1518 : }
1519 : RepeatedPtrFieldBackInsertIterator<T>& operator=(
1520 : const T* const ptr_to_value) {
1521 : *field_->Add() = *ptr_to_value;
1522 : return *this;
1523 : }
1524 : RepeatedPtrFieldBackInsertIterator<T>& operator*() {
1525 : return *this;
1526 : }
1527 : RepeatedPtrFieldBackInsertIterator<T>& operator++() {
1528 : return *this;
1529 : }
1530 : RepeatedPtrFieldBackInsertIterator<T>& operator++(int /* unused */) {
1531 : return *this;
1532 : }
1533 :
1534 : private:
1535 : RepeatedPtrField<T>* field_;
1536 : };
1537 :
1538 : // A back inserter for RepeatedPtrFields that inserts by transfering ownership
1539 : // of a pointer.
1540 : template<typename T> class AllocatedRepeatedPtrFieldBackInsertIterator
1541 : : public std::iterator<std::output_iterator_tag, T> {
1542 : public:
1543 : explicit AllocatedRepeatedPtrFieldBackInsertIterator(
1544 : RepeatedPtrField<T>* const mutable_field)
1545 : : field_(mutable_field) {
1546 : }
1547 : AllocatedRepeatedPtrFieldBackInsertIterator<T>& operator=(
1548 : T* const ptr_to_value) {
1549 : field_->AddAllocated(ptr_to_value);
1550 : return *this;
1551 : }
1552 : AllocatedRepeatedPtrFieldBackInsertIterator<T>& operator*() {
1553 : return *this;
1554 : }
1555 : AllocatedRepeatedPtrFieldBackInsertIterator<T>& operator++() {
1556 : return *this;
1557 : }
1558 : AllocatedRepeatedPtrFieldBackInsertIterator<T>& operator++(
1559 : int /* unused */) {
1560 : return *this;
1561 : }
1562 :
1563 : private:
1564 : RepeatedPtrField<T>* field_;
1565 : };
1566 : } // namespace internal
1567 :
1568 : // Provides a back insert iterator for RepeatedField instances,
1569 : // similar to std::back_inserter().
1570 : template<typename T> internal::RepeatedFieldBackInsertIterator<T>
1571 : RepeatedFieldBackInserter(RepeatedField<T>* const mutable_field) {
1572 : return internal::RepeatedFieldBackInsertIterator<T>(mutable_field);
1573 : }
1574 :
1575 : // Provides a back insert iterator for RepeatedPtrField instances,
1576 : // similar to std::back_inserter().
1577 : template<typename T> internal::RepeatedPtrFieldBackInsertIterator<T>
1578 : RepeatedPtrFieldBackInserter(RepeatedPtrField<T>* const mutable_field) {
1579 : return internal::RepeatedPtrFieldBackInsertIterator<T>(mutable_field);
1580 : }
1581 :
1582 : // Special back insert iterator for RepeatedPtrField instances, just in
1583 : // case someone wants to write generic template code that can access both
1584 : // RepeatedFields and RepeatedPtrFields using a common name.
1585 : template<typename T> internal::RepeatedPtrFieldBackInsertIterator<T>
1586 : RepeatedFieldBackInserter(RepeatedPtrField<T>* const mutable_field) {
1587 : return internal::RepeatedPtrFieldBackInsertIterator<T>(mutable_field);
1588 : }
1589 :
1590 : // Provides a back insert iterator for RepeatedPtrField instances
1591 : // similar to std::back_inserter() which transfers the ownership while
1592 : // copying elements.
1593 : template<typename T> internal::AllocatedRepeatedPtrFieldBackInsertIterator<T>
1594 : AllocatedRepeatedPtrFieldBackInserter(
1595 : RepeatedPtrField<T>* const mutable_field) {
1596 : return internal::AllocatedRepeatedPtrFieldBackInsertIterator<T>(
1597 : mutable_field);
1598 : }
1599 :
1600 : } // namespace protobuf
1601 :
1602 : } // namespace google
1603 : #endif // GOOGLE_PROTOBUF_REPEATED_FIELD_H__
|