/thirdparty/breakpad/third_party/protobuf/protobuf/src/google/protobuf/repeated_field.h

http://github.com/tomahawk-player/tomahawk · C++ Header · 1295 lines · 854 code · 213 blank · 228 comment · 42 complexity · 09c1144db8fd78e26bb9812fe54978cf MD5 · raw file

  1. // Protocol Buffers - Google's data interchange format
  2. // Copyright 2008 Google Inc. All rights reserved.
  3. // http://code.google.com/p/protobuf/
  4. //
  5. // Redistribution and use in source and binary forms, with or without
  6. // modification, are permitted provided that the following conditions are
  7. // met:
  8. //
  9. // * Redistributions of source code must retain the above copyright
  10. // notice, this list of conditions and the following disclaimer.
  11. // * Redistributions in binary form must reproduce the above
  12. // copyright notice, this list of conditions and the following disclaimer
  13. // in the documentation and/or other materials provided with the
  14. // distribution.
  15. // * Neither the name of Google Inc. nor the names of its
  16. // contributors may be used to endorse or promote products derived from
  17. // this software without specific prior written permission.
  18. //
  19. // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  20. // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  21. // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  22. // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  23. // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  24. // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  25. // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  26. // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  27. // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  28. // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  29. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  30. // Author: kenton@google.com (Kenton Varda)
  31. // Based on original Protocol Buffers design by
  32. // Sanjay Ghemawat, Jeff Dean, and others.
  33. //
  34. // RepeatedField and RepeatedPtrField are used by generated protocol message
  35. // classes to manipulate repeated fields. These classes are very similar to
  36. // STL's vector, but include a number of optimizations found to be useful
  37. // specifically in the case of Protocol Buffers. RepeatedPtrField is
  38. // particularly different from STL vector as it manages ownership of the
  39. // pointers that it contains.
  40. //
  41. // Typically, clients should not need to access RepeatedField objects directly,
  42. // but should instead use the accessor functions generated automatically by the
  43. // protocol compiler.
  44. #ifndef GOOGLE_PROTOBUF_REPEATED_FIELD_H__
  45. #define GOOGLE_PROTOBUF_REPEATED_FIELD_H__
  46. #include <string>
  47. #include <iterator>
  48. #include <google/protobuf/stubs/common.h>
  49. #include <google/protobuf/message_lite.h>
  50. namespace google {
  51. namespace protobuf {
  52. class Message;
  53. namespace internal {
  54. // We need this (from generated_message_reflection.cc).
  55. LIBPROTOBUF_EXPORT int StringSpaceUsedExcludingSelf(const string& str);
  56. } // namespace internal
  57. // RepeatedField is used to represent repeated fields of a primitive type (in
  58. // other words, everything except strings and nested Messages). Most users will
  59. // not ever use a RepeatedField directly; they will use the get-by-index,
  60. // set-by-index, and add accessors that are generated for all repeated fields.
  61. template <typename Element>
  62. class RepeatedField {
  63. public:
  64. RepeatedField();
  65. RepeatedField(const RepeatedField& other);
  66. ~RepeatedField();
  67. RepeatedField& operator=(const RepeatedField& other);
  68. int size() const;
  69. const Element& Get(int index) const;
  70. Element* Mutable(int index);
  71. void Set(int index, const Element& value);
  72. void Add(const Element& value);
  73. Element* Add();
  74. // Remove the last element in the array.
  75. // We don't provide a way to remove any element other than the last
  76. // because it invites inefficient use, such as O(n^2) filtering loops
  77. // that should have been O(n). If you want to remove an element other
  78. // than the last, the best way to do it is to re-arrange the elements
  79. // so that the one you want removed is at the end, then call RemoveLast().
  80. void RemoveLast();
  81. void Clear();
  82. void MergeFrom(const RepeatedField& other);
  83. void CopyFrom(const RepeatedField& other);
  84. // Reserve space to expand the field to at least the given size. If the
  85. // array is grown, it will always be at least doubled in size.
  86. void Reserve(int new_size);
  87. // Resize the RepeatedField to a new, smaller size. This is O(1).
  88. void Truncate(int new_size);
  89. void AddAlreadyReserved(const Element& value);
  90. Element* AddAlreadyReserved();
  91. int Capacity() const;
  92. // Gets the underlying array. This pointer is possibly invalidated by
  93. // any add or remove operation.
  94. Element* mutable_data();
  95. const Element* data() const;
  96. // Swap entire contents with "other".
  97. void Swap(RepeatedField* other);
  98. // Swap two elements.
  99. void SwapElements(int index1, int index2);
  100. // STL-like iterator support
  101. typedef Element* iterator;
  102. typedef const Element* const_iterator;
  103. typedef Element value_type;
  104. iterator begin();
  105. const_iterator begin() const;
  106. iterator end();
  107. const_iterator end() const;
  108. // Returns the number of bytes used by the repeated field, excluding
  109. // sizeof(*this)
  110. int SpaceUsedExcludingSelf() const;
  111. private:
  112. static const int kInitialSize = 4;
  113. Element* elements_;
  114. int current_size_;
  115. int total_size_;
  116. Element initial_space_[kInitialSize];
  117. // Move the contents of |from| into |to|, possibly clobbering |from| in the
  118. // process. For primitive types this is just a memcpy(), but it could be
  119. // specialized for non-primitive types to, say, swap each element instead.
  120. void MoveArray(Element to[], Element from[], int size);
  121. // Copy the elements of |from| into |to|.
  122. void CopyArray(Element to[], const Element from[], int size);
  123. };
  124. namespace internal {
  125. template <typename It> class RepeatedPtrIterator;
  126. template <typename It> class RepeatedPtrOverPtrsIterator;
  127. } // namespace internal
  128. namespace internal {
  129. // This is the common base class for RepeatedPtrFields. It deals only in void*
  130. // pointers. Users should not use this interface directly.
  131. //
  132. // The methods of this interface correspond to the methods of RepeatedPtrField,
  133. // but may have a template argument called TypeHandler. Its signature is:
  134. // class TypeHandler {
  135. // public:
  136. // typedef MyType Type;
  137. // static Type* New();
  138. // static void Delete(Type*);
  139. // static void Clear(Type*);
  140. // static void Merge(const Type& from, Type* to);
  141. //
  142. // // Only needs to be implemented if SpaceUsedExcludingSelf() is called.
  143. // static int SpaceUsed(const Type&);
  144. // };
  145. class LIBPROTOBUF_EXPORT RepeatedPtrFieldBase {
  146. protected:
  147. // The reflection implementation needs to call protected methods directly,
  148. // reinterpreting pointers as being to Message instead of a specific Message
  149. // subclass.
  150. friend class GeneratedMessageReflection;
  151. // ExtensionSet stores repeated message extensions as
  152. // RepeatedPtrField<MessageLite>, but non-lite ExtensionSets need to
  153. // implement SpaceUsed(), and thus need to call SpaceUsedExcludingSelf()
  154. // reinterpreting MessageLite as Message. ExtensionSet also needs to make
  155. // use of AddFromCleared(), which is not part of the public interface.
  156. friend class ExtensionSet;
  157. RepeatedPtrFieldBase();
  158. // Must be called from destructor.
  159. template <typename TypeHandler>
  160. void Destroy();
  161. int size() const;
  162. template <typename TypeHandler>
  163. const typename TypeHandler::Type& Get(int index) const;
  164. template <typename TypeHandler>
  165. typename TypeHandler::Type* Mutable(int index);
  166. template <typename TypeHandler>
  167. typename TypeHandler::Type* Add();
  168. template <typename TypeHandler>
  169. void RemoveLast();
  170. template <typename TypeHandler>
  171. void Clear();
  172. template <typename TypeHandler>
  173. void MergeFrom(const RepeatedPtrFieldBase& other);
  174. template <typename TypeHandler>
  175. void CopyFrom(const RepeatedPtrFieldBase& other);
  176. void Reserve(int new_size);
  177. int Capacity() const;
  178. // Used for constructing iterators.
  179. void* const* raw_data() const;
  180. void** raw_mutable_data() const;
  181. template <typename TypeHandler>
  182. typename TypeHandler::Type** mutable_data();
  183. template <typename TypeHandler>
  184. const typename TypeHandler::Type* const* data() const;
  185. void Swap(RepeatedPtrFieldBase* other);
  186. void SwapElements(int index1, int index2);
  187. template <typename TypeHandler>
  188. int SpaceUsedExcludingSelf() const;
  189. // Advanced memory management --------------------------------------
  190. // Like Add(), but if there are no cleared objects to use, returns NULL.
  191. template <typename TypeHandler>
  192. typename TypeHandler::Type* AddFromCleared();
  193. template <typename TypeHandler>
  194. void AddAllocated(typename TypeHandler::Type* value);
  195. template <typename TypeHandler>
  196. typename TypeHandler::Type* ReleaseLast();
  197. int ClearedCount() const;
  198. template <typename TypeHandler>
  199. void AddCleared(typename TypeHandler::Type* value);
  200. template <typename TypeHandler>
  201. typename TypeHandler::Type* ReleaseCleared();
  202. private:
  203. GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RepeatedPtrFieldBase);
  204. static const int kInitialSize = 4;
  205. void** elements_;
  206. int current_size_;
  207. int allocated_size_;
  208. int total_size_;
  209. void* initial_space_[kInitialSize];
  210. template <typename TypeHandler>
  211. static inline typename TypeHandler::Type* cast(void* element) {
  212. return reinterpret_cast<typename TypeHandler::Type*>(element);
  213. }
  214. template <typename TypeHandler>
  215. static inline const typename TypeHandler::Type* cast(const void* element) {
  216. return reinterpret_cast<const typename TypeHandler::Type*>(element);
  217. }
  218. };
  219. template <typename GenericType>
  220. class GenericTypeHandler {
  221. public:
  222. typedef GenericType Type;
  223. static GenericType* New() { return new GenericType; }
  224. static void Delete(GenericType* value) { delete value; }
  225. static void Clear(GenericType* value) { value->Clear(); }
  226. static void Merge(const GenericType& from, GenericType* to) {
  227. to->MergeFrom(from);
  228. }
  229. static int SpaceUsed(const GenericType& value) { return value.SpaceUsed(); }
  230. };
  231. template <>
  232. inline void GenericTypeHandler<MessageLite>::Merge(
  233. const MessageLite& from, MessageLite* to) {
  234. to->CheckTypeAndMergeFrom(from);
  235. }
  236. // HACK: If a class is declared as DLL-exported in MSVC, it insists on
  237. // generating copies of all its methods -- even inline ones -- to include
  238. // in the DLL. But SpaceUsed() calls StringSpaceUsedExcludingSelf() which
  239. // isn't in the lite library, therefore the lite library cannot link if
  240. // StringTypeHandler is exported. So, we factor out StringTypeHandlerBase,
  241. // export that, then make StringTypeHandler be a subclass which is NOT
  242. // exported.
  243. // TODO(kenton): There has to be a better way.
  244. class LIBPROTOBUF_EXPORT StringTypeHandlerBase {
  245. public:
  246. typedef string Type;
  247. static string* New();
  248. static void Delete(string* value);
  249. static void Clear(string* value) { value->clear(); }
  250. static void Merge(const string& from, string* to) { *to = from; }
  251. };
  252. class StringTypeHandler : public StringTypeHandlerBase {
  253. public:
  254. static int SpaceUsed(const string& value) {
  255. return sizeof(value) + StringSpaceUsedExcludingSelf(value);
  256. }
  257. };
  258. } // namespace internal
  259. // RepeatedPtrField is like RepeatedField, but used for repeated strings or
  260. // Messages.
  261. template <typename Element>
  262. class RepeatedPtrField : public internal::RepeatedPtrFieldBase {
  263. public:
  264. RepeatedPtrField();
  265. RepeatedPtrField(const RepeatedPtrField& other);
  266. ~RepeatedPtrField();
  267. RepeatedPtrField& operator=(const RepeatedPtrField& other);
  268. int size() const;
  269. const Element& Get(int index) const;
  270. Element* Mutable(int index);
  271. Element* Add();
  272. void RemoveLast(); // Remove the last element in the array.
  273. void Clear();
  274. void MergeFrom(const RepeatedPtrField& other);
  275. void CopyFrom(const RepeatedPtrField& other);
  276. // Reserve space to expand the field to at least the given size. This only
  277. // resizes the pointer array; it doesn't allocate any objects. If the
  278. // array is grown, it will always be at least doubled in size.
  279. void Reserve(int new_size);
  280. int Capacity() const;
  281. // Gets the underlying array. This pointer is possibly invalidated by
  282. // any add or remove operation.
  283. Element** mutable_data();
  284. const Element* const* data() const;
  285. // Swap entire contents with "other".
  286. void Swap(RepeatedPtrField* other);
  287. // Swap two elements.
  288. void SwapElements(int index1, int index2);
  289. // STL-like iterator support
  290. typedef internal::RepeatedPtrIterator<Element> iterator;
  291. typedef internal::RepeatedPtrIterator<const Element> const_iterator;
  292. typedef Element value_type;
  293. iterator begin();
  294. const_iterator begin() const;
  295. iterator end();
  296. const_iterator end() const;
  297. // Custom STL-like iterator that iterates over and returns the underlying
  298. // pointers to Element rather than Element itself.
  299. typedef internal::RepeatedPtrOverPtrsIterator<Element> pointer_iterator;
  300. pointer_iterator pointer_begin();
  301. pointer_iterator pointer_end();
  302. // Returns (an estimate of) the number of bytes used by the repeated field,
  303. // excluding sizeof(*this).
  304. int SpaceUsedExcludingSelf() const;
  305. // Advanced memory management --------------------------------------
  306. // When hardcore memory management becomes necessary -- as it often
  307. // does here at Google -- the following methods may be useful.
  308. // Add an already-allocated object, passing ownership to the
  309. // RepeatedPtrField.
  310. void AddAllocated(Element* value);
  311. // Remove the last element and return it, passing ownership to the
  312. // caller.
  313. // Requires: size() > 0
  314. Element* ReleaseLast();
  315. // When elements are removed by calls to RemoveLast() or Clear(), they
  316. // are not actually freed. Instead, they are cleared and kept so that
  317. // they can be reused later. This can save lots of CPU time when
  318. // repeatedly reusing a protocol message for similar purposes.
  319. //
  320. // Really, extremely hardcore programs may actually want to manipulate
  321. // these objects to better-optimize memory management. These methods
  322. // allow that.
  323. // Get the number of cleared objects that are currently being kept
  324. // around for reuse.
  325. int ClearedCount() const;
  326. // Add an element to the pool of cleared objects, passing ownership to
  327. // the RepeatedPtrField. The element must be cleared prior to calling
  328. // this method.
  329. void AddCleared(Element* value);
  330. // Remove a single element from the cleared pool and return it, passing
  331. // ownership to the caller. The element is guaranteed to be cleared.
  332. // Requires: ClearedCount() > 0
  333. Element* ReleaseCleared();
  334. protected:
  335. // Note: RepeatedPtrField SHOULD NOT be subclassed by users. We only
  336. // subclass it in one place as a hack for compatibility with proto1. The
  337. // subclass needs to know about TypeHandler in order to call protected
  338. // methods on RepeatedPtrFieldBase.
  339. class TypeHandler;
  340. };
  341. // implementation ====================================================
  342. template <typename Element>
  343. inline RepeatedField<Element>::RepeatedField()
  344. : elements_(initial_space_),
  345. current_size_(0),
  346. total_size_(kInitialSize) {
  347. }
  348. template <typename Element>
  349. inline RepeatedField<Element>::RepeatedField(const RepeatedField& other)
  350. : elements_(initial_space_),
  351. current_size_(0),
  352. total_size_(kInitialSize) {
  353. CopyFrom(other);
  354. }
  355. template <typename Element>
  356. RepeatedField<Element>::~RepeatedField() {
  357. if (elements_ != initial_space_) {
  358. delete [] elements_;
  359. }
  360. }
  361. template <typename Element>
  362. inline RepeatedField<Element>&
  363. RepeatedField<Element>::operator=(const RepeatedField& other) {
  364. CopyFrom(other);
  365. return *this;
  366. }
  367. template <typename Element>
  368. inline int RepeatedField<Element>::size() const {
  369. return current_size_;
  370. }
  371. template <typename Element>
  372. inline int RepeatedField<Element>::Capacity() const {
  373. return total_size_;
  374. }
  375. template<typename Element>
  376. inline void RepeatedField<Element>::AddAlreadyReserved(const Element& value) {
  377. GOOGLE_DCHECK_LT(size(), Capacity());
  378. elements_[current_size_++] = value;
  379. }
  380. template<typename Element>
  381. inline Element* RepeatedField<Element>::AddAlreadyReserved() {
  382. GOOGLE_DCHECK_LT(size(), Capacity());
  383. return &elements_[current_size_++];
  384. }
  385. template <typename Element>
  386. inline const Element& RepeatedField<Element>::Get(int index) const {
  387. GOOGLE_DCHECK_LT(index, size());
  388. return elements_[index];
  389. }
  390. template <typename Element>
  391. inline Element* RepeatedField<Element>::Mutable(int index) {
  392. GOOGLE_DCHECK_LT(index, size());
  393. return elements_ + index;
  394. }
  395. template <typename Element>
  396. inline void RepeatedField<Element>::Set(int index, const Element& value) {
  397. GOOGLE_DCHECK_LT(index, size());
  398. elements_[index] = value;
  399. }
  400. template <typename Element>
  401. inline void RepeatedField<Element>::Add(const Element& value) {
  402. if (current_size_ == total_size_) Reserve(total_size_ + 1);
  403. elements_[current_size_++] = value;
  404. }
  405. template <typename Element>
  406. inline Element* RepeatedField<Element>::Add() {
  407. if (current_size_ == total_size_) Reserve(total_size_ + 1);
  408. return &elements_[current_size_++];
  409. }
  410. template <typename Element>
  411. inline void RepeatedField<Element>::RemoveLast() {
  412. GOOGLE_DCHECK_GT(current_size_, 0);
  413. --current_size_;
  414. }
  415. template <typename Element>
  416. inline void RepeatedField<Element>::Clear() {
  417. current_size_ = 0;
  418. }
  419. template <typename Element>
  420. inline void RepeatedField<Element>::MergeFrom(const RepeatedField& other) {
  421. Reserve(current_size_ + other.current_size_);
  422. CopyArray(elements_ + current_size_, other.elements_, other.current_size_);
  423. current_size_ += other.current_size_;
  424. }
  425. template <typename Element>
  426. inline void RepeatedField<Element>::CopyFrom(const RepeatedField& other) {
  427. Clear();
  428. MergeFrom(other);
  429. }
  430. template <typename Element>
  431. inline Element* RepeatedField<Element>::mutable_data() {
  432. return elements_;
  433. }
  434. template <typename Element>
  435. inline const Element* RepeatedField<Element>::data() const {
  436. return elements_;
  437. }
  438. template <typename Element>
  439. void RepeatedField<Element>::Swap(RepeatedField* other) {
  440. Element* swap_elements = elements_;
  441. int swap_current_size = current_size_;
  442. int swap_total_size = total_size_;
  443. // We may not be using initial_space_ but it's not worth checking. Just
  444. // copy it anyway.
  445. Element swap_initial_space[kInitialSize];
  446. MoveArray(swap_initial_space, initial_space_, kInitialSize);
  447. elements_ = other->elements_;
  448. current_size_ = other->current_size_;
  449. total_size_ = other->total_size_;
  450. MoveArray(initial_space_, other->initial_space_, kInitialSize);
  451. other->elements_ = swap_elements;
  452. other->current_size_ = swap_current_size;
  453. other->total_size_ = swap_total_size;
  454. MoveArray(other->initial_space_, swap_initial_space, kInitialSize);
  455. if (elements_ == other->initial_space_) {
  456. elements_ = initial_space_;
  457. }
  458. if (other->elements_ == initial_space_) {
  459. other->elements_ = other->initial_space_;
  460. }
  461. }
  462. template <typename Element>
  463. void RepeatedField<Element>::SwapElements(int index1, int index2) {
  464. std::swap(elements_[index1], elements_[index2]);
  465. }
  466. template <typename Element>
  467. inline typename RepeatedField<Element>::iterator
  468. RepeatedField<Element>::begin() {
  469. return elements_;
  470. }
  471. template <typename Element>
  472. inline typename RepeatedField<Element>::const_iterator
  473. RepeatedField<Element>::begin() const {
  474. return elements_;
  475. }
  476. template <typename Element>
  477. inline typename RepeatedField<Element>::iterator
  478. RepeatedField<Element>::end() {
  479. return elements_ + current_size_;
  480. }
  481. template <typename Element>
  482. inline typename RepeatedField<Element>::const_iterator
  483. RepeatedField<Element>::end() const {
  484. return elements_ + current_size_;
  485. }
  486. template <typename Element>
  487. inline int RepeatedField<Element>::SpaceUsedExcludingSelf() const {
  488. return (elements_ != initial_space_) ? total_size_ * sizeof(elements_[0]) : 0;
  489. }
  490. // Avoid inlining of Reserve(): new, memcpy, and delete[] lead to a significant
  491. // amount of code bloat.
  492. template <typename Element>
  493. void RepeatedField<Element>::Reserve(int new_size) {
  494. if (total_size_ >= new_size) return;
  495. Element* old_elements = elements_;
  496. total_size_ = max(total_size_ * 2, new_size);
  497. elements_ = new Element[total_size_];
  498. MoveArray(elements_, old_elements, current_size_);
  499. if (old_elements != initial_space_) {
  500. delete [] old_elements;
  501. }
  502. }
  503. template <typename Element>
  504. inline void RepeatedField<Element>::Truncate(int new_size) {
  505. GOOGLE_DCHECK_LE(new_size, current_size_);
  506. current_size_ = new_size;
  507. }
  508. template <typename Element>
  509. inline void RepeatedField<Element>::MoveArray(
  510. Element to[], Element from[], int array_size) {
  511. memcpy(to, from, array_size * sizeof(Element));
  512. }
  513. template <typename Element>
  514. inline void RepeatedField<Element>::CopyArray(
  515. Element to[], const Element from[], int array_size) {
  516. memcpy(to, from, array_size * sizeof(Element));
  517. }
  518. // -------------------------------------------------------------------
  519. namespace internal {
  520. inline RepeatedPtrFieldBase::RepeatedPtrFieldBase()
  521. : elements_(initial_space_),
  522. current_size_(0),
  523. allocated_size_(0),
  524. total_size_(kInitialSize) {
  525. }
  526. template <typename TypeHandler>
  527. void RepeatedPtrFieldBase::Destroy() {
  528. for (int i = 0; i < allocated_size_; i++) {
  529. TypeHandler::Delete(cast<TypeHandler>(elements_[i]));
  530. }
  531. if (elements_ != initial_space_) {
  532. delete [] elements_;
  533. }
  534. }
  535. inline int RepeatedPtrFieldBase::size() const {
  536. return current_size_;
  537. }
  538. template <typename TypeHandler>
  539. inline const typename TypeHandler::Type&
  540. RepeatedPtrFieldBase::Get(int index) const {
  541. GOOGLE_DCHECK_LT(index, size());
  542. return *cast<TypeHandler>(elements_[index]);
  543. }
  544. template <typename TypeHandler>
  545. inline typename TypeHandler::Type*
  546. RepeatedPtrFieldBase::Mutable(int index) {
  547. GOOGLE_DCHECK_LT(index, size());
  548. return cast<TypeHandler>(elements_[index]);
  549. }
  550. template <typename TypeHandler>
  551. inline typename TypeHandler::Type* RepeatedPtrFieldBase::Add() {
  552. if (current_size_ < allocated_size_) {
  553. return cast<TypeHandler>(elements_[current_size_++]);
  554. }
  555. if (allocated_size_ == total_size_) Reserve(total_size_ + 1);
  556. ++allocated_size_;
  557. typename TypeHandler::Type* result = TypeHandler::New();
  558. elements_[current_size_++] = result;
  559. return result;
  560. }
  561. template <typename TypeHandler>
  562. inline void RepeatedPtrFieldBase::RemoveLast() {
  563. GOOGLE_DCHECK_GT(current_size_, 0);
  564. TypeHandler::Clear(cast<TypeHandler>(elements_[--current_size_]));
  565. }
  566. template <typename TypeHandler>
  567. void RepeatedPtrFieldBase::Clear() {
  568. for (int i = 0; i < current_size_; i++) {
  569. TypeHandler::Clear(cast<TypeHandler>(elements_[i]));
  570. }
  571. current_size_ = 0;
  572. }
  573. template <typename TypeHandler>
  574. inline void RepeatedPtrFieldBase::MergeFrom(const RepeatedPtrFieldBase& other) {
  575. Reserve(current_size_ + other.current_size_);
  576. for (int i = 0; i < other.current_size_; i++) {
  577. TypeHandler::Merge(other.template Get<TypeHandler>(i), Add<TypeHandler>());
  578. }
  579. }
  580. template <typename TypeHandler>
  581. inline void RepeatedPtrFieldBase::CopyFrom(const RepeatedPtrFieldBase& other) {
  582. RepeatedPtrFieldBase::Clear<TypeHandler>();
  583. RepeatedPtrFieldBase::MergeFrom<TypeHandler>(other);
  584. }
  585. inline int RepeatedPtrFieldBase::Capacity() const {
  586. return total_size_;
  587. }
  588. inline void* const* RepeatedPtrFieldBase::raw_data() const {
  589. return elements_;
  590. }
  591. inline void** RepeatedPtrFieldBase::raw_mutable_data() const {
  592. return elements_;
  593. }
  594. template <typename TypeHandler>
  595. inline typename TypeHandler::Type** RepeatedPtrFieldBase::mutable_data() {
  596. // TODO(kenton): Breaks C++ aliasing rules. We should probably remove this
  597. // method entirely.
  598. return reinterpret_cast<typename TypeHandler::Type**>(elements_);
  599. }
  600. template <typename TypeHandler>
  601. inline const typename TypeHandler::Type* const*
  602. RepeatedPtrFieldBase::data() const {
  603. // TODO(kenton): Breaks C++ aliasing rules. We should probably remove this
  604. // method entirely.
  605. return reinterpret_cast<const typename TypeHandler::Type* const*>(elements_);
  606. }
  607. inline void RepeatedPtrFieldBase::SwapElements(int index1, int index2) {
  608. std::swap(elements_[index1], elements_[index2]);
  609. }
  610. template <typename TypeHandler>
  611. inline int RepeatedPtrFieldBase::SpaceUsedExcludingSelf() const {
  612. int allocated_bytes =
  613. (elements_ != initial_space_) ? total_size_ * sizeof(elements_[0]) : 0;
  614. for (int i = 0; i < allocated_size_; ++i) {
  615. allocated_bytes += TypeHandler::SpaceUsed(*cast<TypeHandler>(elements_[i]));
  616. }
  617. return allocated_bytes;
  618. }
  619. template <typename TypeHandler>
  620. inline typename TypeHandler::Type* RepeatedPtrFieldBase::AddFromCleared() {
  621. if (current_size_ < allocated_size_) {
  622. return cast<TypeHandler>(elements_[current_size_++]);
  623. } else {
  624. return NULL;
  625. }
  626. }
  627. template <typename TypeHandler>
  628. void RepeatedPtrFieldBase::AddAllocated(
  629. typename TypeHandler::Type* value) {
  630. // Make room for the new pointer.
  631. if (current_size_ == total_size_) {
  632. // The array is completely full with no cleared objects, so grow it.
  633. Reserve(total_size_ + 1);
  634. ++allocated_size_;
  635. } else if (allocated_size_ == total_size_) {
  636. // There is no more space in the pointer array because it contains some
  637. // cleared objects awaiting reuse. We don't want to grow the array in this
  638. // case because otherwise a loop calling AddAllocated() followed by Clear()
  639. // would leak memory.
  640. TypeHandler::Delete(cast<TypeHandler>(elements_[current_size_]));
  641. } else if (current_size_ < allocated_size_) {
  642. // We have some cleared objects. We don't care about their order, so we
  643. // can just move the first one to the end to make space.
  644. elements_[allocated_size_] = elements_[current_size_];
  645. ++allocated_size_;
  646. } else {
  647. // There are no cleared objects.
  648. ++allocated_size_;
  649. }
  650. elements_[current_size_++] = value;
  651. }
  652. template <typename TypeHandler>
  653. inline typename TypeHandler::Type* RepeatedPtrFieldBase::ReleaseLast() {
  654. GOOGLE_DCHECK_GT(current_size_, 0);
  655. typename TypeHandler::Type* result =
  656. cast<TypeHandler>(elements_[--current_size_]);
  657. --allocated_size_;
  658. if (current_size_ < allocated_size_) {
  659. // There are cleared elements on the end; replace the removed element
  660. // with the last allocated element.
  661. elements_[current_size_] = elements_[allocated_size_];
  662. }
  663. return result;
  664. }
  665. inline int RepeatedPtrFieldBase::ClearedCount() const {
  666. return allocated_size_ - current_size_;
  667. }
  668. template <typename TypeHandler>
  669. inline void RepeatedPtrFieldBase::AddCleared(
  670. typename TypeHandler::Type* value) {
  671. if (allocated_size_ == total_size_) Reserve(total_size_ + 1);
  672. elements_[allocated_size_++] = value;
  673. }
  674. template <typename TypeHandler>
  675. inline typename TypeHandler::Type* RepeatedPtrFieldBase::ReleaseCleared() {
  676. GOOGLE_DCHECK_GT(allocated_size_, current_size_);
  677. return cast<TypeHandler>(elements_[--allocated_size_]);
  678. }
  679. } // namespace internal
  680. // -------------------------------------------------------------------
  681. template <typename Element>
  682. class RepeatedPtrField<Element>::TypeHandler
  683. : public internal::GenericTypeHandler<Element> {};
  684. template <>
  685. class RepeatedPtrField<string>::TypeHandler
  686. : public internal::StringTypeHandler {};
  687. template <typename Element>
  688. inline RepeatedPtrField<Element>::RepeatedPtrField() {}
  689. template <typename Element>
  690. inline RepeatedPtrField<Element>::RepeatedPtrField(
  691. const RepeatedPtrField& other) {
  692. CopyFrom(other);
  693. }
  694. template <typename Element>
  695. RepeatedPtrField<Element>::~RepeatedPtrField() {
  696. Destroy<TypeHandler>();
  697. }
  698. template <typename Element>
  699. inline RepeatedPtrField<Element>& RepeatedPtrField<Element>::operator=(
  700. const RepeatedPtrField& other) {
  701. CopyFrom(other);
  702. return *this;
  703. }
  704. template <typename Element>
  705. inline int RepeatedPtrField<Element>::size() const {
  706. return RepeatedPtrFieldBase::size();
  707. }
  708. template <typename Element>
  709. inline const Element& RepeatedPtrField<Element>::Get(int index) const {
  710. return RepeatedPtrFieldBase::Get<TypeHandler>(index);
  711. }
  712. template <typename Element>
  713. inline Element* RepeatedPtrField<Element>::Mutable(int index) {
  714. return RepeatedPtrFieldBase::Mutable<TypeHandler>(index);
  715. }
  716. template <typename Element>
  717. inline Element* RepeatedPtrField<Element>::Add() {
  718. return RepeatedPtrFieldBase::Add<TypeHandler>();
  719. }
  720. template <typename Element>
  721. inline void RepeatedPtrField<Element>::RemoveLast() {
  722. RepeatedPtrFieldBase::RemoveLast<TypeHandler>();
  723. }
  724. template <typename Element>
  725. inline void RepeatedPtrField<Element>::Clear() {
  726. RepeatedPtrFieldBase::Clear<TypeHandler>();
  727. }
  728. template <typename Element>
  729. inline void RepeatedPtrField<Element>::MergeFrom(
  730. const RepeatedPtrField& other) {
  731. RepeatedPtrFieldBase::MergeFrom<TypeHandler>(other);
  732. }
  733. template <typename Element>
  734. inline void RepeatedPtrField<Element>::CopyFrom(
  735. const RepeatedPtrField& other) {
  736. RepeatedPtrFieldBase::CopyFrom<TypeHandler>(other);
  737. }
  738. template <typename Element>
  739. inline Element** RepeatedPtrField<Element>::mutable_data() {
  740. return RepeatedPtrFieldBase::mutable_data<TypeHandler>();
  741. }
  742. template <typename Element>
  743. inline const Element* const* RepeatedPtrField<Element>::data() const {
  744. return RepeatedPtrFieldBase::data<TypeHandler>();
  745. }
  746. template <typename Element>
  747. void RepeatedPtrField<Element>::Swap(RepeatedPtrField* other) {
  748. RepeatedPtrFieldBase::Swap(other);
  749. }
  750. template <typename Element>
  751. void RepeatedPtrField<Element>::SwapElements(int index1, int index2) {
  752. RepeatedPtrFieldBase::SwapElements(index1, index2);
  753. }
  754. template <typename Element>
  755. inline int RepeatedPtrField<Element>::SpaceUsedExcludingSelf() const {
  756. return RepeatedPtrFieldBase::SpaceUsedExcludingSelf<TypeHandler>();
  757. }
  758. template <typename Element>
  759. inline void RepeatedPtrField<Element>::AddAllocated(Element* value) {
  760. RepeatedPtrFieldBase::AddAllocated<TypeHandler>(value);
  761. }
  762. template <typename Element>
  763. inline Element* RepeatedPtrField<Element>::ReleaseLast() {
  764. return RepeatedPtrFieldBase::ReleaseLast<TypeHandler>();
  765. }
  766. template <typename Element>
  767. inline int RepeatedPtrField<Element>::ClearedCount() const {
  768. return RepeatedPtrFieldBase::ClearedCount();
  769. }
  770. template <typename Element>
  771. inline void RepeatedPtrField<Element>::AddCleared(Element* value) {
  772. return RepeatedPtrFieldBase::AddCleared<TypeHandler>(value);
  773. }
  774. template <typename Element>
  775. inline Element* RepeatedPtrField<Element>::ReleaseCleared() {
  776. return RepeatedPtrFieldBase::ReleaseCleared<TypeHandler>();
  777. }
  778. template <typename Element>
  779. inline void RepeatedPtrField<Element>::Reserve(int new_size) {
  780. return RepeatedPtrFieldBase::Reserve(new_size);
  781. }
  782. template <typename Element>
  783. inline int RepeatedPtrField<Element>::Capacity() const {
  784. return RepeatedPtrFieldBase::Capacity();
  785. }
  786. // -------------------------------------------------------------------
  787. namespace internal {
  788. // STL-like iterator implementation for RepeatedPtrField. You should not
  789. // refer to this class directly; use RepeatedPtrField<T>::iterator instead.
  790. //
  791. // The iterator for RepeatedPtrField<T>, RepeatedPtrIterator<T>, is
  792. // very similar to iterator_ptr<T**> in util/gtl/iterator_adaptors-inl.h,
  793. // but adds random-access operators and is modified to wrap a void** base
  794. // iterator (since RepeatedPtrField stores its array as a void* array and
  795. // casting void** to T** would violate C++ aliasing rules).
  796. //
  797. // This code based on net/proto/proto-array-internal.h by Jeffrey Yasskin
  798. // (jyasskin@google.com).
  799. template<typename Element>
  800. class RepeatedPtrIterator
  801. : public std::iterator<
  802. std::random_access_iterator_tag, Element> {
  803. public:
  804. typedef RepeatedPtrIterator<Element> iterator;
  805. typedef std::iterator<
  806. std::random_access_iterator_tag, Element> superclass;
  807. // Let the compiler know that these are type names, so we don't have to
  808. // write "typename" in front of them everywhere.
  809. typedef typename superclass::reference reference;
  810. typedef typename superclass::pointer pointer;
  811. typedef typename superclass::difference_type difference_type;
  812. RepeatedPtrIterator() : it_(NULL) {}
  813. explicit RepeatedPtrIterator(void* const* it) : it_(it) {}
  814. // Allow "upcasting" from RepeatedPtrIterator<T**> to
  815. // RepeatedPtrIterator<const T*const*>.
  816. template<typename OtherElement>
  817. RepeatedPtrIterator(const RepeatedPtrIterator<OtherElement>& other)
  818. : it_(other.it_) {
  819. // Force a compiler error if the other type is not convertible to ours.
  820. if (false) {
  821. implicit_cast<Element*, OtherElement*>(0);
  822. }
  823. }
  824. // dereferenceable
  825. reference operator*() const { return *reinterpret_cast<Element*>(*it_); }
  826. pointer operator->() const { return &(operator*()); }
  827. // {inc,dec}rementable
  828. iterator& operator++() { ++it_; return *this; }
  829. iterator operator++(int) { return iterator(it_++); }
  830. iterator& operator--() { --it_; return *this; }
  831. iterator operator--(int) { return iterator(it_--); }
  832. // equality_comparable
  833. bool operator==(const iterator& x) const { return it_ == x.it_; }
  834. bool operator!=(const iterator& x) const { return it_ != x.it_; }
  835. // less_than_comparable
  836. bool operator<(const iterator& x) const { return it_ < x.it_; }
  837. bool operator<=(const iterator& x) const { return it_ <= x.it_; }
  838. bool operator>(const iterator& x) const { return it_ > x.it_; }
  839. bool operator>=(const iterator& x) const { return it_ >= x.it_; }
  840. // addable, subtractable
  841. iterator& operator+=(difference_type d) {
  842. it_ += d;
  843. return *this;
  844. }
  845. friend iterator operator+(iterator it, difference_type d) {
  846. it += d;
  847. return it;
  848. }
  849. friend iterator operator+(difference_type d, iterator it) {
  850. it += d;
  851. return it;
  852. }
  853. iterator& operator-=(difference_type d) {
  854. it_ -= d;
  855. return *this;
  856. }
  857. friend iterator operator-(iterator it, difference_type d) {
  858. it -= d;
  859. return it;
  860. }
  861. // indexable
  862. reference operator[](difference_type d) const { return *(*this + d); }
  863. // random access iterator
  864. difference_type operator-(const iterator& x) const { return it_ - x.it_; }
  865. private:
  866. template<typename OtherElement>
  867. friend class RepeatedPtrIterator;
  868. // The internal iterator.
  869. void* const* it_;
  870. };
  871. // Provide an iterator that operates on pointers to the underlying objects
  872. // rather than the objects themselves as RepeatedPtrIterator does.
  873. // Consider using this when working with stl algorithms that change
  874. // the array.
  875. template<typename Element>
  876. class RepeatedPtrOverPtrsIterator
  877. : public std::iterator<std::random_access_iterator_tag, Element*> {
  878. public:
  879. typedef RepeatedPtrOverPtrsIterator<Element> iterator;
  880. typedef std::iterator<
  881. std::random_access_iterator_tag, Element*> superclass;
  882. // Let the compiler know that these are type names, so we don't have to
  883. // write "typename" in front of them everywhere.
  884. typedef typename superclass::reference reference;
  885. typedef typename superclass::pointer pointer;
  886. typedef typename superclass::difference_type difference_type;
  887. RepeatedPtrOverPtrsIterator() : it_(NULL) {}
  888. explicit RepeatedPtrOverPtrsIterator(void** it) : it_(it) {}
  889. // dereferenceable
  890. reference operator*() const { return *reinterpret_cast<Element**>(it_); }
  891. pointer operator->() const { return &(operator*()); }
  892. // {inc,dec}rementable
  893. iterator& operator++() { ++it_; return *this; }
  894. iterator operator++(int) { return iterator(it_++); }
  895. iterator& operator--() { --it_; return *this; }
  896. iterator operator--(int) { return iterator(it_--); }
  897. // equality_comparable
  898. bool operator==(const iterator& x) const { return it_ == x.it_; }
  899. bool operator!=(const iterator& x) const { return it_ != x.it_; }
  900. // less_than_comparable
  901. bool operator<(const iterator& x) const { return it_ < x.it_; }
  902. bool operator<=(const iterator& x) const { return it_ <= x.it_; }
  903. bool operator>(const iterator& x) const { return it_ > x.it_; }
  904. bool operator>=(const iterator& x) const { return it_ >= x.it_; }
  905. // addable, subtractable
  906. iterator& operator+=(difference_type d) {
  907. it_ += d;
  908. return *this;
  909. }
  910. friend iterator operator+(iterator it, difference_type d) {
  911. it += d;
  912. return it;
  913. }
  914. friend iterator operator+(difference_type d, iterator it) {
  915. it += d;
  916. return it;
  917. }
  918. iterator& operator-=(difference_type d) {
  919. it_ -= d;
  920. return *this;
  921. }
  922. friend iterator operator-(iterator it, difference_type d) {
  923. it -= d;
  924. return it;
  925. }
  926. // indexable
  927. reference operator[](difference_type d) const { return *(*this + d); }
  928. // random access iterator
  929. difference_type operator-(const iterator& x) const { return it_ - x.it_; }
  930. private:
  931. template<typename OtherElement>
  932. friend class RepeatedPtrIterator;
  933. // The internal iterator.
  934. void** it_;
  935. };
  936. } // namespace internal
  937. template <typename Element>
  938. inline typename RepeatedPtrField<Element>::iterator
  939. RepeatedPtrField<Element>::begin() {
  940. return iterator(raw_data());
  941. }
  942. template <typename Element>
  943. inline typename RepeatedPtrField<Element>::const_iterator
  944. RepeatedPtrField<Element>::begin() const {
  945. return iterator(raw_data());
  946. }
  947. template <typename Element>
  948. inline typename RepeatedPtrField<Element>::iterator
  949. RepeatedPtrField<Element>::end() {
  950. return iterator(raw_data() + size());
  951. }
  952. template <typename Element>
  953. inline typename RepeatedPtrField<Element>::const_iterator
  954. RepeatedPtrField<Element>::end() const {
  955. return iterator(raw_data() + size());
  956. }
  957. template <typename Element>
  958. inline typename RepeatedPtrField<Element>::pointer_iterator
  959. RepeatedPtrField<Element>::pointer_begin() {
  960. return pointer_iterator(raw_mutable_data());
  961. }
  962. template <typename Element>
  963. inline typename RepeatedPtrField<Element>::pointer_iterator
  964. RepeatedPtrField<Element>::pointer_end() {
  965. return pointer_iterator(raw_mutable_data() + size());
  966. }
  967. // Iterators and helper functions that follow the spirit of the STL
  968. // std::back_insert_iterator and std::back_inserter but are tailor-made
  969. // for RepeatedField and RepatedPtrField. Typical usage would be:
  970. //
  971. // std::copy(some_sequence.begin(), some_sequence.end(),
  972. // google::protobuf::RepeatedFieldBackInserter(proto.mutable_sequence()));
  973. //
  974. // Ported by johannes from util/gtl/proto-array-iterators-inl.h
  975. namespace internal {
  976. // A back inserter for RepeatedField objects.
  977. template<typename T> class RepeatedFieldBackInsertIterator
  978. : public std::iterator<std::output_iterator_tag, T> {
  979. public:
  980. explicit RepeatedFieldBackInsertIterator(
  981. RepeatedField<T>* const mutable_field)
  982. : field_(mutable_field) {
  983. }
  984. RepeatedFieldBackInsertIterator<T>& operator=(const T& value) {
  985. field_->Add(value);
  986. return *this;
  987. }
  988. RepeatedFieldBackInsertIterator<T>& operator*() {
  989. return *this;
  990. }
  991. RepeatedFieldBackInsertIterator<T>& operator++() {
  992. return *this;
  993. }
  994. RepeatedFieldBackInsertIterator<T>& operator++(int ignores_parameter) {
  995. return *this;
  996. }
  997. private:
  998. RepeatedField<T>* field_;
  999. };
  1000. // A back inserter for RepeatedPtrField objects.
  1001. template<typename T> class RepeatedPtrFieldBackInsertIterator
  1002. : public std::iterator<std::output_iterator_tag, T> {
  1003. public:
  1004. RepeatedPtrFieldBackInsertIterator(
  1005. RepeatedPtrField<T>* const mutable_field)
  1006. : field_(mutable_field) {
  1007. }
  1008. RepeatedPtrFieldBackInsertIterator<T>& operator=(const T& value) {
  1009. *field_->Add() = value;
  1010. return *this;
  1011. }
  1012. RepeatedPtrFieldBackInsertIterator<T>& operator=(
  1013. const T* const ptr_to_value) {
  1014. *field_->Add() = *ptr_to_value;
  1015. return *this;
  1016. }
  1017. RepeatedPtrFieldBackInsertIterator<T>& operator*() {
  1018. return *this;
  1019. }
  1020. RepeatedPtrFieldBackInsertIterator<T>& operator++() {
  1021. return *this;
  1022. }
  1023. RepeatedPtrFieldBackInsertIterator<T>& operator++(int ignores_parameter) {
  1024. return *this;
  1025. }
  1026. private:
  1027. RepeatedPtrField<T>* field_;
  1028. };
  1029. // A back inserter for RepeatedPtrFields that inserts by transfering ownership
  1030. // of a pointer.
  1031. template<typename T> class AllocatedRepeatedPtrFieldBackInsertIterator
  1032. : public std::iterator<std::output_iterator_tag, T> {
  1033. public:
  1034. explicit AllocatedRepeatedPtrFieldBackInsertIterator(
  1035. RepeatedPtrField<T>* const mutable_field)
  1036. : field_(mutable_field) {
  1037. }
  1038. AllocatedRepeatedPtrFieldBackInsertIterator<T>& operator=(
  1039. T* const ptr_to_value) {
  1040. field_->AddAllocated(ptr_to_value);
  1041. return *this;
  1042. }
  1043. AllocatedRepeatedPtrFieldBackInsertIterator<T>& operator*() {
  1044. return *this;
  1045. }
  1046. AllocatedRepeatedPtrFieldBackInsertIterator<T>& operator++() {
  1047. return *this;
  1048. }
  1049. AllocatedRepeatedPtrFieldBackInsertIterator<T>& operator++(
  1050. int ignores_parameter) {
  1051. return *this;
  1052. }
  1053. private:
  1054. RepeatedPtrField<T>* field_;
  1055. };
  1056. } // namespace internal
  1057. // Provides a back insert iterator for RepeatedField instances,
  1058. // similar to std::back_inserter(). Note the identically named
  1059. // function for RepeatedPtrField instances.
  1060. template<typename T> internal::RepeatedFieldBackInsertIterator<T>
  1061. RepeatedFieldBackInserter(RepeatedField<T>* const mutable_field) {
  1062. return internal::RepeatedFieldBackInsertIterator<T>(mutable_field);
  1063. }
  1064. // Provides a back insert iterator for RepeatedPtrField instances,
  1065. // similar to std::back_inserter(). Note the identically named
  1066. // function for RepeatedField instances.
  1067. template<typename T> internal::RepeatedPtrFieldBackInsertIterator<T>
  1068. RepeatedFieldBackInserter(RepeatedPtrField<T>* const mutable_field) {
  1069. return internal::RepeatedPtrFieldBackInsertIterator<T>(mutable_field);
  1070. }
  1071. // Provides a back insert iterator for RepeatedPtrField instances
  1072. // similar to std::back_inserter() which transfers the ownership while
  1073. // copying elements.
  1074. template<typename T> internal::AllocatedRepeatedPtrFieldBackInsertIterator<T>
  1075. AllocatedRepeatedPtrFieldBackInserter(
  1076. RepeatedPtrField<T>* const mutable_field) {
  1077. return internal::AllocatedRepeatedPtrFieldBackInsertIterator<T>(
  1078. mutable_field);
  1079. }
  1080. } // namespace protobuf
  1081. } // namespace google
  1082. #endif // GOOGLE_PROTOBUF_REPEATED_FIELD_H__