• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Protocol Buffers - Google's data interchange format
2 // Copyright 2008, 2024 Google Inc.  All rights reserved.
3 //
4 // Use of this source code is governed by a BSD-style
5 // license that can be found in the LICENSE file or at
6 // https://developers.google.com/open-source/licenses/bsd
7 
8 #include "google/protobuf/repeated_ptr_field.h"
9 
10 #include <algorithm>
11 #include <cstddef>
12 #include <cstdint>
13 #include <cstdlib>
14 #include <cstring>
15 #include <iterator>
16 #include <list>
17 #include <memory>
18 #include <string>
19 #include <type_traits>
20 #include <utility>
21 #include <vector>
22 
23 #include <gmock/gmock.h>
24 #include <gtest/gtest.h>
25 #include "absl/log/absl_check.h"
26 #include "absl/numeric/bits.h"
27 #include "absl/strings/str_cat.h"
28 #include "google/protobuf/arena_test_util.h"
29 #include "google/protobuf/internal_visibility_for_testing.h"
30 #include "google/protobuf/io/coded_stream.h"
31 #include "google/protobuf/unittest.pb.h"
32 
33 
34 // Must be included last.
35 #include "google/protobuf/port_def.inc"
36 
37 namespace google {
38 namespace protobuf {
39 namespace {
40 
41 using ::protobuf_unittest::TestAllTypes;
42 using ::protobuf_unittest::TestMessageWithManyRepeatedPtrFields;
43 using ::testing::A;
44 using ::testing::AllOf;
45 using ::testing::ElementsAre;
46 using ::testing::Ge;
47 using ::testing::Le;
48 
TEST(RepeatedPtrOverPtrsIterator,Traits)49 TEST(RepeatedPtrOverPtrsIterator, Traits) {
50   using It = RepeatedPtrField<std::string>::pointer_iterator;
51   static_assert(std::is_same<It::value_type, std::string*>::value, "");
52   static_assert(std::is_same<It::reference, std::string*&>::value, "");
53   static_assert(std::is_same<It::pointer, std::string**>::value, "");
54   static_assert(std::is_same<It::difference_type, std::ptrdiff_t>::value, "");
55   static_assert(std::is_same<It::iterator_category,
56                              std::random_access_iterator_tag>::value,
57                 "");
58 #if __cplusplus >= 202002L
59   static_assert(
60       std::is_same<It::iterator_concept, std::contiguous_iterator_tag>::value,
61       "");
62 #else
63   static_assert(std::is_same<It::iterator_concept,
64                              std::random_access_iterator_tag>::value,
65                 "");
66 #endif
67 }
68 
69 #ifdef __cpp_lib_to_address
TEST(RepeatedPtrOverPtrsIterator,ToAddress)70 TEST(RepeatedPtrOverPtrsIterator, ToAddress) {
71   // empty container
72   RepeatedPtrField<std::string> field;
73   EXPECT_THAT(std::to_address(field.pointer_begin()), A<std::string**>());
74   EXPECT_EQ(std::to_address(field.pointer_begin()),
75             std::to_address(field.pointer_end()));
76 
77   // "null" iterator
78   using It = RepeatedPtrField<std::string>::pointer_iterator;
79   EXPECT_THAT(std::to_address(It()), A<std::string**>());
80 }
81 #endif
82 
TEST(ConstRepeatedPtrOverPtrsIterator,Traits)83 TEST(ConstRepeatedPtrOverPtrsIterator, Traits) {
84   using It = RepeatedPtrField<std::string>::const_pointer_iterator;
85   static_assert(std::is_same<It::value_type, const std::string*>::value, "");
86   static_assert(std::is_same<It::reference, const std::string* const&>::value,
87                 "");
88   static_assert(std::is_same<It::pointer, const std::string* const*>::value,
89                 "");
90   static_assert(std::is_same<It::difference_type, std::ptrdiff_t>::value, "");
91   static_assert(std::is_same<It::iterator_category,
92                              std::random_access_iterator_tag>::value,
93                 "");
94 #if __cplusplus >= 202002L
95   static_assert(
96       std::is_same<It::iterator_concept, std::contiguous_iterator_tag>::value,
97       "");
98 #else
99   static_assert(std::is_same<It::iterator_concept,
100                              std::random_access_iterator_tag>::value,
101                 "");
102 #endif
103 }
104 
TEST(RepeatedPtrField,MoveAdd)105 TEST(RepeatedPtrField, MoveAdd) {
106   RepeatedPtrField<TestAllTypes> field;
107   TestAllTypes test_all_types;
108   auto* optional_nested_message =
109       test_all_types.mutable_optional_nested_message();
110   optional_nested_message->set_bb(42);
111   field.Add(std::move(test_all_types));
112 
113   EXPECT_EQ(optional_nested_message,
114             field.Mutable(0)->mutable_optional_nested_message());
115 }
116 
TEST(RepeatedPtrField,ConstInit)117 TEST(RepeatedPtrField, ConstInit) {
118   PROTOBUF_CONSTINIT static RepeatedPtrField<std::string> field{};  // NOLINT
119   EXPECT_TRUE(field.empty());
120 }
121 
TEST(RepeatedPtrField,ClearThenReserveMore)122 TEST(RepeatedPtrField, ClearThenReserveMore) {
123   // Test that Reserve properly destroys the old internal array when it's forced
124   // to allocate a new one, even when cleared-but-not-deleted objects are
125   // present. Use a 'string' and > 16 bytes length so that the elements are
126   // non-POD and allocate -- the leak checker will catch any skipped destructor
127   // calls here.
128   RepeatedPtrField<std::string> field;
129   for (int i = 0; i < 32; i++) {
130     *field.Add() = std::string("abcdefghijklmnopqrstuvwxyz0123456789");
131   }
132   EXPECT_EQ(32, field.size());
133   field.Clear();
134   EXPECT_EQ(0, field.size());
135   EXPECT_LE(32, field.Capacity());
136 
137   field.Reserve(1024);
138   EXPECT_EQ(0, field.size());
139   EXPECT_LE(1024, field.Capacity());
140   // Finish test -- |field| should destroy the cleared-but-not-yet-destroyed
141   // strings.
142 }
143 
144 // This helper overload set tests whether X::f can be called with a braced pair,
145 // X::f({a, b}) of std::string iterators (specifically, pointers: That call is
146 // ambiguous if and only if the call to ValidResolutionPointerRange is not.
147 template <typename X>
148 auto ValidResolutionPointerRange(const std::string* p)
149     -> decltype(X::f({p, p + 2}), std::true_type{});
150 template <typename X>
151 std::false_type ValidResolutionPointerRange(void*);
152 
TEST(RepeatedPtrField,UnambiguousConstructor)153 TEST(RepeatedPtrField, UnambiguousConstructor) {
154   struct X {
155     static bool f(std::vector<std::string>) { return false; }
156     static bool f(google::protobuf::RepeatedPtrField<std::string>) { return true; }
157 
158     static bool g(std::vector<int>) { return false; }
159     static bool g(google::protobuf::RepeatedPtrField<std::string>) { return true; }
160   };
161 
162   // RepeatedPtrField has no initializer-list constructor, and a constructor
163   // from to const char* values is excluded by its constraints.
164   EXPECT_FALSE(X::f({"abc", "xyz"}));
165 
166   // Construction from a pair of int* is also not ambiguous.
167   int a[5] = {};
168   EXPECT_FALSE(X::g({a, a + 5}));
169 
170   // Construction from string iterators for the unique string overload "g"
171   // works.
172   // Disabling this for now, this is actually ambiguous with libstdc++.
173   // std::string b[2] = {"abc", "xyz"};
174   // EXPECT_TRUE(X::g({b, b + 2}));
175 
176   // Construction from string iterators for "f" is ambiguous, since both
177   // containers are equally good.
178   //
179   // X::f({b, b + 2});  // error => ValidResolutionPointerRange is unambiguous.
180   EXPECT_FALSE(decltype(ValidResolutionPointerRange<X>(nullptr))::value);
181 }
182 
TEST(RepeatedPtrField,Small)183 TEST(RepeatedPtrField, Small) {
184   RepeatedPtrField<std::string> field;
185 
186   EXPECT_TRUE(field.empty());
187   EXPECT_EQ(field.size(), 0);
188 
189   field.Add()->assign("foo");
190 
191   EXPECT_FALSE(field.empty());
192   EXPECT_EQ(field.size(), 1);
193   EXPECT_EQ(field.Get(0), "foo");
194   EXPECT_EQ(field.at(0), "foo");
195 
196   field.Add()->assign("bar");
197 
198   EXPECT_FALSE(field.empty());
199   EXPECT_EQ(field.size(), 2);
200   EXPECT_EQ(field.Get(0), "foo");
201   EXPECT_EQ(field.at(0), "foo");
202   EXPECT_EQ(field.Get(1), "bar");
203   EXPECT_EQ(field.at(1), "bar");
204 
205   field.Mutable(1)->assign("baz");
206 
207   EXPECT_FALSE(field.empty());
208   EXPECT_EQ(field.size(), 2);
209   EXPECT_EQ(field.Get(0), "foo");
210   EXPECT_EQ(field.at(0), "foo");
211   EXPECT_EQ(field.Get(1), "baz");
212   EXPECT_EQ(field.at(1), "baz");
213 
214   field.RemoveLast();
215 
216   EXPECT_FALSE(field.empty());
217   EXPECT_EQ(field.size(), 1);
218   EXPECT_EQ(field.Get(0), "foo");
219   EXPECT_EQ(field.at(0), "foo");
220 
221   field.Clear();
222 
223   EXPECT_TRUE(field.empty());
224   EXPECT_EQ(field.size(), 0);
225 }
226 
TEST(RepeatedPtrField,Large)227 TEST(RepeatedPtrField, Large) {
228   RepeatedPtrField<std::string> field;
229 
230   for (int i = 0; i < 16; i++) {
231     *field.Add() += 'a' + i;
232   }
233 
234   EXPECT_EQ(field.size(), 16);
235 
236   for (int i = 0; i < 16; i++) {
237     EXPECT_EQ(field.Get(i).size(), 1);
238     EXPECT_EQ(field.Get(i)[0], 'a' + i);
239   }
240 
241   int min_expected_usage = 16 * sizeof(std::string);
242   EXPECT_GE(field.SpaceUsedExcludingSelf(), min_expected_usage);
243 }
244 
245 // TODO: Dedup with the same thing in repeated_field_unittest.cc.
246 template <typename Rep>
CheckAllocationSizes()247 void CheckAllocationSizes() {
248   using T = typename Rep::value_type;
249   // Use a large initial block to make the checks below easier to predict.
250   std::string buf(1 << 20, 0);
251   Arena arena(&buf[0], buf.size());
252   auto* rep = Arena::Create<Rep>(&arena);
253   size_t prev = arena.SpaceUsed();
254 
255   for (int i = 0; i < 100; ++i) {
256     rep->Add(T{});
257     if (sizeof(void*) == 8) {
258       // For `RepeatedPtrField`, we also allocate the T on the arena.
259       // Subtract those from the count.
260       size_t new_used = arena.SpaceUsed() - (sizeof(T) * (i + 1));
261       size_t last_alloc = new_used - prev;
262       prev = new_used;
263 
264       // When we actually allocated something, check the size.
265       if (last_alloc != 0) {
266         // Must be `>= 16`, as expected by the Arena.
267         ASSERT_GE(last_alloc, 16);
268         // Must be of a power of two.
269         size_t log2 = absl::bit_width(last_alloc) - 1;
270         ASSERT_EQ((1 << log2), last_alloc);
271       }
272 
273       // The byte size must be a multiple of 8 when not SOO.
274       const int capacity_bytes = rep->Capacity() * sizeof(T);
275       if (capacity_bytes > internal::kSooCapacityBytes) {
276         ASSERT_EQ(capacity_bytes % 8, 0);
277       }
278     }
279   }
280 }
281 
TEST(RepeatedPtrField,ArenaAllocationSizesMatchExpectedValues)282 TEST(RepeatedPtrField, ArenaAllocationSizesMatchExpectedValues) {
283   EXPECT_NO_FATAL_FAILURE(
284       CheckAllocationSizes<RepeatedPtrField<std::string>>());
285 }
286 
TEST(RepeatedPtrField,NaturalGrowthOnArenasReuseBlocks)287 TEST(RepeatedPtrField, NaturalGrowthOnArenasReuseBlocks) {
288   using Rep = RepeatedPtrField<std::string>;
289   Arena arena;
290   std::vector<Rep*> values;
291 
292   static constexpr int kNumFields = 100;
293   static constexpr int kNumElems = 1000;
294   for (int i = 0; i < kNumFields; ++i) {
295     values.push_back(Arena::Create<Rep>(&arena));
296     auto& field = *values.back();
297     for (int j = 0; j < kNumElems; ++j) {
298       field.Add("");
299     }
300   }
301 
302   size_t expected =
303       values.size() * values[0]->Capacity() * sizeof(std::string*) +
304       sizeof(std::string) * kNumElems * kNumFields;
305   // Use a 2% slack for other overhead.
306   // If we were not reusing the blocks, the actual value would be ~2x the
307   // expected.
308   EXPECT_THAT(arena.SpaceUsed(), AllOf(Ge(expected), Le(1.02 * expected)));
309 }
310 
TEST(RepeatedPtrField,AddAndAssignRanges)311 TEST(RepeatedPtrField, AddAndAssignRanges) {
312   RepeatedPtrField<std::string> field;
313 
314   const char* vals[] = {"abc", "x", "yz", "xyzzy"};
315   field.Assign(std::begin(vals), std::end(vals));
316 
317   ASSERT_EQ(field.size(), 4);
318   EXPECT_EQ(field.Get(0), "abc");
319   EXPECT_EQ(field.Get(1), "x");
320   EXPECT_EQ(field.Get(2), "yz");
321   EXPECT_EQ(field.Get(3), "xyzzy");
322 
323   field.Add(std::begin(vals), std::end(vals));
324   ASSERT_EQ(field.size(), 8);
325   EXPECT_EQ(field.Get(0), "abc");
326   EXPECT_EQ(field.Get(1), "x");
327   EXPECT_EQ(field.Get(2), "yz");
328   EXPECT_EQ(field.Get(3), "xyzzy");
329   EXPECT_EQ(field.Get(4), "abc");
330   EXPECT_EQ(field.Get(5), "x");
331   EXPECT_EQ(field.Get(6), "yz");
332   EXPECT_EQ(field.Get(7), "xyzzy");
333 }
334 
TEST(RepeatedPtrField,SwapSmallSmall)335 TEST(RepeatedPtrField, SwapSmallSmall) {
336   RepeatedPtrField<std::string> field1;
337   RepeatedPtrField<std::string> field2;
338 
339   EXPECT_TRUE(field1.empty());
340   EXPECT_EQ(field1.size(), 0);
341   EXPECT_TRUE(field2.empty());
342   EXPECT_EQ(field2.size(), 0);
343 
344   field1.Add()->assign("foo");
345   field1.Add()->assign("bar");
346 
347   EXPECT_FALSE(field1.empty());
348   EXPECT_EQ(field1.size(), 2);
349   EXPECT_EQ(field1.Get(0), "foo");
350   EXPECT_EQ(field1.Get(1), "bar");
351 
352   EXPECT_TRUE(field2.empty());
353   EXPECT_EQ(field2.size(), 0);
354 
355   field1.Swap(&field2);
356 
357   EXPECT_TRUE(field1.empty());
358   EXPECT_EQ(field1.size(), 0);
359 
360   EXPECT_EQ(field2.size(), 2);
361   EXPECT_EQ(field2.Get(0), "foo");
362   EXPECT_EQ(field2.Get(1), "bar");
363 }
364 
TEST(RepeatedPtrField,SwapLargeSmall)365 TEST(RepeatedPtrField, SwapLargeSmall) {
366   RepeatedPtrField<std::string> field1;
367   RepeatedPtrField<std::string> field2;
368 
369   field2.Add()->assign("foo");
370   field2.Add()->assign("bar");
371   for (int i = 0; i < 16; i++) {
372     *field1.Add() += 'a' + i;
373   }
374   field1.Swap(&field2);
375 
376   EXPECT_EQ(field1.size(), 2);
377   EXPECT_EQ(field1.Get(0), "foo");
378   EXPECT_EQ(field1.Get(1), "bar");
379   EXPECT_EQ(field2.size(), 16);
380   for (int i = 0; i < 16; i++) {
381     EXPECT_EQ(field2.Get(i).size(), 1);
382     EXPECT_EQ(field2.Get(i)[0], 'a' + i);
383   }
384 }
385 
TEST(RepeatedPtrField,SwapLargeLarge)386 TEST(RepeatedPtrField, SwapLargeLarge) {
387   RepeatedPtrField<std::string> field1;
388   RepeatedPtrField<std::string> field2;
389 
390   field1.Add()->assign("foo");
391   field1.Add()->assign("bar");
392   for (int i = 0; i < 16; i++) {
393     *field1.Add() += 'A' + i;
394     *field2.Add() += 'a' + i;
395   }
396   field2.Swap(&field1);
397 
398   EXPECT_EQ(field1.size(), 16);
399   for (int i = 0; i < 16; i++) {
400     EXPECT_EQ(field1.Get(i).size(), 1);
401     EXPECT_EQ(field1.Get(i)[0], 'a' + i);
402   }
403   EXPECT_EQ(field2.size(), 18);
404   EXPECT_EQ(field2.Get(0), "foo");
405   EXPECT_EQ(field2.Get(1), "bar");
406   for (int i = 2; i < 18; i++) {
407     EXPECT_EQ(field2.Get(i).size(), 1);
408     EXPECT_EQ(field2.Get(i)[0], 'A' + i - 2);
409   }
410 }
411 
ReservedSpace(RepeatedPtrField<std::string> * field)412 static int ReservedSpace(RepeatedPtrField<std::string>* field) {
413   const std::string* const* ptr = field->data();
414   do {
415     field->Add();
416   } while (field->data() == ptr);
417 
418   return field->size() - 1;
419 }
420 
TEST(RepeatedPtrField,ReserveMoreThanDouble)421 TEST(RepeatedPtrField, ReserveMoreThanDouble) {
422   RepeatedPtrField<std::string> field;
423   field.Reserve(20);
424 
425   EXPECT_LE(20, ReservedSpace(&field));
426 }
427 
TEST(RepeatedPtrField,ReserveLessThanDouble)428 TEST(RepeatedPtrField, ReserveLessThanDouble) {
429   RepeatedPtrField<std::string> field;
430   field.Reserve(20);
431 
432   int capacity = field.Capacity();
433   // Grow by 1.5x
434   field.Reserve(capacity + (capacity >> 2));
435 
436   EXPECT_LE(2 * capacity, ReservedSpace(&field));
437 }
438 
TEST(RepeatedPtrField,ReserveLessThanExisting)439 TEST(RepeatedPtrField, ReserveLessThanExisting) {
440   RepeatedPtrField<std::string> field;
441   field.Reserve(20);
442   const std::string* const* previous_ptr = field.data();
443   field.Reserve(10);
444 
445   EXPECT_EQ(previous_ptr, field.data());
446   EXPECT_LE(20, ReservedSpace(&field));
447 }
448 
TEST(RepeatedPtrField,ReserveDoesntLoseAllocated)449 TEST(RepeatedPtrField, ReserveDoesntLoseAllocated) {
450   // Check that a bug is fixed:  An earlier implementation of Reserve()
451   // failed to copy pointers to allocated-but-cleared objects, possibly
452   // leading to segfaults.
453   RepeatedPtrField<std::string> field;
454   std::string* first = field.Add();
455   field.RemoveLast();
456 
457   field.Reserve(20);
458   EXPECT_EQ(first, field.Add());
459 }
460 
461 // Clearing elements is tricky with RepeatedPtrFields since the memory for
462 // the elements is retained and reused.
TEST(RepeatedPtrField,ClearedElements)463 TEST(RepeatedPtrField, ClearedElements) {
464   PROTOBUF_IGNORE_DEPRECATION_START
465   RepeatedPtrField<std::string> field;
466 
467   std::string* original = field.Add();
468   *original = "foo";
469 
470   EXPECT_EQ(field.ClearedCount(), 0);
471 
472   field.RemoveLast();
473   EXPECT_TRUE(original->empty());
474   EXPECT_EQ(field.ClearedCount(), 1);
475 
476   EXPECT_EQ(field.Add(),
477             original);  // Should return same string for reuse.
478   EXPECT_EQ(field.UnsafeArenaReleaseLast(), original);  // We take ownership.
479   EXPECT_EQ(field.ClearedCount(), 0);
480 
481   EXPECT_NE(field.Add(), original);  // Should NOT return the same string.
482   EXPECT_EQ(field.ClearedCount(), 0);
483 
484   field.UnsafeArenaAddAllocated(original);  // Give ownership back.
485   EXPECT_EQ(field.ClearedCount(), 0);
486   EXPECT_EQ(field.Mutable(1), original);
487 
488   field.Clear();
489   EXPECT_EQ(field.ClearedCount(), 2);
490   PROTOBUF_IGNORE_DEPRECATION_STOP
491 }
492 
493 // Test all code paths in AddAllocated().
TEST(RepeatedPtrField,AddAllocated)494 TEST(RepeatedPtrField, AddAllocated) {
495   RepeatedPtrField<std::string> field;
496   while (field.size() < field.Capacity()) {
497     field.Add()->assign("filler");
498   }
499 
500   const auto ensure_at_capacity = [&] {
501     while (field.size() < field.Capacity()) {
502       field.Add()->assign("filler");
503     }
504   };
505   const auto ensure_not_at_capacity = [&] { field.Reserve(field.size() + 1); };
506 
507   ensure_at_capacity();
508   int index = field.size();
509 
510   // First branch:  Field is at capacity with no cleared objects.
511   ASSERT_EQ(field.size(), field.Capacity());
512   std::string* foo = new std::string("foo");
513   field.AddAllocated(foo);
514   EXPECT_EQ(index + 1, field.size());
515   EXPECT_EQ(0, field.ClearedCount());
516   EXPECT_EQ(foo, &field.Get(index));
517 
518   // Last branch:  Field is not at capacity and there are no cleared objects.
519   ensure_not_at_capacity();
520   std::string* bar = new std::string("bar");
521   field.AddAllocated(bar);
522   ++index;
523   EXPECT_EQ(index + 1, field.size());
524   EXPECT_EQ(0, field.ClearedCount());
525   EXPECT_EQ(bar, &field.Get(index));
526 
527   // Third branch:  Field is not at capacity and there are no cleared objects.
528   ensure_not_at_capacity();
529   field.RemoveLast();
530   std::string* baz = new std::string("baz");
531   field.AddAllocated(baz);
532   EXPECT_EQ(index + 1, field.size());
533   EXPECT_EQ(1, field.ClearedCount());
534   EXPECT_EQ(baz, &field.Get(index));
535 
536   // Second branch:  Field is at capacity but has some cleared objects.
537   ensure_at_capacity();
538   field.RemoveLast();
539   index = field.size();
540   std::string* moo = new std::string("moo");
541   field.AddAllocated(moo);
542   EXPECT_EQ(index + 1, field.size());
543   // We should have discarded the cleared object.
544   EXPECT_EQ(0, field.ClearedCount());
545   EXPECT_EQ(moo, &field.Get(index));
546 }
547 
TEST(RepeatedPtrField,AddMethodsDontAcceptNull)548 TEST(RepeatedPtrField, AddMethodsDontAcceptNull) {
549 #if !defined(NDEBUG)
550   RepeatedPtrField<std::string> field;
551   EXPECT_DEATH(field.AddAllocated(nullptr), "nullptr");
552   EXPECT_DEATH(field.UnsafeArenaAddAllocated(nullptr), "nullptr");
553 #endif
554 }
555 
TEST(RepeatedPtrField,AddAllocatedDifferentArena)556 TEST(RepeatedPtrField, AddAllocatedDifferentArena) {
557   RepeatedPtrField<TestAllTypes> field;
558   Arena arena;
559   auto* msg = Arena::Create<TestAllTypes>(&arena);
560   field.AddAllocated(msg);
561 }
562 
TEST(RepeatedPtrField,MergeFrom)563 TEST(RepeatedPtrField, MergeFrom) {
564   RepeatedPtrField<std::string> source, destination;
565   source.Add()->assign("4");
566   source.Add()->assign("5");
567   destination.Add()->assign("1");
568   destination.Add()->assign("2");
569   destination.Add()->assign("3");
570 
571   destination.MergeFrom(source);
572 
573   ASSERT_EQ(5, destination.size());
574   EXPECT_EQ("1", destination.Get(0));
575   EXPECT_EQ("2", destination.Get(1));
576   EXPECT_EQ("3", destination.Get(2));
577   EXPECT_EQ("4", destination.Get(3));
578   EXPECT_EQ("5", destination.Get(4));
579 }
580 
581 
TEST(RepeatedPtrField,CopyFrom)582 TEST(RepeatedPtrField, CopyFrom) {
583   RepeatedPtrField<std::string> source, destination;
584   source.Add()->assign("4");
585   source.Add()->assign("5");
586   destination.Add()->assign("1");
587   destination.Add()->assign("2");
588   destination.Add()->assign("3");
589 
590   destination.CopyFrom(source);
591 
592   ASSERT_EQ(2, destination.size());
593   EXPECT_EQ("4", destination.Get(0));
594   EXPECT_EQ("5", destination.Get(1));
595 }
596 
TEST(RepeatedPtrField,CopyFromSelf)597 TEST(RepeatedPtrField, CopyFromSelf) {
598   RepeatedPtrField<std::string> me;
599   me.Add()->assign("1");
600   me.CopyFrom(me);
601   ASSERT_EQ(1, me.size());
602   EXPECT_EQ("1", me.Get(0));
603 }
604 
TEST(RepeatedPtrField,Erase)605 TEST(RepeatedPtrField, Erase) {
606   RepeatedPtrField<std::string> me;
607   RepeatedPtrField<std::string>::iterator it = me.erase(me.begin(), me.end());
608   EXPECT_TRUE(me.begin() == it);
609   EXPECT_EQ(0, me.size());
610 
611   *me.Add() = "1";
612   *me.Add() = "2";
613   *me.Add() = "3";
614   it = me.erase(me.begin(), me.end());
615   EXPECT_TRUE(me.begin() == it);
616   EXPECT_EQ(0, me.size());
617 
618   *me.Add() = "4";
619   *me.Add() = "5";
620   *me.Add() = "6";
621   it = me.erase(me.begin() + 2, me.end());
622   EXPECT_TRUE(me.begin() + 2 == it);
623   EXPECT_EQ(2, me.size());
624   EXPECT_EQ("4", me.Get(0));
625   EXPECT_EQ("5", me.Get(1));
626 
627   *me.Add() = "6";
628   *me.Add() = "7";
629   *me.Add() = "8";
630   it = me.erase(me.begin() + 1, me.begin() + 3);
631   EXPECT_TRUE(me.begin() + 1 == it);
632   EXPECT_EQ(3, me.size());
633   EXPECT_EQ("4", me.Get(0));
634   EXPECT_EQ("7", me.Get(1));
635   EXPECT_EQ("8", me.Get(2));
636 }
637 
TEST(RepeatedPtrField,CopyConstruct)638 TEST(RepeatedPtrField, CopyConstruct) {
639   auto token = internal::InternalVisibilityForTesting{};
640   RepeatedPtrField<std::string> source;
641   source.Add()->assign("1");
642   source.Add()->assign("2");
643 
644   RepeatedPtrField<std::string> destination1(source);
645   ASSERT_EQ(2, destination1.size());
646   EXPECT_EQ("1", destination1.Get(0));
647   EXPECT_EQ("2", destination1.Get(1));
648 
649   RepeatedPtrField<std::string> destination2(token, nullptr, source);
650   ASSERT_EQ(2, destination2.size());
651   EXPECT_EQ("1", destination2.Get(0));
652   EXPECT_EQ("2", destination2.Get(1));
653 }
654 
TEST(RepeatedPtrField,CopyConstructWithArena)655 TEST(RepeatedPtrField, CopyConstructWithArena) {
656   auto token = internal::InternalVisibilityForTesting{};
657   RepeatedPtrField<std::string> source;
658   source.Add()->assign("1");
659   source.Add()->assign("2");
660 
661   Arena arena;
662   RepeatedPtrField<std::string> destination(token, &arena, source);
663   ASSERT_EQ(2, destination.size());
664   EXPECT_EQ("1", destination.Get(0));
665   EXPECT_EQ("2", destination.Get(1));
666 }
667 
TEST(RepeatedPtrField,IteratorConstruct_String)668 TEST(RepeatedPtrField, IteratorConstruct_String) {
669   std::vector<std::string> values;
670   values.push_back("1");
671   values.push_back("2");
672 
673   RepeatedPtrField<std::string> field(values.begin(), values.end());
674   ASSERT_EQ(values.size(), field.size());
675   EXPECT_EQ(values[0], field.Get(0));
676   EXPECT_EQ(values[1], field.Get(1));
677 
678   RepeatedPtrField<std::string> other(field.begin(), field.end());
679   ASSERT_EQ(values.size(), other.size());
680   EXPECT_EQ(values[0], other.Get(0));
681   EXPECT_EQ(values[1], other.Get(1));
682 }
683 
TEST(RepeatedPtrField,IteratorConstruct_Proto)684 TEST(RepeatedPtrField, IteratorConstruct_Proto) {
685   typedef TestAllTypes::NestedMessage Nested;
686   std::vector<Nested> values;
687   values.push_back(Nested());
688   values.back().set_bb(1);
689   values.push_back(Nested());
690   values.back().set_bb(2);
691 
692   RepeatedPtrField<Nested> field(values.begin(), values.end());
693   ASSERT_EQ(values.size(), field.size());
694   EXPECT_EQ(values[0].bb(), field.Get(0).bb());
695   EXPECT_EQ(values[1].bb(), field.Get(1).bb());
696 
697   RepeatedPtrField<Nested> other(field.begin(), field.end());
698   ASSERT_EQ(values.size(), other.size());
699   EXPECT_EQ(values[0].bb(), other.Get(0).bb());
700   EXPECT_EQ(values[1].bb(), other.Get(1).bb());
701 }
702 
TEST(RepeatedPtrField,SmallOptimization)703 TEST(RepeatedPtrField, SmallOptimization) {
704   // Properties checked here are not part of the contract of RepeatedPtrField,
705   // but we test them to verify that SSO is working as expected by the
706   // implementation.
707 
708   // We use an arena to easily measure memory usage, but not needed.
709   Arena arena;
710   auto* array = Arena::Create<RepeatedPtrField<std::string>>(&arena);
711   EXPECT_EQ(array->Capacity(), 1);
712   EXPECT_EQ(array->SpaceUsedExcludingSelf(), 0);
713   std::string str;
714   auto usage_before = arena.SpaceUsed();
715   // We use UnsafeArenaAddAllocated just to grow the array without creating
716   // objects or causing extra cleanup costs in the arena to make the
717   // measurements simpler.
718   array->UnsafeArenaAddAllocated(&str);
719   // No backing array, just the string.
720   EXPECT_EQ(array->SpaceUsedExcludingSelf(), sizeof(str));
721   // We have not used any arena space.
722   EXPECT_EQ(usage_before, arena.SpaceUsed());
723   // Verify the string is where we think it is.
724   EXPECT_EQ(&*array->begin(), &str);
725   EXPECT_EQ(array->pointer_begin()[0], &str);
726   auto is_inlined = [array]() {
727     return std::less_equal<void*>{}(array, &*array->pointer_begin()) &&
728            std::less<void*>{}(&*array->pointer_begin(), array + 1);
729   };
730   // The T** in pointer_begin points into the sso in the object.
731   EXPECT_TRUE(is_inlined());
732 
733   // Adding a second object stops sso.
734   std::string str2;
735   array->UnsafeArenaAddAllocated(&str2);
736   EXPECT_EQ(array->Capacity(), 3);
737   // Backing array and the strings.
738   EXPECT_EQ(array->SpaceUsedExcludingSelf(),
739             (1 + array->Capacity()) * sizeof(void*) + 2 * sizeof(str));
740   // We used some arena space now.
741   EXPECT_LT(usage_before, arena.SpaceUsed());
742   // And the pointer_begin is not in the sso anymore.
743   EXPECT_FALSE(is_inlined());
744 }
745 
TEST(RepeatedPtrField,CopyAssign)746 TEST(RepeatedPtrField, CopyAssign) {
747   RepeatedPtrField<std::string> source, destination;
748   source.Add()->assign("4");
749   source.Add()->assign("5");
750   destination.Add()->assign("1");
751   destination.Add()->assign("2");
752   destination.Add()->assign("3");
753 
754   destination = source;
755 
756   ASSERT_EQ(2, destination.size());
757   EXPECT_EQ("4", destination.Get(0));
758   EXPECT_EQ("5", destination.Get(1));
759 }
760 
TEST(RepeatedPtrField,SelfAssign)761 TEST(RepeatedPtrField, SelfAssign) {
762   // Verify that assignment to self does not destroy data.
763   RepeatedPtrField<std::string> source, *p;
764   p = &source;
765   source.Add()->assign("7");
766   source.Add()->assign("8");
767 
768   *p = source;
769 
770   ASSERT_EQ(2, source.size());
771   EXPECT_EQ("7", source.Get(0));
772   EXPECT_EQ("8", source.Get(1));
773 }
774 
TEST(RepeatedPtrField,MoveConstruct)775 TEST(RepeatedPtrField, MoveConstruct) {
776   {
777     RepeatedPtrField<std::string> source;
778     *source.Add() = "1";
779     *source.Add() = "2";
780     const std::string* const* data = source.data();
781     RepeatedPtrField<std::string> destination = std::move(source);
782     EXPECT_EQ(data, destination.data());
783     EXPECT_THAT(destination, ElementsAre("1", "2"));
784     // This property isn't guaranteed but it's useful to have a test that would
785     // catch changes in this area.
786     EXPECT_TRUE(source.empty());
787   }
788   {
789     Arena arena;
790     RepeatedPtrField<std::string>* source =
791         Arena::Create<RepeatedPtrField<std::string>>(&arena);
792     *source->Add() = "1";
793     *source->Add() = "2";
794     RepeatedPtrField<std::string> destination = std::move(*source);
795     EXPECT_EQ(nullptr, destination.GetArena());
796     EXPECT_THAT(destination, ElementsAre("1", "2"));
797     // This property isn't guaranteed but it's useful to have a test that would
798     // catch changes in this area.
799     EXPECT_THAT(*source, ElementsAre("1", "2"));
800   }
801 }
802 
TEST(RepeatedPtrField,MoveAssign)803 TEST(RepeatedPtrField, MoveAssign) {
804   {
805     RepeatedPtrField<std::string> source;
806     *source.Add() = "1";
807     *source.Add() = "2";
808     RepeatedPtrField<std::string> destination;
809     *destination.Add() = "3";
810     const std::string* const* source_data = source.data();
811     destination = std::move(source);
812     EXPECT_EQ(source_data, destination.data());
813     EXPECT_THAT(destination, ElementsAre("1", "2"));
814     EXPECT_THAT(source, ElementsAre("3"));
815   }
816   {
817     Arena arena;
818     RepeatedPtrField<std::string>* source =
819         Arena::Create<RepeatedPtrField<std::string>>(&arena);
820     *source->Add() = "1";
821     *source->Add() = "2";
822     RepeatedPtrField<std::string>* destination =
823         Arena::Create<RepeatedPtrField<std::string>>(&arena);
824     *destination->Add() = "3";
825     const std::string* const* source_data = source->data();
826     *destination = std::move(*source);
827     EXPECT_EQ(source_data, destination->data());
828     EXPECT_THAT(*destination, ElementsAre("1", "2"));
829     EXPECT_THAT(*source, ElementsAre("3"));
830   }
831   {
832     Arena source_arena;
833     RepeatedPtrField<std::string>* source =
834         Arena::Create<RepeatedPtrField<std::string>>(&source_arena);
835     *source->Add() = "1";
836     *source->Add() = "2";
837     Arena destination_arena;
838     RepeatedPtrField<std::string>* destination =
839         Arena::Create<RepeatedPtrField<std::string>>(&destination_arena);
840     *destination->Add() = "3";
841     *destination = std::move(*source);
842     EXPECT_THAT(*destination, ElementsAre("1", "2"));
843     // This property isn't guaranteed but it's useful to have a test that would
844     // catch changes in this area.
845     EXPECT_THAT(*source, ElementsAre("1", "2"));
846   }
847   {
848     Arena arena;
849     RepeatedPtrField<std::string>* source =
850         Arena::Create<RepeatedPtrField<std::string>>(&arena);
851     *source->Add() = "1";
852     *source->Add() = "2";
853     RepeatedPtrField<std::string> destination;
854     *destination.Add() = "3";
855     destination = std::move(*source);
856     EXPECT_THAT(destination, ElementsAre("1", "2"));
857     // This property isn't guaranteed but it's useful to have a test that would
858     // catch changes in this area.
859     EXPECT_THAT(*source, ElementsAre("1", "2"));
860   }
861   {
862     RepeatedPtrField<std::string> source;
863     *source.Add() = "1";
864     *source.Add() = "2";
865     Arena arena;
866     RepeatedPtrField<std::string>* destination =
867         Arena::Create<RepeatedPtrField<std::string>>(&arena);
868     *destination->Add() = "3";
869     *destination = std::move(source);
870     EXPECT_THAT(*destination, ElementsAre("1", "2"));
871     // This property isn't guaranteed but it's useful to have a test that would
872     // catch changes in this area.
873     EXPECT_THAT(source, ElementsAre("1", "2"));
874   }
875   {
876     RepeatedPtrField<std::string> field;
877     // An alias to defeat -Wself-move.
878     RepeatedPtrField<std::string>& alias = field;
879     *field.Add() = "1";
880     *field.Add() = "2";
881     const std::string* const* data = field.data();
882     field = std::move(alias);
883     EXPECT_EQ(data, field.data());
884     EXPECT_THAT(field, ElementsAre("1", "2"));
885   }
886   {
887     Arena arena;
888     RepeatedPtrField<std::string>* field =
889         Arena::Create<RepeatedPtrField<std::string>>(&arena);
890     *field->Add() = "1";
891     *field->Add() = "2";
892     const std::string* const* data = field->data();
893     *field = std::move(*field);
894     EXPECT_EQ(data, field->data());
895     EXPECT_THAT(*field, ElementsAre("1", "2"));
896   }
897 }
898 
TEST(RepeatedPtrField,MutableDataIsMutable)899 TEST(RepeatedPtrField, MutableDataIsMutable) {
900   RepeatedPtrField<std::string> field;
901   *field.Add() = "1";
902   EXPECT_EQ("1", field.Get(0));
903   // The fact that this line compiles would be enough, but we'll check the
904   // value anyway.
905   std::string** data = field.mutable_data();
906   **data = "2";
907   EXPECT_EQ("2", field.Get(0));
908 }
909 
TEST(RepeatedPtrField,SubscriptOperators)910 TEST(RepeatedPtrField, SubscriptOperators) {
911   RepeatedPtrField<std::string> field;
912   *field.Add() = "1";
913   EXPECT_EQ("1", field.Get(0));
914   EXPECT_EQ("1", field[0]);
915   EXPECT_EQ(field.Mutable(0), &field[0]);
916   const RepeatedPtrField<std::string>& const_field = field;
917   EXPECT_EQ(*field.data(), &const_field[0]);
918 }
919 
TEST(RepeatedPtrField,ExtractSubrange)920 TEST(RepeatedPtrField, ExtractSubrange) {
921   // Exhaustively test every subrange in arrays of all sizes from 0 through 9
922   // with 0 through 3 cleared elements at the end.
923   for (int sz = 0; sz < 10; ++sz) {
924     for (int num = 0; num <= sz; ++num) {
925       for (int start = 0; start < sz - num; ++start) {
926         for (int extra = 0; extra < 4; ++extra) {
927           std::vector<std::string*> subject;
928 
929           // Create an array with "sz" elements and "extra" cleared elements.
930           // Use an arena to avoid copies from debug-build stability checks.
931           Arena arena;
932           auto& field = *Arena::Create<RepeatedPtrField<std::string>>(&arena);
933           for (int i = 0; i < sz + extra; ++i) {
934             subject.push_back(new std::string());
935             field.AddAllocated(subject[i]);
936           }
937           EXPECT_EQ(field.size(), sz + extra);
938           for (int i = 0; i < extra; ++i) field.RemoveLast();
939           EXPECT_EQ(field.size(), sz);
940           EXPECT_EQ(field.ClearedCount(), extra);
941 
942           // Create a catcher array and call ExtractSubrange.
943           std::string* catcher[10];
944           for (int i = 0; i < 10; ++i) catcher[i] = nullptr;
945           field.ExtractSubrange(start, num, catcher);
946 
947           // Does the resulting array have the right size?
948           EXPECT_EQ(field.size(), sz - num);
949 
950           // Were the removed elements extracted into the catcher array?
951           for (int i = 0; i < num; ++i)
952             EXPECT_EQ(*catcher[i], *subject[start + i]);
953           EXPECT_EQ(nullptr, catcher[num]);
954 
955           // Does the resulting array contain the right values?
956           for (int i = 0; i < start; ++i)
957             EXPECT_EQ(field.Mutable(i), subject[i]);
958           for (int i = start; i < field.size(); ++i)
959             EXPECT_EQ(field.Mutable(i), subject[i + num]);
960 
961           // Reinstate the cleared elements.
962           EXPECT_EQ(field.ClearedCount(), extra);
963           for (int i = 0; i < extra; ++i) field.Add();
964           EXPECT_EQ(field.ClearedCount(), 0);
965           EXPECT_EQ(field.size(), sz - num + extra);
966 
967           // Make sure the extra elements are all there (in some order).
968           for (int i = sz; i < sz + extra; ++i) {
969             int count = 0;
970             for (int j = sz; j < sz + extra; ++j) {
971               if (field.Mutable(j - num) == subject[i]) count += 1;
972             }
973             EXPECT_EQ(count, 1);
974           }
975 
976           // Release the caught elements.
977           for (int i = 0; i < num; ++i) delete catcher[i];
978         }
979       }
980     }
981   }
982 }
983 
TEST(RepeatedPtrField,DeleteSubrange)984 TEST(RepeatedPtrField, DeleteSubrange) {
985   // DeleteSubrange is a trivial extension of ExtendSubrange.
986 }
987 
TEST(RepeatedPtrField,Cleanups)988 TEST(RepeatedPtrField, Cleanups) {
989   Arena arena;
990   auto growth = internal::CleanupGrowth(
991       arena, [&] { Arena::Create<RepeatedPtrField<std::string>>(&arena); });
992   EXPECT_THAT(growth.cleanups, testing::IsEmpty());
993 
994   growth = internal::CleanupGrowth(
995       arena, [&] { Arena::Create<RepeatedPtrField<TestAllTypes>>(&arena); });
996   EXPECT_THAT(growth.cleanups, testing::IsEmpty());
997 }
998 
999 
1000 // ===================================================================
1001 
1002 class RepeatedPtrFieldIteratorTest : public testing::Test {
1003  protected:
SetUp()1004   void SetUp() override {
1005     proto_array_.Add()->assign("foo");
1006     proto_array_.Add()->assign("bar");
1007     proto_array_.Add()->assign("baz");
1008   }
1009 
1010   RepeatedPtrField<std::string> proto_array_;
1011 };
1012 
TEST_F(RepeatedPtrFieldIteratorTest,Convertible)1013 TEST_F(RepeatedPtrFieldIteratorTest, Convertible) {
1014   RepeatedPtrField<std::string>::iterator iter = proto_array_.begin();
1015   RepeatedPtrField<std::string>::const_iterator c_iter = iter;
1016   RepeatedPtrField<std::string>::value_type value = *c_iter;
1017   EXPECT_EQ("foo", value);
1018 }
1019 
TEST_F(RepeatedPtrFieldIteratorTest,MutableIteration)1020 TEST_F(RepeatedPtrFieldIteratorTest, MutableIteration) {
1021   RepeatedPtrField<std::string>::iterator iter = proto_array_.begin();
1022   EXPECT_EQ("foo", *iter);
1023   ++iter;
1024   EXPECT_EQ("bar", *(iter++));
1025   EXPECT_EQ("baz", *iter);
1026   ++iter;
1027   EXPECT_TRUE(proto_array_.end() == iter);
1028   EXPECT_EQ("baz", *(--proto_array_.end()));
1029 }
1030 
TEST_F(RepeatedPtrFieldIteratorTest,ConstIteration)1031 TEST_F(RepeatedPtrFieldIteratorTest, ConstIteration) {
1032   const RepeatedPtrField<std::string>& const_proto_array = proto_array_;
1033   RepeatedPtrField<std::string>::const_iterator iter =
1034       const_proto_array.begin();
1035   iter - const_proto_array.cbegin();
1036   EXPECT_EQ("foo", *iter);
1037   ++iter;
1038   EXPECT_EQ("bar", *(iter++));
1039   EXPECT_EQ("baz", *iter);
1040   ++iter;
1041   EXPECT_TRUE(const_proto_array.end() == iter);
1042   EXPECT_EQ("baz", *(--const_proto_array.end()));
1043 }
1044 
TEST_F(RepeatedPtrFieldIteratorTest,MutableReverseIteration)1045 TEST_F(RepeatedPtrFieldIteratorTest, MutableReverseIteration) {
1046   RepeatedPtrField<std::string>::reverse_iterator iter = proto_array_.rbegin();
1047   EXPECT_EQ("baz", *iter);
1048   ++iter;
1049   EXPECT_EQ("bar", *(iter++));
1050   EXPECT_EQ("foo", *iter);
1051   ++iter;
1052   EXPECT_TRUE(proto_array_.rend() == iter);
1053   EXPECT_EQ("foo", *(--proto_array_.rend()));
1054 }
1055 
TEST_F(RepeatedPtrFieldIteratorTest,ConstReverseIteration)1056 TEST_F(RepeatedPtrFieldIteratorTest, ConstReverseIteration) {
1057   const RepeatedPtrField<std::string>& const_proto_array = proto_array_;
1058   RepeatedPtrField<std::string>::const_reverse_iterator iter =
1059       const_proto_array.rbegin();
1060   EXPECT_EQ("baz", *iter);
1061   ++iter;
1062   EXPECT_EQ("bar", *(iter++));
1063   EXPECT_EQ("foo", *iter);
1064   ++iter;
1065   EXPECT_TRUE(const_proto_array.rend() == iter);
1066   EXPECT_EQ("foo", *(--const_proto_array.rend()));
1067 }
1068 
TEST_F(RepeatedPtrFieldIteratorTest,RandomAccess)1069 TEST_F(RepeatedPtrFieldIteratorTest, RandomAccess) {
1070   RepeatedPtrField<std::string>::iterator iter = proto_array_.begin();
1071   RepeatedPtrField<std::string>::iterator iter2 = iter;
1072   ++iter2;
1073   ++iter2;
1074   EXPECT_TRUE(iter + 2 == iter2);
1075   EXPECT_TRUE(iter == iter2 - 2);
1076   EXPECT_EQ("baz", iter[2]);
1077   EXPECT_EQ("baz", *(iter + 2));
1078   EXPECT_EQ(3, proto_array_.end() - proto_array_.begin());
1079 }
1080 
TEST_F(RepeatedPtrFieldIteratorTest,RandomAccessConst)1081 TEST_F(RepeatedPtrFieldIteratorTest, RandomAccessConst) {
1082   RepeatedPtrField<std::string>::const_iterator iter = proto_array_.cbegin();
1083   RepeatedPtrField<std::string>::const_iterator iter2 = iter;
1084   ++iter2;
1085   ++iter2;
1086   EXPECT_TRUE(iter + 2 == iter2);
1087   EXPECT_TRUE(iter == iter2 - 2);
1088   EXPECT_EQ("baz", iter[2]);
1089   EXPECT_EQ("baz", *(iter + 2));
1090   EXPECT_EQ(3, proto_array_.cend() - proto_array_.cbegin());
1091 }
1092 
TEST_F(RepeatedPtrFieldIteratorTest,DifferenceConstConversion)1093 TEST_F(RepeatedPtrFieldIteratorTest, DifferenceConstConversion) {
1094   EXPECT_EQ(3, proto_array_.end() - proto_array_.cbegin());
1095   EXPECT_EQ(3, proto_array_.cend() - proto_array_.begin());
1096 }
1097 
TEST_F(RepeatedPtrFieldIteratorTest,Comparable)1098 TEST_F(RepeatedPtrFieldIteratorTest, Comparable) {
1099   RepeatedPtrField<std::string>::const_iterator iter = proto_array_.begin();
1100   RepeatedPtrField<std::string>::const_iterator iter2 = iter + 1;
1101   EXPECT_TRUE(iter == iter);
1102   EXPECT_TRUE(iter != iter2);
1103   EXPECT_TRUE(iter < iter2);
1104   EXPECT_TRUE(iter <= iter2);
1105   EXPECT_TRUE(iter <= iter);
1106   EXPECT_TRUE(iter2 > iter);
1107   EXPECT_TRUE(iter2 >= iter);
1108   EXPECT_TRUE(iter >= iter);
1109 }
1110 
TEST_F(RepeatedPtrFieldIteratorTest,ComparableConstConversion)1111 TEST_F(RepeatedPtrFieldIteratorTest, ComparableConstConversion) {
1112   RepeatedPtrField<std::string>::iterator iter = proto_array_.begin();
1113   RepeatedPtrField<std::string>::const_iterator iter2 = iter + 1;
1114   EXPECT_TRUE(iter == iter);
1115   EXPECT_TRUE(iter == proto_array_.cbegin());
1116   EXPECT_TRUE(proto_array_.cbegin() == iter);
1117   EXPECT_TRUE(iter != iter2);
1118   EXPECT_TRUE(iter2 != iter);
1119   EXPECT_TRUE(iter < iter2);
1120   EXPECT_TRUE(iter <= iter2);
1121   EXPECT_TRUE(iter <= iter);
1122   EXPECT_TRUE(iter2 > iter);
1123   EXPECT_TRUE(iter2 >= iter);
1124   EXPECT_TRUE(iter >= iter);
1125 }
1126 
1127 // Uninitialized iterator does not point to any of the RepeatedPtrField.
TEST_F(RepeatedPtrFieldIteratorTest,UninitializedIterator)1128 TEST_F(RepeatedPtrFieldIteratorTest, UninitializedIterator) {
1129   RepeatedPtrField<std::string>::iterator iter;
1130   EXPECT_TRUE(iter != proto_array_.begin());
1131   EXPECT_TRUE(iter != proto_array_.begin() + 1);
1132   EXPECT_TRUE(iter != proto_array_.begin() + 2);
1133   EXPECT_TRUE(iter != proto_array_.begin() + 3);
1134   EXPECT_TRUE(iter != proto_array_.end());
1135 }
1136 
TEST_F(RepeatedPtrFieldIteratorTest,STLAlgorithms_lower_bound)1137 TEST_F(RepeatedPtrFieldIteratorTest, STLAlgorithms_lower_bound) {
1138   proto_array_.Clear();
1139   proto_array_.Add()->assign("a");
1140   proto_array_.Add()->assign("c");
1141   proto_array_.Add()->assign("d");
1142   proto_array_.Add()->assign("n");
1143   proto_array_.Add()->assign("p");
1144   proto_array_.Add()->assign("x");
1145   proto_array_.Add()->assign("y");
1146 
1147   std::string v = "f";
1148   RepeatedPtrField<std::string>::const_iterator it =
1149       std::lower_bound(proto_array_.begin(), proto_array_.end(), v);
1150 
1151   EXPECT_EQ(*it, "n");
1152   EXPECT_TRUE(it == proto_array_.begin() + 3);
1153 }
1154 
TEST_F(RepeatedPtrFieldIteratorTest,Mutation)1155 TEST_F(RepeatedPtrFieldIteratorTest, Mutation) {
1156   RepeatedPtrField<std::string>::iterator iter = proto_array_.begin();
1157   *iter = "moo";
1158   EXPECT_EQ("moo", proto_array_.Get(0));
1159 }
1160 
1161 // -------------------------------------------------------------------
1162 
1163 class RepeatedPtrFieldPtrsIteratorTest : public testing::Test {
1164  protected:
SetUp()1165   void SetUp() override {
1166     proto_array_.Add()->assign("foo");
1167     proto_array_.Add()->assign("bar");
1168     proto_array_.Add()->assign("baz");
1169     const_proto_array_ = &proto_array_;
1170   }
1171 
1172   RepeatedPtrField<std::string> proto_array_;
1173   const RepeatedPtrField<std::string>* const_proto_array_;
1174 };
1175 
TEST_F(RepeatedPtrFieldPtrsIteratorTest,ConvertiblePtr)1176 TEST_F(RepeatedPtrFieldPtrsIteratorTest, ConvertiblePtr) {
1177   RepeatedPtrField<std::string>::pointer_iterator iter =
1178       proto_array_.pointer_begin();
1179   static_cast<void>(iter);
1180 }
1181 
TEST_F(RepeatedPtrFieldPtrsIteratorTest,ConvertibleConstPtr)1182 TEST_F(RepeatedPtrFieldPtrsIteratorTest, ConvertibleConstPtr) {
1183   RepeatedPtrField<std::string>::const_pointer_iterator iter =
1184       const_proto_array_->pointer_begin();
1185   static_cast<void>(iter);
1186 }
1187 
TEST_F(RepeatedPtrFieldPtrsIteratorTest,MutablePtrIteration)1188 TEST_F(RepeatedPtrFieldPtrsIteratorTest, MutablePtrIteration) {
1189   RepeatedPtrField<std::string>::pointer_iterator iter =
1190       proto_array_.pointer_begin();
1191   EXPECT_EQ("foo", **iter);
1192   ++iter;
1193   EXPECT_EQ("bar", **(iter++));
1194   EXPECT_EQ("baz", **iter);
1195   ++iter;
1196   EXPECT_TRUE(proto_array_.pointer_end() == iter);
1197   EXPECT_EQ("baz", **(--proto_array_.pointer_end()));
1198 }
1199 
TEST_F(RepeatedPtrFieldPtrsIteratorTest,MutableConstPtrIteration)1200 TEST_F(RepeatedPtrFieldPtrsIteratorTest, MutableConstPtrIteration) {
1201   RepeatedPtrField<std::string>::const_pointer_iterator iter =
1202       const_proto_array_->pointer_begin();
1203   EXPECT_EQ("foo", **iter);
1204   ++iter;
1205   EXPECT_EQ("bar", **(iter++));
1206   EXPECT_EQ("baz", **iter);
1207   ++iter;
1208   EXPECT_TRUE(const_proto_array_->pointer_end() == iter);
1209   EXPECT_EQ("baz", **(--const_proto_array_->pointer_end()));
1210 }
1211 
TEST_F(RepeatedPtrFieldPtrsIteratorTest,RandomPtrAccess)1212 TEST_F(RepeatedPtrFieldPtrsIteratorTest, RandomPtrAccess) {
1213   RepeatedPtrField<std::string>::pointer_iterator iter =
1214       proto_array_.pointer_begin();
1215   RepeatedPtrField<std::string>::pointer_iterator iter2 = iter;
1216   ++iter2;
1217   ++iter2;
1218   EXPECT_TRUE(iter + 2 == iter2);
1219   EXPECT_TRUE(iter == iter2 - 2);
1220   EXPECT_EQ("baz", *iter[2]);
1221   EXPECT_EQ("baz", **(iter + 2));
1222   EXPECT_EQ(3, proto_array_.end() - proto_array_.begin());
1223 }
1224 
TEST_F(RepeatedPtrFieldPtrsIteratorTest,RandomConstPtrAccess)1225 TEST_F(RepeatedPtrFieldPtrsIteratorTest, RandomConstPtrAccess) {
1226   RepeatedPtrField<std::string>::const_pointer_iterator iter =
1227       const_proto_array_->pointer_begin();
1228   RepeatedPtrField<std::string>::const_pointer_iterator iter2 = iter;
1229   ++iter2;
1230   ++iter2;
1231   EXPECT_TRUE(iter + 2 == iter2);
1232   EXPECT_TRUE(iter == iter2 - 2);
1233   EXPECT_EQ("baz", *iter[2]);
1234   EXPECT_EQ("baz", **(iter + 2));
1235   EXPECT_EQ(3, const_proto_array_->end() - const_proto_array_->begin());
1236 }
1237 
TEST_F(RepeatedPtrFieldPtrsIteratorTest,DifferenceConstConversion)1238 TEST_F(RepeatedPtrFieldPtrsIteratorTest, DifferenceConstConversion) {
1239   EXPECT_EQ(3,
1240             proto_array_.pointer_end() - const_proto_array_->pointer_begin());
1241   EXPECT_EQ(3,
1242             const_proto_array_->pointer_end() - proto_array_.pointer_begin());
1243 }
1244 
TEST_F(RepeatedPtrFieldPtrsIteratorTest,ComparablePtr)1245 TEST_F(RepeatedPtrFieldPtrsIteratorTest, ComparablePtr) {
1246   RepeatedPtrField<std::string>::pointer_iterator iter =
1247       proto_array_.pointer_begin();
1248   RepeatedPtrField<std::string>::pointer_iterator iter2 = iter + 1;
1249   EXPECT_TRUE(iter == iter);
1250   EXPECT_TRUE(iter != iter2);
1251   EXPECT_TRUE(iter < iter2);
1252   EXPECT_TRUE(iter <= iter2);
1253   EXPECT_TRUE(iter <= iter);
1254   EXPECT_TRUE(iter2 > iter);
1255   EXPECT_TRUE(iter2 >= iter);
1256   EXPECT_TRUE(iter >= iter);
1257 }
1258 
TEST_F(RepeatedPtrFieldPtrsIteratorTest,ComparableConstPtr)1259 TEST_F(RepeatedPtrFieldPtrsIteratorTest, ComparableConstPtr) {
1260   RepeatedPtrField<std::string>::const_pointer_iterator iter =
1261       const_proto_array_->pointer_begin();
1262   RepeatedPtrField<std::string>::const_pointer_iterator iter2 = iter + 1;
1263   EXPECT_TRUE(iter == iter);
1264   EXPECT_TRUE(iter != iter2);
1265   EXPECT_TRUE(iter < iter2);
1266   EXPECT_TRUE(iter <= iter2);
1267   EXPECT_TRUE(iter <= iter);
1268   EXPECT_TRUE(iter2 > iter);
1269   EXPECT_TRUE(iter2 >= iter);
1270   EXPECT_TRUE(iter >= iter);
1271 }
1272 
TEST_F(RepeatedPtrFieldPtrsIteratorTest,ComparableConstConversion)1273 TEST_F(RepeatedPtrFieldPtrsIteratorTest, ComparableConstConversion) {
1274   RepeatedPtrField<std::string>::pointer_iterator iter =
1275       proto_array_.pointer_begin();
1276   RepeatedPtrField<std::string>::const_pointer_iterator iter2 = iter + 1;
1277   EXPECT_TRUE(iter == iter);
1278   EXPECT_TRUE(iter == const_proto_array_->pointer_begin());
1279   EXPECT_TRUE(const_proto_array_->pointer_begin() == iter);
1280   EXPECT_TRUE(iter != iter2);
1281   EXPECT_TRUE(iter2 != iter);
1282   EXPECT_TRUE(iter < iter2);
1283   EXPECT_TRUE(iter <= iter2);
1284   EXPECT_TRUE(iter <= iter);
1285   EXPECT_TRUE(iter2 > iter);
1286   EXPECT_TRUE(iter2 >= iter);
1287   EXPECT_TRUE(iter >= iter);
1288 }
1289 
1290 // Uninitialized iterator does not point to any of the RepeatedPtrOverPtrs.
1291 // Dereferencing an uninitialized iterator crashes the process.
TEST_F(RepeatedPtrFieldPtrsIteratorTest,UninitializedPtrIterator)1292 TEST_F(RepeatedPtrFieldPtrsIteratorTest, UninitializedPtrIterator) {
1293   RepeatedPtrField<std::string>::pointer_iterator iter;
1294   EXPECT_TRUE(iter != proto_array_.pointer_begin());
1295   EXPECT_TRUE(iter != proto_array_.pointer_begin() + 1);
1296   EXPECT_TRUE(iter != proto_array_.pointer_begin() + 2);
1297   EXPECT_TRUE(iter != proto_array_.pointer_begin() + 3);
1298   EXPECT_TRUE(iter != proto_array_.pointer_end());
1299 }
1300 
TEST_F(RepeatedPtrFieldPtrsIteratorTest,UninitializedConstPtrIterator)1301 TEST_F(RepeatedPtrFieldPtrsIteratorTest, UninitializedConstPtrIterator) {
1302   RepeatedPtrField<std::string>::const_pointer_iterator iter;
1303   EXPECT_TRUE(iter != const_proto_array_->pointer_begin());
1304   EXPECT_TRUE(iter != const_proto_array_->pointer_begin() + 1);
1305   EXPECT_TRUE(iter != const_proto_array_->pointer_begin() + 2);
1306   EXPECT_TRUE(iter != const_proto_array_->pointer_begin() + 3);
1307   EXPECT_TRUE(iter != const_proto_array_->pointer_end());
1308 }
1309 
1310 // This comparison functor is required by the tests for RepeatedPtrOverPtrs.
1311 // They operate on strings and need to compare strings as strings in
1312 // any stl algorithm, even though the iterator returns a pointer to a
1313 // string
1314 // - i.e. *iter has type std::string*.
1315 struct StringLessThan {
operator ()google::protobuf::__anon8b66761c0111::StringLessThan1316   bool operator()(const std::string* z, const std::string* y) const {
1317     return *z < *y;
1318   }
1319 };
1320 
TEST_F(RepeatedPtrFieldPtrsIteratorTest,PtrSTLAlgorithms_lower_bound)1321 TEST_F(RepeatedPtrFieldPtrsIteratorTest, PtrSTLAlgorithms_lower_bound) {
1322   proto_array_.Clear();
1323   proto_array_.Add()->assign("a");
1324   proto_array_.Add()->assign("c");
1325   proto_array_.Add()->assign("d");
1326   proto_array_.Add()->assign("n");
1327   proto_array_.Add()->assign("p");
1328   proto_array_.Add()->assign("x");
1329   proto_array_.Add()->assign("y");
1330 
1331   {
1332     std::string v = "f";
1333     RepeatedPtrField<std::string>::pointer_iterator it =
1334         std::lower_bound(proto_array_.pointer_begin(),
1335                          proto_array_.pointer_end(), &v, StringLessThan());
1336 
1337     ABSL_CHECK(*it != nullptr);
1338 
1339     EXPECT_EQ(**it, "n");
1340     EXPECT_TRUE(it == proto_array_.pointer_begin() + 3);
1341   }
1342   {
1343     std::string v = "f";
1344     RepeatedPtrField<std::string>::const_pointer_iterator it = std::lower_bound(
1345         const_proto_array_->pointer_begin(), const_proto_array_->pointer_end(),
1346         &v, StringLessThan());
1347 
1348     ABSL_CHECK(*it != nullptr);
1349 
1350     EXPECT_EQ(**it, "n");
1351     EXPECT_EQ(it, const_proto_array_->pointer_begin() + 3);
1352   }
1353 }
1354 
TEST_F(RepeatedPtrFieldPtrsIteratorTest,PtrMutation)1355 TEST_F(RepeatedPtrFieldPtrsIteratorTest, PtrMutation) {
1356   RepeatedPtrField<std::string>::pointer_iterator iter =
1357       proto_array_.pointer_begin();
1358   **iter = "moo";
1359   EXPECT_EQ("moo", proto_array_.Get(0));
1360 
1361   EXPECT_EQ("bar", proto_array_.Get(1));
1362   EXPECT_EQ("baz", proto_array_.Get(2));
1363   ++iter;
1364   delete *iter;
1365   *iter = new std::string("a");
1366   ++iter;
1367   delete *iter;
1368   *iter = new std::string("b");
1369   EXPECT_EQ("a", proto_array_.Get(1));
1370   EXPECT_EQ("b", proto_array_.Get(2));
1371 }
1372 
TEST_F(RepeatedPtrFieldPtrsIteratorTest,Sort)1373 TEST_F(RepeatedPtrFieldPtrsIteratorTest, Sort) {
1374   proto_array_.Add()->assign("c");
1375   proto_array_.Add()->assign("d");
1376   proto_array_.Add()->assign("n");
1377   proto_array_.Add()->assign("p");
1378   proto_array_.Add()->assign("a");
1379   proto_array_.Add()->assign("y");
1380   proto_array_.Add()->assign("x");
1381   EXPECT_EQ("foo", proto_array_.Get(0));
1382   EXPECT_EQ("n", proto_array_.Get(5));
1383   EXPECT_EQ("x", proto_array_.Get(9));
1384   std::sort(proto_array_.pointer_begin(), proto_array_.pointer_end(),
1385             StringLessThan());
1386   EXPECT_EQ("a", proto_array_.Get(0));
1387   EXPECT_EQ("baz", proto_array_.Get(2));
1388   EXPECT_EQ("y", proto_array_.Get(9));
1389 }
1390 
1391 // -----------------------------------------------------------------------------
1392 // Unit-tests for the insert iterators
1393 // `google::protobuf::RepeatedPtrFieldBackInserter`,
1394 // `google::protobuf::AllocatedRepeatedPtrFieldBackInserter`
1395 // Ported from util/gtl/proto-array-iterators_unittest.
1396 
1397 class RepeatedPtrFieldInsertionIteratorsTest : public testing::Test {
1398  protected:
1399   using Nested = TestAllTypes::NestedMessage;
1400 
1401   std::vector<std::string> words_;
1402   Nested nesteds_[2];
1403   std::vector<Nested*> nested_ptrs_;
1404   TestAllTypes protobuffer_;
1405 
SetUp()1406   void SetUp() override {
1407     words_.push_back("Able");
1408     words_.push_back("was");
1409     words_.push_back("I");
1410     words_.push_back("ere");
1411     words_.push_back("I");
1412     words_.push_back("saw");
1413     words_.push_back("Elba");
1414     std::copy(
1415         words_.begin(), words_.end(),
1416         RepeatedFieldBackInserter(protobuffer_.mutable_repeated_string()));
1417 
1418     nesteds_[0].set_bb(17);
1419     nesteds_[1].set_bb(4711);
1420     std::copy(&nesteds_[0], &nesteds_[2],
1421               RepeatedFieldBackInserter(
1422                   protobuffer_.mutable_repeated_nested_message()));
1423 
1424     nested_ptrs_.push_back(new Nested);
1425     nested_ptrs_.back()->set_bb(170);
1426     nested_ptrs_.push_back(new Nested);
1427     nested_ptrs_.back()->set_bb(47110);
1428     std::copy(nested_ptrs_.begin(), nested_ptrs_.end(),
1429               RepeatedFieldBackInserter(
1430                   protobuffer_.mutable_repeated_nested_message()));
1431   }
1432 
TearDown()1433   void TearDown() override {
1434     for (auto ptr : nested_ptrs_) {
1435       delete ptr;
1436     }
1437   }
1438 };
1439 
TEST_F(RepeatedPtrFieldInsertionIteratorsTest,Words1)1440 TEST_F(RepeatedPtrFieldInsertionIteratorsTest, Words1) {
1441   ASSERT_EQ(words_.size(), protobuffer_.repeated_string_size());
1442   for (size_t i = 0; i < words_.size(); ++i) {
1443     EXPECT_EQ(words_.at(i), protobuffer_.repeated_string(i));
1444   }
1445 }
1446 
TEST_F(RepeatedPtrFieldInsertionIteratorsTest,Words2)1447 TEST_F(RepeatedPtrFieldInsertionIteratorsTest, Words2) {
1448   words_.clear();
1449   words_.push_back("sing");
1450   words_.push_back("a");
1451   words_.push_back("song");
1452   words_.push_back("of");
1453   words_.push_back("six");
1454   words_.push_back("pence");
1455   protobuffer_.mutable_repeated_string()->Clear();
1456   std::copy(
1457       words_.begin(), words_.end(),
1458       RepeatedPtrFieldBackInserter(protobuffer_.mutable_repeated_string()));
1459   ASSERT_EQ(words_.size(), protobuffer_.repeated_string_size());
1460   for (size_t i = 0; i < words_.size(); ++i) {
1461     EXPECT_EQ(words_.at(i), protobuffer_.repeated_string(i));
1462   }
1463 }
1464 
TEST_F(RepeatedPtrFieldInsertionIteratorsTest,Nesteds)1465 TEST_F(RepeatedPtrFieldInsertionIteratorsTest, Nesteds) {
1466   ASSERT_EQ(protobuffer_.repeated_nested_message_size(), 4);
1467   EXPECT_EQ(protobuffer_.repeated_nested_message(0).bb(), 17);
1468   EXPECT_EQ(protobuffer_.repeated_nested_message(1).bb(), 4711);
1469   EXPECT_EQ(protobuffer_.repeated_nested_message(2).bb(), 170);
1470   EXPECT_EQ(protobuffer_.repeated_nested_message(3).bb(), 47110);
1471 }
1472 
TEST_F(RepeatedPtrFieldInsertionIteratorsTest,AllocatedRepeatedPtrFieldWithStringIntData)1473 TEST_F(RepeatedPtrFieldInsertionIteratorsTest,
1474        AllocatedRepeatedPtrFieldWithStringIntData) {
1475   std::vector<Nested*> data;
1476   TestAllTypes goldenproto;
1477   for (int i = 0; i < 10; ++i) {
1478     Nested* new_data = new Nested;
1479     new_data->set_bb(i);
1480     data.push_back(new_data);
1481 
1482     new_data = goldenproto.add_repeated_nested_message();
1483     new_data->set_bb(i);
1484   }
1485   TestAllTypes testproto;
1486   std::copy(data.begin(), data.end(),
1487             AllocatedRepeatedPtrFieldBackInserter(
1488                 testproto.mutable_repeated_nested_message()));
1489   EXPECT_EQ(testproto.DebugString(), goldenproto.DebugString());
1490 }
1491 
TEST_F(RepeatedPtrFieldInsertionIteratorsTest,AllocatedRepeatedPtrFieldWithString)1492 TEST_F(RepeatedPtrFieldInsertionIteratorsTest,
1493        AllocatedRepeatedPtrFieldWithString) {
1494   std::vector<std::string*> data;
1495   TestAllTypes goldenproto;
1496   for (int i = 0; i < 10; ++i) {
1497     std::string* new_data = new std::string;
1498     *new_data = absl::StrCat("name-", i);
1499     data.push_back(new_data);
1500 
1501     new_data = goldenproto.add_repeated_string();
1502     *new_data = absl::StrCat("name-", i);
1503   }
1504   TestAllTypes testproto;
1505   std::copy(data.begin(), data.end(),
1506             AllocatedRepeatedPtrFieldBackInserter(
1507                 testproto.mutable_repeated_string()));
1508   EXPECT_EQ(testproto.DebugString(), goldenproto.DebugString());
1509 }
1510 
TEST_F(RepeatedPtrFieldInsertionIteratorsTest,UnsafeArenaAllocatedRepeatedPtrFieldWithStringIntData)1511 TEST_F(RepeatedPtrFieldInsertionIteratorsTest,
1512        UnsafeArenaAllocatedRepeatedPtrFieldWithStringIntData) {
1513   std::vector<Nested*> data;
1514   Arena arena;
1515   auto* goldenproto = Arena::Create<TestAllTypes>(&arena);
1516   for (int i = 0; i < 10; ++i) {
1517     auto* new_data = goldenproto->add_repeated_nested_message();
1518     new_data->set_bb(i);
1519     data.push_back(new_data);
1520   }
1521   auto* testproto = Arena::Create<TestAllTypes>(&arena);
1522   std::copy(data.begin(), data.end(),
1523             UnsafeArenaAllocatedRepeatedPtrFieldBackInserter(
1524                 testproto->mutable_repeated_nested_message()));
1525   EXPECT_EQ(testproto->DebugString(), goldenproto->DebugString());
1526 }
1527 
TEST_F(RepeatedPtrFieldInsertionIteratorsTest,UnsafeArenaAllocatedRepeatedPtrFieldWithString)1528 TEST_F(RepeatedPtrFieldInsertionIteratorsTest,
1529        UnsafeArenaAllocatedRepeatedPtrFieldWithString) {
1530   std::vector<std::string*> data;
1531   Arena arena;
1532   auto* goldenproto = Arena::Create<TestAllTypes>(&arena);
1533   for (int i = 0; i < 10; ++i) {
1534     auto* new_data = goldenproto->add_repeated_string();
1535     *new_data = absl::StrCat("name-", i);
1536     data.push_back(new_data);
1537   }
1538   auto* testproto = Arena::Create<TestAllTypes>(&arena);
1539   std::copy(data.begin(), data.end(),
1540             UnsafeArenaAllocatedRepeatedPtrFieldBackInserter(
1541                 testproto->mutable_repeated_string()));
1542   EXPECT_EQ(testproto->DebugString(), goldenproto->DebugString());
1543 }
1544 
TEST_F(RepeatedPtrFieldInsertionIteratorsTest,MoveStrings)1545 TEST_F(RepeatedPtrFieldInsertionIteratorsTest, MoveStrings) {
1546   std::vector<std::string> src = {"a", "b", "c", "d"};
1547   std::vector<std::string> copy =
1548       src;  // copy since move leaves in undefined state
1549   TestAllTypes testproto;
1550   std::move(copy.begin(), copy.end(),
1551             RepeatedFieldBackInserter(testproto.mutable_repeated_string()));
1552 
1553   ASSERT_THAT(testproto.repeated_string(), testing::ElementsAreArray(src));
1554 }
1555 
TEST_F(RepeatedPtrFieldInsertionIteratorsTest,MoveProtos)1556 TEST_F(RepeatedPtrFieldInsertionIteratorsTest, MoveProtos) {
1557   auto make_nested = [](int32_t x) {
1558     Nested ret;
1559     ret.set_bb(x);
1560     return ret;
1561   };
1562   std::vector<Nested> src = {make_nested(3), make_nested(5), make_nested(7)};
1563   std::vector<Nested> copy = src;  // copy since move leaves in undefined state
1564   TestAllTypes testproto;
1565   std::move(
1566       copy.begin(), copy.end(),
1567       RepeatedFieldBackInserter(testproto.mutable_repeated_nested_message()));
1568 
1569   ASSERT_EQ(src.size(), testproto.repeated_nested_message_size());
1570   for (int i = 0; i < src.size(); ++i) {
1571     EXPECT_EQ(src[i].DebugString(),
1572               testproto.repeated_nested_message(i).DebugString());
1573   }
1574 }
1575 
1576 }  // namespace
1577 
1578 }  // namespace protobuf
1579 }  // namespace google
1580 
1581 #include "google/protobuf/port_undef.inc"
1582