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