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