1 // Protocol Buffers - Google's data interchange format
2 // Copyright 2008 Google Inc. All rights reserved.
3 // https://developers.google.com/protocol-buffers/
4 //
5 // Redistribution and use in source and binary forms, with or without
6 // modification, are permitted provided that the following conditions are
7 // met:
8 //
9 // * Redistributions of source code must retain the above copyright
10 // notice, this list of conditions and the following disclaimer.
11 // * Redistributions in binary form must reproduce the above
12 // copyright notice, this list of conditions and the following disclaimer
13 // in the documentation and/or other materials provided with the
14 // distribution.
15 // * Neither the name of Google Inc. nor the names of its
16 // contributors may be used to endorse or promote products derived from
17 // this software without specific prior written permission.
18 //
19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
31 // Author: kenton@google.com (Kenton Varda)
32 // Based on original Protocol Buffers design by
33 // Sanjay Ghemawat, Jeff Dean, and others.
34 //
35 // TODO(kenton): Improve this unittest to bring it up to the standards of
36 // other proto2 unittests.
37
38 #include <algorithm>
39 #include <limits>
40 #include <list>
41 #include <vector>
42
43 #include <google/protobuf/repeated_field.h>
44
45 #include <google/protobuf/stubs/logging.h>
46 #include <google/protobuf/stubs/common.h>
47 #include <google/protobuf/unittest.pb.h>
48 #include <google/protobuf/stubs/strutil.h>
49 #include <google/protobuf/testing/googletest.h>
50 #include <gtest/gtest.h>
51 #include <google/protobuf/stubs/stl_util.h>
52
53 namespace google {
54 using protobuf_unittest::TestAllTypes;
55
56 namespace protobuf {
57 namespace {
58
59 // Test operations on a small RepeatedField.
TEST(RepeatedField,Small)60 TEST(RepeatedField, Small) {
61 RepeatedField<int> field;
62
63 EXPECT_TRUE(field.empty());
64 EXPECT_EQ(field.size(), 0);
65
66 field.Add(5);
67
68 EXPECT_FALSE(field.empty());
69 EXPECT_EQ(field.size(), 1);
70 EXPECT_EQ(field.Get(0), 5);
71
72 field.Add(42);
73
74 EXPECT_FALSE(field.empty());
75 EXPECT_EQ(field.size(), 2);
76 EXPECT_EQ(field.Get(0), 5);
77 EXPECT_EQ(field.Get(1), 42);
78
79 field.Set(1, 23);
80
81 EXPECT_FALSE(field.empty());
82 EXPECT_EQ(field.size(), 2);
83 EXPECT_EQ(field.Get(0), 5);
84 EXPECT_EQ(field.Get(1), 23);
85
86 field.RemoveLast();
87
88 EXPECT_FALSE(field.empty());
89 EXPECT_EQ(field.size(), 1);
90 EXPECT_EQ(field.Get(0), 5);
91
92 field.Clear();
93
94 EXPECT_TRUE(field.empty());
95 EXPECT_EQ(field.size(), 0);
96 // Additional bytes are for 'struct Rep' header.
97 int expected_usage = 4 * sizeof(int) + sizeof(Arena*);
98 EXPECT_EQ(field.SpaceUsedExcludingSelf(), expected_usage);
99 }
100
101
102 // Test operations on a RepeatedField which is large enough to allocate a
103 // separate array.
TEST(RepeatedField,Large)104 TEST(RepeatedField, Large) {
105 RepeatedField<int> field;
106
107 for (int i = 0; i < 16; i++) {
108 field.Add(i * i);
109 }
110
111 EXPECT_FALSE(field.empty());
112 EXPECT_EQ(field.size(), 16);
113
114 for (int i = 0; i < 16; i++) {
115 EXPECT_EQ(field.Get(i), i * i);
116 }
117
118 int expected_usage = 16 * sizeof(int);
119 EXPECT_GE(field.SpaceUsedExcludingSelf(), expected_usage);
120 }
121
122 // Test swapping between various types of RepeatedFields.
TEST(RepeatedField,SwapSmallSmall)123 TEST(RepeatedField, SwapSmallSmall) {
124 RepeatedField<int> field1;
125 RepeatedField<int> field2;
126
127 field1.Add(5);
128 field1.Add(42);
129
130 EXPECT_FALSE(field1.empty());
131 EXPECT_EQ(field1.size(), 2);
132 EXPECT_EQ(field1.Get(0), 5);
133 EXPECT_EQ(field1.Get(1), 42);
134
135 EXPECT_TRUE(field2.empty());
136 EXPECT_EQ(field2.size(), 0);
137
138 field1.Swap(&field2);
139
140 EXPECT_TRUE(field1.empty());
141 EXPECT_EQ(field1.size(), 0);
142
143 EXPECT_FALSE(field2.empty());
144 EXPECT_EQ(field2.size(), 2);
145 EXPECT_EQ(field2.Get(0), 5);
146 EXPECT_EQ(field2.Get(1), 42);
147 }
148
TEST(RepeatedField,SwapLargeSmall)149 TEST(RepeatedField, SwapLargeSmall) {
150 RepeatedField<int> field1;
151 RepeatedField<int> field2;
152
153 for (int i = 0; i < 16; i++) {
154 field1.Add(i * i);
155 }
156 field2.Add(5);
157 field2.Add(42);
158 field1.Swap(&field2);
159
160 EXPECT_EQ(field1.size(), 2);
161 EXPECT_EQ(field1.Get(0), 5);
162 EXPECT_EQ(field1.Get(1), 42);
163 EXPECT_EQ(field2.size(), 16);
164 for (int i = 0; i < 16; i++) {
165 EXPECT_EQ(field2.Get(i), i * i);
166 }
167 }
168
TEST(RepeatedField,SwapLargeLarge)169 TEST(RepeatedField, SwapLargeLarge) {
170 RepeatedField<int> field1;
171 RepeatedField<int> field2;
172
173 field1.Add(5);
174 field1.Add(42);
175 for (int i = 0; i < 16; i++) {
176 field1.Add(i);
177 field2.Add(i * i);
178 }
179 field2.Swap(&field1);
180
181 EXPECT_EQ(field1.size(), 16);
182 for (int i = 0; i < 16; i++) {
183 EXPECT_EQ(field1.Get(i), i * i);
184 }
185 EXPECT_EQ(field2.size(), 18);
186 EXPECT_EQ(field2.Get(0), 5);
187 EXPECT_EQ(field2.Get(1), 42);
188 for (int i = 2; i < 18; i++) {
189 EXPECT_EQ(field2.Get(i), i - 2);
190 }
191 }
192
193 // Determines how much space was reserved by the given field by adding elements
194 // to it until it re-allocates its space.
ReservedSpace(RepeatedField<int> * field)195 static int ReservedSpace(RepeatedField<int>* field) {
196 const int* ptr = field->data();
197 do {
198 field->Add(0);
199 } while (field->data() == ptr);
200
201 return field->size() - 1;
202 }
203
TEST(RepeatedField,ReserveMoreThanDouble)204 TEST(RepeatedField, ReserveMoreThanDouble) {
205 // Reserve more than double the previous space in the field and expect the
206 // field to reserve exactly the amount specified.
207 RepeatedField<int> field;
208 field.Reserve(20);
209
210 EXPECT_EQ(20, ReservedSpace(&field));
211 }
212
TEST(RepeatedField,ReserveLessThanDouble)213 TEST(RepeatedField, ReserveLessThanDouble) {
214 // Reserve less than double the previous space in the field and expect the
215 // field to grow by double instead.
216 RepeatedField<int> field;
217 field.Reserve(20);
218 field.Reserve(30);
219
220 EXPECT_EQ(40, ReservedSpace(&field));
221 }
222
TEST(RepeatedField,ReserveLessThanExisting)223 TEST(RepeatedField, ReserveLessThanExisting) {
224 // Reserve less than the previous space in the field and expect the
225 // field to not re-allocate at all.
226 RepeatedField<int> field;
227 field.Reserve(20);
228 const int* previous_ptr = field.data();
229 field.Reserve(10);
230
231 EXPECT_EQ(previous_ptr, field.data());
232 EXPECT_EQ(20, ReservedSpace(&field));
233 }
234
TEST(RepeatedField,Resize)235 TEST(RepeatedField, Resize) {
236 RepeatedField<int> field;
237 field.Resize(2, 1);
238 EXPECT_EQ(2, field.size());
239 field.Resize(5, 2);
240 EXPECT_EQ(5, field.size());
241 field.Resize(4, 3);
242 ASSERT_EQ(4, field.size());
243 EXPECT_EQ(1, field.Get(0));
244 EXPECT_EQ(1, field.Get(1));
245 EXPECT_EQ(2, field.Get(2));
246 EXPECT_EQ(2, field.Get(3));
247 field.Resize(0, 4);
248 EXPECT_TRUE(field.empty());
249 }
250
TEST(RepeatedField,MergeFrom)251 TEST(RepeatedField, MergeFrom) {
252 RepeatedField<int> source, destination;
253 source.Add(4);
254 source.Add(5);
255 destination.Add(1);
256 destination.Add(2);
257 destination.Add(3);
258
259 destination.MergeFrom(source);
260
261 ASSERT_EQ(5, destination.size());
262 EXPECT_EQ(1, destination.Get(0));
263 EXPECT_EQ(2, destination.Get(1));
264 EXPECT_EQ(3, destination.Get(2));
265 EXPECT_EQ(4, destination.Get(3));
266 EXPECT_EQ(5, destination.Get(4));
267 }
268
269 #ifdef PROTOBUF_HAS_DEATH_TEST
TEST(RepeatedField,MergeFromSelf)270 TEST(RepeatedField, MergeFromSelf) {
271 RepeatedField<int> me;
272 me.Add(3);
273 EXPECT_DEATH(me.MergeFrom(me), "");
274 }
275 #endif // PROTOBUF_HAS_DEATH_TEST
276
TEST(RepeatedField,CopyFrom)277 TEST(RepeatedField, CopyFrom) {
278 RepeatedField<int> source, destination;
279 source.Add(4);
280 source.Add(5);
281 destination.Add(1);
282 destination.Add(2);
283 destination.Add(3);
284
285 destination.CopyFrom(source);
286
287 ASSERT_EQ(2, destination.size());
288 EXPECT_EQ(4, destination.Get(0));
289 EXPECT_EQ(5, destination.Get(1));
290 }
291
TEST(RepeatedField,CopyFromSelf)292 TEST(RepeatedField, CopyFromSelf) {
293 RepeatedField<int> me;
294 me.Add(3);
295 me.CopyFrom(me);
296 ASSERT_EQ(1, me.size());
297 EXPECT_EQ(3, me.Get(0));
298 }
299
TEST(RepeatedField,Erase)300 TEST(RepeatedField, Erase) {
301 RepeatedField<int> me;
302 RepeatedField<int>::iterator it = me.erase(me.begin(), me.end());
303 EXPECT_TRUE(me.begin() == it);
304 EXPECT_EQ(0, me.size());
305
306 me.Add(1);
307 me.Add(2);
308 me.Add(3);
309 it = me.erase(me.begin(), me.end());
310 EXPECT_TRUE(me.begin() == it);
311 EXPECT_EQ(0, me.size());
312
313 me.Add(4);
314 me.Add(5);
315 me.Add(6);
316 it = me.erase(me.begin() + 2, me.end());
317 EXPECT_TRUE(me.begin() + 2 == it);
318 EXPECT_EQ(2, me.size());
319 EXPECT_EQ(4, me.Get(0));
320 EXPECT_EQ(5, me.Get(1));
321
322 me.Add(6);
323 me.Add(7);
324 me.Add(8);
325 it = me.erase(me.begin() + 1, me.begin() + 3);
326 EXPECT_TRUE(me.begin() + 1 == it);
327 EXPECT_EQ(3, me.size());
328 EXPECT_EQ(4, me.Get(0));
329 EXPECT_EQ(7, me.Get(1));
330 EXPECT_EQ(8, me.Get(2));
331 }
332
TEST(RepeatedField,CopyConstruct)333 TEST(RepeatedField, CopyConstruct) {
334 RepeatedField<int> source;
335 source.Add(1);
336 source.Add(2);
337
338 RepeatedField<int> destination(source);
339
340 ASSERT_EQ(2, destination.size());
341 EXPECT_EQ(1, destination.Get(0));
342 EXPECT_EQ(2, destination.Get(1));
343 }
344
TEST(RepeatedField,IteratorConstruct)345 TEST(RepeatedField, IteratorConstruct) {
346 vector<int> values;
347 values.push_back(1);
348 values.push_back(2);
349
350 RepeatedField<int> field(values.begin(), values.end());
351 ASSERT_EQ(values.size(), field.size());
352 EXPECT_EQ(values[0], field.Get(0));
353 EXPECT_EQ(values[1], field.Get(1));
354
355 RepeatedField<int> other(field.begin(), field.end());
356 ASSERT_EQ(values.size(), other.size());
357 EXPECT_EQ(values[0], other.Get(0));
358 EXPECT_EQ(values[1], other.Get(1));
359 }
360
TEST(RepeatedField,CopyAssign)361 TEST(RepeatedField, CopyAssign) {
362 RepeatedField<int> source, destination;
363 source.Add(4);
364 source.Add(5);
365 destination.Add(1);
366 destination.Add(2);
367 destination.Add(3);
368
369 destination = source;
370
371 ASSERT_EQ(2, destination.size());
372 EXPECT_EQ(4, destination.Get(0));
373 EXPECT_EQ(5, destination.Get(1));
374 }
375
TEST(RepeatedField,SelfAssign)376 TEST(RepeatedField, SelfAssign) {
377 // Verify that assignment to self does not destroy data.
378 RepeatedField<int> source, *p;
379 p = &source;
380 source.Add(7);
381 source.Add(8);
382
383 *p = source;
384
385 ASSERT_EQ(2, source.size());
386 EXPECT_EQ(7, source.Get(0));
387 EXPECT_EQ(8, source.Get(1));
388 }
389
TEST(RepeatedField,MutableDataIsMutable)390 TEST(RepeatedField, MutableDataIsMutable) {
391 RepeatedField<int> field;
392 field.Add(1);
393 EXPECT_EQ(1, field.Get(0));
394 // The fact that this line compiles would be enough, but we'll check the
395 // value anyway.
396 *field.mutable_data() = 2;
397 EXPECT_EQ(2, field.Get(0));
398 }
399
TEST(RepeatedField,Truncate)400 TEST(RepeatedField, Truncate) {
401 RepeatedField<int> field;
402
403 field.Add(12);
404 field.Add(34);
405 field.Add(56);
406 field.Add(78);
407 EXPECT_EQ(4, field.size());
408
409 field.Truncate(3);
410 EXPECT_EQ(3, field.size());
411
412 field.Add(90);
413 EXPECT_EQ(4, field.size());
414 EXPECT_EQ(90, field.Get(3));
415
416 // Truncations that don't change the size are allowed, but growing is not
417 // allowed.
418 field.Truncate(field.size());
419 #ifdef PROTOBUF_HAS_DEATH_TEST
420 EXPECT_DEBUG_DEATH(field.Truncate(field.size() + 1), "new_size");
421 #endif
422 }
423
424
TEST(RepeatedField,ExtractSubrange)425 TEST(RepeatedField, ExtractSubrange) {
426 // Exhaustively test every subrange in arrays of all sizes from 0 through 9.
427 for (int sz = 0; sz < 10; ++sz) {
428 for (int num = 0; num <= sz; ++num) {
429 for (int start = 0; start < sz - num; ++start) {
430 // Create RepeatedField with sz elements having values 0 through sz-1.
431 RepeatedField<int32> field;
432 for (int i = 0; i < sz; ++i)
433 field.Add(i);
434 EXPECT_EQ(field.size(), sz);
435
436 // Create a catcher array and call ExtractSubrange.
437 int32 catcher[10];
438 for (int i = 0; i < 10; ++i)
439 catcher[i] = -1;
440 field.ExtractSubrange(start, num, catcher);
441
442 // Does the resulting array have the right size?
443 EXPECT_EQ(field.size(), sz - num);
444
445 // Were the removed elements extracted into the catcher array?
446 for (int i = 0; i < num; ++i)
447 EXPECT_EQ(catcher[i], start + i);
448 EXPECT_EQ(catcher[num], -1);
449
450 // Does the resulting array contain the right values?
451 for (int i = 0; i < start; ++i)
452 EXPECT_EQ(field.Get(i), i);
453 for (int i = start; i < field.size(); ++i)
454 EXPECT_EQ(field.Get(i), i + num);
455 }
456 }
457 }
458 }
459
TEST(RepeatedField,ClearThenReserveMore)460 TEST(RepeatedField, ClearThenReserveMore) {
461 // Test that Reserve properly destroys the old internal array when it's forced
462 // to allocate a new one, even when cleared-but-not-deleted objects are
463 // present. Use a 'string' and > 16 bytes length so that the elements are
464 // non-POD and allocate -- the leak checker will catch any skipped destructor
465 // calls here.
466 RepeatedField<string> field;
467 for (int i = 0; i < 32; i++) {
468 field.Add(string("abcdefghijklmnopqrstuvwxyz0123456789"));
469 }
470 EXPECT_EQ(32, field.size());
471 field.Clear();
472 EXPECT_EQ(0, field.size());
473 EXPECT_EQ(32, field.Capacity());
474
475 field.Reserve(1024);
476 EXPECT_EQ(0, field.size());
477 EXPECT_EQ(1024, field.Capacity());
478 // Finish test -- |field| should destroy the cleared-but-not-yet-destroyed
479 // strings.
480 }
481
482 // ===================================================================
483 // RepeatedPtrField tests. These pretty much just mirror the RepeatedField
484 // tests above.
485
TEST(RepeatedPtrField,Small)486 TEST(RepeatedPtrField, Small) {
487 RepeatedPtrField<string> field;
488
489 EXPECT_TRUE(field.empty());
490 EXPECT_EQ(field.size(), 0);
491
492 field.Add()->assign("foo");
493
494 EXPECT_FALSE(field.empty());
495 EXPECT_EQ(field.size(), 1);
496 EXPECT_EQ(field.Get(0), "foo");
497
498 field.Add()->assign("bar");
499
500 EXPECT_FALSE(field.empty());
501 EXPECT_EQ(field.size(), 2);
502 EXPECT_EQ(field.Get(0), "foo");
503 EXPECT_EQ(field.Get(1), "bar");
504
505 field.Mutable(1)->assign("baz");
506
507 EXPECT_FALSE(field.empty());
508 EXPECT_EQ(field.size(), 2);
509 EXPECT_EQ(field.Get(0), "foo");
510 EXPECT_EQ(field.Get(1), "baz");
511
512 field.RemoveLast();
513
514 EXPECT_FALSE(field.empty());
515 EXPECT_EQ(field.size(), 1);
516 EXPECT_EQ(field.Get(0), "foo");
517
518 field.Clear();
519
520 EXPECT_TRUE(field.empty());
521 EXPECT_EQ(field.size(), 0);
522 }
523
TEST(RepeatedPtrField,Large)524 TEST(RepeatedPtrField, Large) {
525 RepeatedPtrField<string> field;
526
527 for (int i = 0; i < 16; i++) {
528 *field.Add() += 'a' + i;
529 }
530
531 EXPECT_EQ(field.size(), 16);
532
533 for (int i = 0; i < 16; i++) {
534 EXPECT_EQ(field.Get(i).size(), 1);
535 EXPECT_EQ(field.Get(i)[0], 'a' + i);
536 }
537
538 int min_expected_usage = 16 * sizeof(string);
539 EXPECT_GE(field.SpaceUsedExcludingSelf(), min_expected_usage);
540 }
541
TEST(RepeatedPtrField,SwapSmallSmall)542 TEST(RepeatedPtrField, SwapSmallSmall) {
543 RepeatedPtrField<string> field1;
544 RepeatedPtrField<string> field2;
545
546 EXPECT_TRUE(field1.empty());
547 EXPECT_EQ(field1.size(), 0);
548 EXPECT_TRUE(field2.empty());
549 EXPECT_EQ(field2.size(), 0);
550
551 field1.Add()->assign("foo");
552 field1.Add()->assign("bar");
553
554 EXPECT_FALSE(field1.empty());
555 EXPECT_EQ(field1.size(), 2);
556 EXPECT_EQ(field1.Get(0), "foo");
557 EXPECT_EQ(field1.Get(1), "bar");
558
559 EXPECT_TRUE(field2.empty());
560 EXPECT_EQ(field2.size(), 0);
561
562 field1.Swap(&field2);
563
564 EXPECT_TRUE(field1.empty());
565 EXPECT_EQ(field1.size(), 0);
566
567 EXPECT_EQ(field2.size(), 2);
568 EXPECT_EQ(field2.Get(0), "foo");
569 EXPECT_EQ(field2.Get(1), "bar");
570 }
571
TEST(RepeatedPtrField,SwapLargeSmall)572 TEST(RepeatedPtrField, SwapLargeSmall) {
573 RepeatedPtrField<string> field1;
574 RepeatedPtrField<string> field2;
575
576 field2.Add()->assign("foo");
577 field2.Add()->assign("bar");
578 for (int i = 0; i < 16; i++) {
579 *field1.Add() += 'a' + i;
580 }
581 field1.Swap(&field2);
582
583 EXPECT_EQ(field1.size(), 2);
584 EXPECT_EQ(field1.Get(0), "foo");
585 EXPECT_EQ(field1.Get(1), "bar");
586 EXPECT_EQ(field2.size(), 16);
587 for (int i = 0; i < 16; i++) {
588 EXPECT_EQ(field2.Get(i).size(), 1);
589 EXPECT_EQ(field2.Get(i)[0], 'a' + i);
590 }
591 }
592
TEST(RepeatedPtrField,SwapLargeLarge)593 TEST(RepeatedPtrField, SwapLargeLarge) {
594 RepeatedPtrField<string> field1;
595 RepeatedPtrField<string> field2;
596
597 field1.Add()->assign("foo");
598 field1.Add()->assign("bar");
599 for (int i = 0; i < 16; i++) {
600 *field1.Add() += 'A' + i;
601 *field2.Add() += 'a' + i;
602 }
603 field2.Swap(&field1);
604
605 EXPECT_EQ(field1.size(), 16);
606 for (int i = 0; i < 16; i++) {
607 EXPECT_EQ(field1.Get(i).size(), 1);
608 EXPECT_EQ(field1.Get(i)[0], 'a' + i);
609 }
610 EXPECT_EQ(field2.size(), 18);
611 EXPECT_EQ(field2.Get(0), "foo");
612 EXPECT_EQ(field2.Get(1), "bar");
613 for (int i = 2; i < 18; i++) {
614 EXPECT_EQ(field2.Get(i).size(), 1);
615 EXPECT_EQ(field2.Get(i)[0], 'A' + i - 2);
616 }
617 }
618
ReservedSpace(RepeatedPtrField<string> * field)619 static int ReservedSpace(RepeatedPtrField<string>* field) {
620 const string* const* ptr = field->data();
621 do {
622 field->Add();
623 } while (field->data() == ptr);
624
625 return field->size() - 1;
626 }
627
TEST(RepeatedPtrField,ReserveMoreThanDouble)628 TEST(RepeatedPtrField, ReserveMoreThanDouble) {
629 RepeatedPtrField<string> field;
630 field.Reserve(20);
631
632 EXPECT_EQ(20, ReservedSpace(&field));
633 }
634
TEST(RepeatedPtrField,ReserveLessThanDouble)635 TEST(RepeatedPtrField, ReserveLessThanDouble) {
636 RepeatedPtrField<string> field;
637 field.Reserve(20);
638 field.Reserve(30);
639
640 EXPECT_EQ(40, ReservedSpace(&field));
641 }
642
TEST(RepeatedPtrField,ReserveLessThanExisting)643 TEST(RepeatedPtrField, ReserveLessThanExisting) {
644 RepeatedPtrField<string> field;
645 field.Reserve(20);
646 const string* const* previous_ptr = field.data();
647 field.Reserve(10);
648
649 EXPECT_EQ(previous_ptr, field.data());
650 EXPECT_EQ(20, ReservedSpace(&field));
651 }
652
TEST(RepeatedPtrField,ReserveDoesntLoseAllocated)653 TEST(RepeatedPtrField, ReserveDoesntLoseAllocated) {
654 // Check that a bug is fixed: An earlier implementation of Reserve()
655 // failed to copy pointers to allocated-but-cleared objects, possibly
656 // leading to segfaults.
657 RepeatedPtrField<string> field;
658 string* first = field.Add();
659 field.RemoveLast();
660
661 field.Reserve(20);
662 EXPECT_EQ(first, field.Add());
663 }
664
665 // Clearing elements is tricky with RepeatedPtrFields since the memory for
666 // the elements is retained and reused.
TEST(RepeatedPtrField,ClearedElements)667 TEST(RepeatedPtrField, ClearedElements) {
668 RepeatedPtrField<string> field;
669
670 string* original = field.Add();
671 *original = "foo";
672
673 EXPECT_EQ(field.ClearedCount(), 0);
674
675 field.RemoveLast();
676 EXPECT_TRUE(original->empty());
677 EXPECT_EQ(field.ClearedCount(), 1);
678
679 EXPECT_EQ(field.Add(), original); // Should return same string for reuse.
680
681 EXPECT_EQ(field.ReleaseLast(), original); // We take ownership.
682 EXPECT_EQ(field.ClearedCount(), 0);
683
684 EXPECT_NE(field.Add(), original); // Should NOT return the same string.
685 EXPECT_EQ(field.ClearedCount(), 0);
686
687 field.AddAllocated(original); // Give ownership back.
688 EXPECT_EQ(field.ClearedCount(), 0);
689 EXPECT_EQ(field.Mutable(1), original);
690
691 field.Clear();
692 EXPECT_EQ(field.ClearedCount(), 2);
693 EXPECT_EQ(field.ReleaseCleared(), original); // Take ownership again.
694 EXPECT_EQ(field.ClearedCount(), 1);
695 EXPECT_NE(field.Add(), original);
696 EXPECT_EQ(field.ClearedCount(), 0);
697 EXPECT_NE(field.Add(), original);
698 EXPECT_EQ(field.ClearedCount(), 0);
699
700 field.AddCleared(original); // Give ownership back, but as a cleared object.
701 EXPECT_EQ(field.ClearedCount(), 1);
702 EXPECT_EQ(field.Add(), original);
703 EXPECT_EQ(field.ClearedCount(), 0);
704 }
705
706 // Test all code paths in AddAllocated().
TEST(RepeatedPtrField,AddAlocated)707 TEST(RepeatedPtrField, AddAlocated) {
708 RepeatedPtrField<string> field;
709 while (field.size() < field.Capacity()) {
710 field.Add()->assign("filler");
711 }
712
713 int index = field.size();
714
715 // First branch: Field is at capacity with no cleared objects.
716 string* foo = new string("foo");
717 field.AddAllocated(foo);
718 EXPECT_EQ(index + 1, field.size());
719 EXPECT_EQ(0, field.ClearedCount());
720 EXPECT_EQ(foo, &field.Get(index));
721
722 // Last branch: Field is not at capacity and there are no cleared objects.
723 string* bar = new string("bar");
724 field.AddAllocated(bar);
725 ++index;
726 EXPECT_EQ(index + 1, field.size());
727 EXPECT_EQ(0, field.ClearedCount());
728 EXPECT_EQ(bar, &field.Get(index));
729
730 // Third branch: Field is not at capacity and there are no cleared objects.
731 field.RemoveLast();
732 string* baz = new string("baz");
733 field.AddAllocated(baz);
734 EXPECT_EQ(index + 1, field.size());
735 EXPECT_EQ(1, field.ClearedCount());
736 EXPECT_EQ(baz, &field.Get(index));
737
738 // Second branch: Field is at capacity but has some cleared objects.
739 while (field.size() < field.Capacity()) {
740 field.Add()->assign("filler2");
741 }
742 field.RemoveLast();
743 index = field.size();
744 string* qux = new string("qux");
745 field.AddAllocated(qux);
746 EXPECT_EQ(index + 1, field.size());
747 // We should have discarded the cleared object.
748 EXPECT_EQ(0, field.ClearedCount());
749 EXPECT_EQ(qux, &field.Get(index));
750 }
751
TEST(RepeatedPtrField,MergeFrom)752 TEST(RepeatedPtrField, MergeFrom) {
753 RepeatedPtrField<string> source, destination;
754 source.Add()->assign("4");
755 source.Add()->assign("5");
756 destination.Add()->assign("1");
757 destination.Add()->assign("2");
758 destination.Add()->assign("3");
759
760 destination.MergeFrom(source);
761
762 ASSERT_EQ(5, destination.size());
763 EXPECT_EQ("1", destination.Get(0));
764 EXPECT_EQ("2", destination.Get(1));
765 EXPECT_EQ("3", destination.Get(2));
766 EXPECT_EQ("4", destination.Get(3));
767 EXPECT_EQ("5", destination.Get(4));
768 }
769
770 #ifdef PROTOBUF_HAS_DEATH_TEST
TEST(RepeatedPtrField,MergeFromSelf)771 TEST(RepeatedPtrField, MergeFromSelf) {
772 RepeatedPtrField<string> me;
773 me.Add()->assign("1");
774 EXPECT_DEATH(me.MergeFrom(me), "");
775 }
776 #endif // PROTOBUF_HAS_DEATH_TEST
777
TEST(RepeatedPtrField,CopyFrom)778 TEST(RepeatedPtrField, CopyFrom) {
779 RepeatedPtrField<string> source, destination;
780 source.Add()->assign("4");
781 source.Add()->assign("5");
782 destination.Add()->assign("1");
783 destination.Add()->assign("2");
784 destination.Add()->assign("3");
785
786 destination.CopyFrom(source);
787
788 ASSERT_EQ(2, destination.size());
789 EXPECT_EQ("4", destination.Get(0));
790 EXPECT_EQ("5", destination.Get(1));
791 }
792
TEST(RepeatedPtrField,CopyFromSelf)793 TEST(RepeatedPtrField, CopyFromSelf) {
794 RepeatedPtrField<string> me;
795 me.Add()->assign("1");
796 me.CopyFrom(me);
797 ASSERT_EQ(1, me.size());
798 EXPECT_EQ("1", me.Get(0));
799 }
800
TEST(RepeatedPtrField,Erase)801 TEST(RepeatedPtrField, Erase) {
802 RepeatedPtrField<string> me;
803 RepeatedPtrField<string>::iterator it = me.erase(me.begin(), me.end());
804 EXPECT_TRUE(me.begin() == it);
805 EXPECT_EQ(0, me.size());
806
807 *me.Add() = "1";
808 *me.Add() = "2";
809 *me.Add() = "3";
810 it = me.erase(me.begin(), me.end());
811 EXPECT_TRUE(me.begin() == it);
812 EXPECT_EQ(0, me.size());
813
814 *me.Add() = "4";
815 *me.Add() = "5";
816 *me.Add() = "6";
817 it = me.erase(me.begin() + 2, me.end());
818 EXPECT_TRUE(me.begin() + 2 == it);
819 EXPECT_EQ(2, me.size());
820 EXPECT_EQ("4", me.Get(0));
821 EXPECT_EQ("5", me.Get(1));
822
823 *me.Add() = "6";
824 *me.Add() = "7";
825 *me.Add() = "8";
826 it = me.erase(me.begin() + 1, me.begin() + 3);
827 EXPECT_TRUE(me.begin() + 1 == it);
828 EXPECT_EQ(3, me.size());
829 EXPECT_EQ("4", me.Get(0));
830 EXPECT_EQ("7", me.Get(1));
831 EXPECT_EQ("8", me.Get(2));
832 }
833
TEST(RepeatedPtrField,CopyConstruct)834 TEST(RepeatedPtrField, CopyConstruct) {
835 RepeatedPtrField<string> source;
836 source.Add()->assign("1");
837 source.Add()->assign("2");
838
839 RepeatedPtrField<string> destination(source);
840
841 ASSERT_EQ(2, destination.size());
842 EXPECT_EQ("1", destination.Get(0));
843 EXPECT_EQ("2", destination.Get(1));
844 }
845
TEST(RepeatedPtrField,IteratorConstruct_String)846 TEST(RepeatedPtrField, IteratorConstruct_String) {
847 vector<string> values;
848 values.push_back("1");
849 values.push_back("2");
850
851 RepeatedPtrField<string> field(values.begin(), values.end());
852 ASSERT_EQ(values.size(), field.size());
853 EXPECT_EQ(values[0], field.Get(0));
854 EXPECT_EQ(values[1], field.Get(1));
855
856 RepeatedPtrField<string> other(field.begin(), field.end());
857 ASSERT_EQ(values.size(), other.size());
858 EXPECT_EQ(values[0], other.Get(0));
859 EXPECT_EQ(values[1], other.Get(1));
860 }
861
TEST(RepeatedPtrField,IteratorConstruct_Proto)862 TEST(RepeatedPtrField, IteratorConstruct_Proto) {
863 typedef TestAllTypes::NestedMessage Nested;
864 vector<Nested> values;
865 values.push_back(Nested());
866 values.back().set_bb(1);
867 values.push_back(Nested());
868 values.back().set_bb(2);
869
870 RepeatedPtrField<Nested> field(values.begin(), values.end());
871 ASSERT_EQ(values.size(), field.size());
872 EXPECT_EQ(values[0].bb(), field.Get(0).bb());
873 EXPECT_EQ(values[1].bb(), field.Get(1).bb());
874
875 RepeatedPtrField<Nested> other(field.begin(), field.end());
876 ASSERT_EQ(values.size(), other.size());
877 EXPECT_EQ(values[0].bb(), other.Get(0).bb());
878 EXPECT_EQ(values[1].bb(), other.Get(1).bb());
879 }
880
TEST(RepeatedPtrField,CopyAssign)881 TEST(RepeatedPtrField, CopyAssign) {
882 RepeatedPtrField<string> source, destination;
883 source.Add()->assign("4");
884 source.Add()->assign("5");
885 destination.Add()->assign("1");
886 destination.Add()->assign("2");
887 destination.Add()->assign("3");
888
889 destination = source;
890
891 ASSERT_EQ(2, destination.size());
892 EXPECT_EQ("4", destination.Get(0));
893 EXPECT_EQ("5", destination.Get(1));
894 }
895
TEST(RepeatedPtrField,SelfAssign)896 TEST(RepeatedPtrField, SelfAssign) {
897 // Verify that assignment to self does not destroy data.
898 RepeatedPtrField<string> source, *p;
899 p = &source;
900 source.Add()->assign("7");
901 source.Add()->assign("8");
902
903 *p = source;
904
905 ASSERT_EQ(2, source.size());
906 EXPECT_EQ("7", source.Get(0));
907 EXPECT_EQ("8", source.Get(1));
908 }
909
TEST(RepeatedPtrField,MutableDataIsMutable)910 TEST(RepeatedPtrField, MutableDataIsMutable) {
911 RepeatedPtrField<string> field;
912 *field.Add() = "1";
913 EXPECT_EQ("1", field.Get(0));
914 // The fact that this line compiles would be enough, but we'll check the
915 // value anyway.
916 string** data = field.mutable_data();
917 **data = "2";
918 EXPECT_EQ("2", field.Get(0));
919 }
920
TEST(RepeatedPtrField,ExtractSubrange)921 TEST(RepeatedPtrField, ExtractSubrange) {
922 // Exhaustively test every subrange in arrays of all sizes from 0 through 9
923 // with 0 through 3 cleared elements at the end.
924 for (int sz = 0; sz < 10; ++sz) {
925 for (int num = 0; num <= sz; ++num) {
926 for (int start = 0; start < sz - num; ++start) {
927 for (int extra = 0; extra < 4; ++extra) {
928 vector<string*> subject;
929
930 // Create an array with "sz" elements and "extra" cleared elements.
931 RepeatedPtrField<string> field;
932 for (int i = 0; i < sz + extra; ++i) {
933 subject.push_back(new string());
934 field.AddAllocated(subject[i]);
935 }
936 EXPECT_EQ(field.size(), sz + extra);
937 for (int i = 0; i < extra; ++i)
938 field.RemoveLast();
939 EXPECT_EQ(field.size(), sz);
940 EXPECT_EQ(field.ClearedCount(), extra);
941
942 // Create a catcher array and call ExtractSubrange.
943 string* catcher[10];
944 for (int i = 0; i < 10; ++i)
945 catcher[i] = NULL;
946 field.ExtractSubrange(start, num, catcher);
947
948 // Does the resulting array have the right size?
949 EXPECT_EQ(field.size(), sz - num);
950
951 // Were the removed elements extracted into the catcher array?
952 for (int i = 0; i < num; ++i)
953 EXPECT_EQ(catcher[i], subject[start + i]);
954 EXPECT_EQ(NULL, catcher[num]);
955
956 // Does the resulting array contain the right values?
957 for (int i = 0; i < start; ++i)
958 EXPECT_EQ(field.Mutable(i), subject[i]);
959 for (int i = start; i < field.size(); ++i)
960 EXPECT_EQ(field.Mutable(i), subject[i + num]);
961
962 // Reinstate the cleared elements.
963 EXPECT_EQ(field.ClearedCount(), extra);
964 for (int i = 0; i < extra; ++i)
965 field.Add();
966 EXPECT_EQ(field.ClearedCount(), 0);
967 EXPECT_EQ(field.size(), sz - num + extra);
968
969 // Make sure the extra elements are all there (in some order).
970 for (int i = sz; i < sz + extra; ++i) {
971 int count = 0;
972 for (int j = sz; j < sz + extra; ++j) {
973 if (field.Mutable(j - num) == subject[i])
974 count += 1;
975 }
976 EXPECT_EQ(count, 1);
977 }
978
979 // Release the caught elements.
980 for (int i = 0; i < num; ++i)
981 delete catcher[i];
982 }
983 }
984 }
985 }
986 }
987
TEST(RepeatedPtrField,DeleteSubrange)988 TEST(RepeatedPtrField, DeleteSubrange) {
989 // DeleteSubrange is a trivial extension of ExtendSubrange.
990 }
991
992 // ===================================================================
993
994 // Iterator tests stolen from net/proto/proto-array_unittest.
995 class RepeatedFieldIteratorTest : public testing::Test {
996 protected:
SetUp()997 virtual void SetUp() {
998 for (int i = 0; i < 3; ++i) {
999 proto_array_.Add(i);
1000 }
1001 }
1002
1003 RepeatedField<int> proto_array_;
1004 };
1005
TEST_F(RepeatedFieldIteratorTest,Convertible)1006 TEST_F(RepeatedFieldIteratorTest, Convertible) {
1007 RepeatedField<int>::iterator iter = proto_array_.begin();
1008 RepeatedField<int>::const_iterator c_iter = iter;
1009 RepeatedField<int>::value_type value = *c_iter;
1010 EXPECT_EQ(0, value);
1011 }
1012
TEST_F(RepeatedFieldIteratorTest,MutableIteration)1013 TEST_F(RepeatedFieldIteratorTest, MutableIteration) {
1014 RepeatedField<int>::iterator iter = proto_array_.begin();
1015 EXPECT_EQ(0, *iter);
1016 ++iter;
1017 EXPECT_EQ(1, *iter++);
1018 EXPECT_EQ(2, *iter);
1019 ++iter;
1020 EXPECT_TRUE(proto_array_.end() == iter);
1021
1022 EXPECT_EQ(2, *(proto_array_.end() - 1));
1023 }
1024
TEST_F(RepeatedFieldIteratorTest,ConstIteration)1025 TEST_F(RepeatedFieldIteratorTest, ConstIteration) {
1026 const RepeatedField<int>& const_proto_array = proto_array_;
1027 RepeatedField<int>::const_iterator iter = const_proto_array.begin();
1028 EXPECT_EQ(0, *iter);
1029 ++iter;
1030 EXPECT_EQ(1, *iter++);
1031 EXPECT_EQ(2, *iter);
1032 ++iter;
1033 EXPECT_TRUE(proto_array_.end() == iter);
1034 EXPECT_EQ(2, *(proto_array_.end() - 1));
1035 }
1036
TEST_F(RepeatedFieldIteratorTest,Mutation)1037 TEST_F(RepeatedFieldIteratorTest, Mutation) {
1038 RepeatedField<int>::iterator iter = proto_array_.begin();
1039 *iter = 7;
1040 EXPECT_EQ(7, proto_array_.Get(0));
1041 }
1042
1043 // -------------------------------------------------------------------
1044
1045 class RepeatedPtrFieldIteratorTest : public testing::Test {
1046 protected:
SetUp()1047 virtual void SetUp() {
1048 proto_array_.Add()->assign("foo");
1049 proto_array_.Add()->assign("bar");
1050 proto_array_.Add()->assign("baz");
1051 }
1052
1053 RepeatedPtrField<string> proto_array_;
1054 };
1055
TEST_F(RepeatedPtrFieldIteratorTest,Convertible)1056 TEST_F(RepeatedPtrFieldIteratorTest, Convertible) {
1057 RepeatedPtrField<string>::iterator iter = proto_array_.begin();
1058 RepeatedPtrField<string>::const_iterator c_iter = iter;
1059 RepeatedPtrField<string>::value_type value = *c_iter;
1060 EXPECT_EQ("foo", value);
1061 }
1062
TEST_F(RepeatedPtrFieldIteratorTest,MutableIteration)1063 TEST_F(RepeatedPtrFieldIteratorTest, MutableIteration) {
1064 RepeatedPtrField<string>::iterator iter = proto_array_.begin();
1065 EXPECT_EQ("foo", *iter);
1066 ++iter;
1067 EXPECT_EQ("bar", *(iter++));
1068 EXPECT_EQ("baz", *iter);
1069 ++iter;
1070 EXPECT_TRUE(proto_array_.end() == iter);
1071 EXPECT_EQ("baz", *(--proto_array_.end()));
1072 }
1073
TEST_F(RepeatedPtrFieldIteratorTest,ConstIteration)1074 TEST_F(RepeatedPtrFieldIteratorTest, ConstIteration) {
1075 const RepeatedPtrField<string>& const_proto_array = proto_array_;
1076 RepeatedPtrField<string>::const_iterator iter = const_proto_array.begin();
1077 EXPECT_EQ("foo", *iter);
1078 ++iter;
1079 EXPECT_EQ("bar", *(iter++));
1080 EXPECT_EQ("baz", *iter);
1081 ++iter;
1082 EXPECT_TRUE(const_proto_array.end() == iter);
1083 EXPECT_EQ("baz", *(--const_proto_array.end()));
1084 }
1085
TEST_F(RepeatedPtrFieldIteratorTest,MutableReverseIteration)1086 TEST_F(RepeatedPtrFieldIteratorTest, MutableReverseIteration) {
1087 RepeatedPtrField<string>::reverse_iterator iter = proto_array_.rbegin();
1088 EXPECT_EQ("baz", *iter);
1089 ++iter;
1090 EXPECT_EQ("bar", *(iter++));
1091 EXPECT_EQ("foo", *iter);
1092 ++iter;
1093 EXPECT_TRUE(proto_array_.rend() == iter);
1094 EXPECT_EQ("foo", *(--proto_array_.rend()));
1095 }
1096
TEST_F(RepeatedPtrFieldIteratorTest,ConstReverseIteration)1097 TEST_F(RepeatedPtrFieldIteratorTest, ConstReverseIteration) {
1098 const RepeatedPtrField<string>& const_proto_array = proto_array_;
1099 RepeatedPtrField<string>::const_reverse_iterator iter
1100 = const_proto_array.rbegin();
1101 EXPECT_EQ("baz", *iter);
1102 ++iter;
1103 EXPECT_EQ("bar", *(iter++));
1104 EXPECT_EQ("foo", *iter);
1105 ++iter;
1106 EXPECT_TRUE(const_proto_array.rend() == iter);
1107 EXPECT_EQ("foo", *(--const_proto_array.rend()));
1108 }
1109
TEST_F(RepeatedPtrFieldIteratorTest,RandomAccess)1110 TEST_F(RepeatedPtrFieldIteratorTest, RandomAccess) {
1111 RepeatedPtrField<string>::iterator iter = proto_array_.begin();
1112 RepeatedPtrField<string>::iterator iter2 = iter;
1113 ++iter2;
1114 ++iter2;
1115 EXPECT_TRUE(iter + 2 == iter2);
1116 EXPECT_TRUE(iter == iter2 - 2);
1117 EXPECT_EQ("baz", iter[2]);
1118 EXPECT_EQ("baz", *(iter + 2));
1119 EXPECT_EQ(3, proto_array_.end() - proto_array_.begin());
1120 }
1121
TEST_F(RepeatedPtrFieldIteratorTest,Comparable)1122 TEST_F(RepeatedPtrFieldIteratorTest, Comparable) {
1123 RepeatedPtrField<string>::const_iterator iter = proto_array_.begin();
1124 RepeatedPtrField<string>::const_iterator iter2 = iter + 1;
1125 EXPECT_TRUE(iter == iter);
1126 EXPECT_TRUE(iter != iter2);
1127 EXPECT_TRUE(iter < iter2);
1128 EXPECT_TRUE(iter <= iter2);
1129 EXPECT_TRUE(iter <= iter);
1130 EXPECT_TRUE(iter2 > iter);
1131 EXPECT_TRUE(iter2 >= iter);
1132 EXPECT_TRUE(iter >= iter);
1133 }
1134
1135 // Uninitialized iterator does not point to any of the RepeatedPtrField.
TEST_F(RepeatedPtrFieldIteratorTest,UninitializedIterator)1136 TEST_F(RepeatedPtrFieldIteratorTest, UninitializedIterator) {
1137 RepeatedPtrField<string>::iterator iter;
1138 EXPECT_TRUE(iter != proto_array_.begin());
1139 EXPECT_TRUE(iter != proto_array_.begin() + 1);
1140 EXPECT_TRUE(iter != proto_array_.begin() + 2);
1141 EXPECT_TRUE(iter != proto_array_.begin() + 3);
1142 EXPECT_TRUE(iter != proto_array_.end());
1143 }
1144
TEST_F(RepeatedPtrFieldIteratorTest,STLAlgorithms_lower_bound)1145 TEST_F(RepeatedPtrFieldIteratorTest, STLAlgorithms_lower_bound) {
1146 proto_array_.Clear();
1147 proto_array_.Add()->assign("a");
1148 proto_array_.Add()->assign("c");
1149 proto_array_.Add()->assign("d");
1150 proto_array_.Add()->assign("n");
1151 proto_array_.Add()->assign("p");
1152 proto_array_.Add()->assign("x");
1153 proto_array_.Add()->assign("y");
1154
1155 string v = "f";
1156 RepeatedPtrField<string>::const_iterator it =
1157 std::lower_bound(proto_array_.begin(), proto_array_.end(), v);
1158
1159 EXPECT_EQ(*it, "n");
1160 EXPECT_TRUE(it == proto_array_.begin() + 3);
1161 }
1162
TEST_F(RepeatedPtrFieldIteratorTest,Mutation)1163 TEST_F(RepeatedPtrFieldIteratorTest, Mutation) {
1164 RepeatedPtrField<string>::iterator iter = proto_array_.begin();
1165 *iter = "qux";
1166 EXPECT_EQ("qux", proto_array_.Get(0));
1167 }
1168
1169 // -------------------------------------------------------------------
1170
1171 class RepeatedPtrFieldPtrsIteratorTest : public testing::Test {
1172 protected:
SetUp()1173 virtual void SetUp() {
1174 proto_array_.Add()->assign("foo");
1175 proto_array_.Add()->assign("bar");
1176 proto_array_.Add()->assign("baz");
1177 const_proto_array_ = &proto_array_;
1178 }
1179
1180 RepeatedPtrField<string> proto_array_;
1181 const RepeatedPtrField<string>* const_proto_array_;
1182 };
1183
TEST_F(RepeatedPtrFieldPtrsIteratorTest,ConvertiblePtr)1184 TEST_F(RepeatedPtrFieldPtrsIteratorTest, ConvertiblePtr) {
1185 RepeatedPtrField<string>::pointer_iterator iter =
1186 proto_array_.pointer_begin();
1187 static_cast<void>(iter);
1188 }
1189
TEST_F(RepeatedPtrFieldPtrsIteratorTest,ConvertibleConstPtr)1190 TEST_F(RepeatedPtrFieldPtrsIteratorTest, ConvertibleConstPtr) {
1191 RepeatedPtrField<string>::const_pointer_iterator iter =
1192 const_proto_array_->pointer_begin();
1193 static_cast<void>(iter);
1194 }
1195
TEST_F(RepeatedPtrFieldPtrsIteratorTest,MutablePtrIteration)1196 TEST_F(RepeatedPtrFieldPtrsIteratorTest, MutablePtrIteration) {
1197 RepeatedPtrField<string>::pointer_iterator iter =
1198 proto_array_.pointer_begin();
1199 EXPECT_EQ("foo", **iter);
1200 ++iter;
1201 EXPECT_EQ("bar", **(iter++));
1202 EXPECT_EQ("baz", **iter);
1203 ++iter;
1204 EXPECT_TRUE(proto_array_.pointer_end() == iter);
1205 EXPECT_EQ("baz", **(--proto_array_.pointer_end()));
1206 }
1207
TEST_F(RepeatedPtrFieldPtrsIteratorTest,MutableConstPtrIteration)1208 TEST_F(RepeatedPtrFieldPtrsIteratorTest, MutableConstPtrIteration) {
1209 RepeatedPtrField<string>::const_pointer_iterator iter =
1210 const_proto_array_->pointer_begin();
1211 EXPECT_EQ("foo", **iter);
1212 ++iter;
1213 EXPECT_EQ("bar", **(iter++));
1214 EXPECT_EQ("baz", **iter);
1215 ++iter;
1216 EXPECT_TRUE(const_proto_array_->pointer_end() == iter);
1217 EXPECT_EQ("baz", **(--const_proto_array_->pointer_end()));
1218 }
1219
TEST_F(RepeatedPtrFieldPtrsIteratorTest,RandomPtrAccess)1220 TEST_F(RepeatedPtrFieldPtrsIteratorTest, RandomPtrAccess) {
1221 RepeatedPtrField<string>::pointer_iterator iter =
1222 proto_array_.pointer_begin();
1223 RepeatedPtrField<string>::pointer_iterator iter2 = iter;
1224 ++iter2;
1225 ++iter2;
1226 EXPECT_TRUE(iter + 2 == iter2);
1227 EXPECT_TRUE(iter == iter2 - 2);
1228 EXPECT_EQ("baz", *iter[2]);
1229 EXPECT_EQ("baz", **(iter + 2));
1230 EXPECT_EQ(3, proto_array_.end() - proto_array_.begin());
1231 }
1232
TEST_F(RepeatedPtrFieldPtrsIteratorTest,RandomConstPtrAccess)1233 TEST_F(RepeatedPtrFieldPtrsIteratorTest, RandomConstPtrAccess) {
1234 RepeatedPtrField<string>::const_pointer_iterator iter =
1235 const_proto_array_->pointer_begin();
1236 RepeatedPtrField<string>::const_pointer_iterator iter2 = iter;
1237 ++iter2;
1238 ++iter2;
1239 EXPECT_TRUE(iter + 2 == iter2);
1240 EXPECT_TRUE(iter == iter2 - 2);
1241 EXPECT_EQ("baz", *iter[2]);
1242 EXPECT_EQ("baz", **(iter + 2));
1243 EXPECT_EQ(3, const_proto_array_->end() - const_proto_array_->begin());
1244 }
1245
TEST_F(RepeatedPtrFieldPtrsIteratorTest,ComparablePtr)1246 TEST_F(RepeatedPtrFieldPtrsIteratorTest, ComparablePtr) {
1247 RepeatedPtrField<string>::pointer_iterator iter =
1248 proto_array_.pointer_begin();
1249 RepeatedPtrField<string>::pointer_iterator iter2 = iter + 1;
1250 EXPECT_TRUE(iter == iter);
1251 EXPECT_TRUE(iter != iter2);
1252 EXPECT_TRUE(iter < iter2);
1253 EXPECT_TRUE(iter <= iter2);
1254 EXPECT_TRUE(iter <= iter);
1255 EXPECT_TRUE(iter2 > iter);
1256 EXPECT_TRUE(iter2 >= iter);
1257 EXPECT_TRUE(iter >= iter);
1258 }
1259
TEST_F(RepeatedPtrFieldPtrsIteratorTest,ComparableConstPtr)1260 TEST_F(RepeatedPtrFieldPtrsIteratorTest, ComparableConstPtr) {
1261 RepeatedPtrField<string>::const_pointer_iterator iter =
1262 const_proto_array_->pointer_begin();
1263 RepeatedPtrField<string>::const_pointer_iterator iter2 = iter + 1;
1264 EXPECT_TRUE(iter == iter);
1265 EXPECT_TRUE(iter != iter2);
1266 EXPECT_TRUE(iter < iter2);
1267 EXPECT_TRUE(iter <= iter2);
1268 EXPECT_TRUE(iter <= iter);
1269 EXPECT_TRUE(iter2 > iter);
1270 EXPECT_TRUE(iter2 >= iter);
1271 EXPECT_TRUE(iter >= iter);
1272 }
1273
1274 // Uninitialized iterator does not point to any of the RepeatedPtrOverPtrs.
1275 // Dereferencing an uninitialized iterator crashes the process.
TEST_F(RepeatedPtrFieldPtrsIteratorTest,UninitializedPtrIterator)1276 TEST_F(RepeatedPtrFieldPtrsIteratorTest, UninitializedPtrIterator) {
1277 RepeatedPtrField<string>::pointer_iterator iter;
1278 EXPECT_TRUE(iter != proto_array_.pointer_begin());
1279 EXPECT_TRUE(iter != proto_array_.pointer_begin() + 1);
1280 EXPECT_TRUE(iter != proto_array_.pointer_begin() + 2);
1281 EXPECT_TRUE(iter != proto_array_.pointer_begin() + 3);
1282 EXPECT_TRUE(iter != proto_array_.pointer_end());
1283 }
1284
TEST_F(RepeatedPtrFieldPtrsIteratorTest,UninitializedConstPtrIterator)1285 TEST_F(RepeatedPtrFieldPtrsIteratorTest, UninitializedConstPtrIterator) {
1286 RepeatedPtrField<string>::const_pointer_iterator iter;
1287 EXPECT_TRUE(iter != const_proto_array_->pointer_begin());
1288 EXPECT_TRUE(iter != const_proto_array_->pointer_begin() + 1);
1289 EXPECT_TRUE(iter != const_proto_array_->pointer_begin() + 2);
1290 EXPECT_TRUE(iter != const_proto_array_->pointer_begin() + 3);
1291 EXPECT_TRUE(iter != const_proto_array_->pointer_end());
1292 }
1293
1294 // This comparison functor is required by the tests for RepeatedPtrOverPtrs.
1295 // They operate on strings and need to compare strings as strings in
1296 // any stl algorithm, even though the iterator returns a pointer to a string
1297 // - i.e. *iter has type string*.
1298 struct StringLessThan {
operator ()google::protobuf::__anon34fc3b9d0111::StringLessThan1299 bool operator()(const string* z, const string& y) {
1300 return *z < y;
1301 }
operator ()google::protobuf::__anon34fc3b9d0111::StringLessThan1302 bool operator()(const string* z, const string* y) const { return *z < *y; }
1303 };
1304
TEST_F(RepeatedPtrFieldPtrsIteratorTest,PtrSTLAlgorithms_lower_bound)1305 TEST_F(RepeatedPtrFieldPtrsIteratorTest, PtrSTLAlgorithms_lower_bound) {
1306 proto_array_.Clear();
1307 proto_array_.Add()->assign("a");
1308 proto_array_.Add()->assign("c");
1309 proto_array_.Add()->assign("d");
1310 proto_array_.Add()->assign("n");
1311 proto_array_.Add()->assign("p");
1312 proto_array_.Add()->assign("x");
1313 proto_array_.Add()->assign("y");
1314
1315 {
1316 string v = "f";
1317 RepeatedPtrField<string>::pointer_iterator it =
1318 std::lower_bound(proto_array_.pointer_begin(),
1319 proto_array_.pointer_end(), &v, StringLessThan());
1320
1321 GOOGLE_CHECK(*it != NULL);
1322
1323 EXPECT_EQ(**it, "n");
1324 EXPECT_TRUE(it == proto_array_.pointer_begin() + 3);
1325 }
1326 {
1327 string v = "f";
1328 RepeatedPtrField<string>::const_pointer_iterator it = std::lower_bound(
1329 const_proto_array_->pointer_begin(), const_proto_array_->pointer_end(),
1330 &v, StringLessThan());
1331
1332 GOOGLE_CHECK(*it != NULL);
1333
1334 EXPECT_EQ(**it, "n");
1335 EXPECT_TRUE(it == const_proto_array_->pointer_begin() + 3);
1336 }
1337 }
1338
TEST_F(RepeatedPtrFieldPtrsIteratorTest,PtrMutation)1339 TEST_F(RepeatedPtrFieldPtrsIteratorTest, PtrMutation) {
1340 RepeatedPtrField<string>::pointer_iterator iter =
1341 proto_array_.pointer_begin();
1342 **iter = "qux";
1343 EXPECT_EQ("qux", proto_array_.Get(0));
1344
1345 EXPECT_EQ("bar", proto_array_.Get(1));
1346 EXPECT_EQ("baz", proto_array_.Get(2));
1347 ++iter;
1348 delete *iter;
1349 *iter = new string("a");
1350 ++iter;
1351 delete *iter;
1352 *iter = new string("b");
1353 EXPECT_EQ("a", proto_array_.Get(1));
1354 EXPECT_EQ("b", proto_array_.Get(2));
1355 }
1356
TEST_F(RepeatedPtrFieldPtrsIteratorTest,Sort)1357 TEST_F(RepeatedPtrFieldPtrsIteratorTest, Sort) {
1358 proto_array_.Add()->assign("c");
1359 proto_array_.Add()->assign("d");
1360 proto_array_.Add()->assign("n");
1361 proto_array_.Add()->assign("p");
1362 proto_array_.Add()->assign("a");
1363 proto_array_.Add()->assign("y");
1364 proto_array_.Add()->assign("x");
1365 EXPECT_EQ("foo", proto_array_.Get(0));
1366 EXPECT_EQ("n", proto_array_.Get(5));
1367 EXPECT_EQ("x", proto_array_.Get(9));
1368 std::sort(proto_array_.pointer_begin(), proto_array_.pointer_end(),
1369 StringLessThan());
1370 EXPECT_EQ("a", proto_array_.Get(0));
1371 EXPECT_EQ("baz", proto_array_.Get(2));
1372 EXPECT_EQ("y", proto_array_.Get(9));
1373 }
1374
1375
1376 // -----------------------------------------------------------------------------
1377 // Unit-tests for the insert iterators
1378 // google::protobuf::RepeatedFieldBackInserter,
1379 // google::protobuf::AllocatedRepeatedPtrFieldBackInserter
1380 // Ported from util/gtl/proto-array-iterators_unittest.
1381
1382 class RepeatedFieldInsertionIteratorsTest : public testing::Test {
1383 protected:
1384 std::list<double> halves;
1385 std::list<int> fibonacci;
1386 std::vector<string> words;
1387 typedef TestAllTypes::NestedMessage Nested;
1388 Nested nesteds[2];
1389 std::vector<Nested*> nested_ptrs;
1390 TestAllTypes protobuffer;
1391
SetUp()1392 virtual void SetUp() {
1393 fibonacci.push_back(1);
1394 fibonacci.push_back(1);
1395 fibonacci.push_back(2);
1396 fibonacci.push_back(3);
1397 fibonacci.push_back(5);
1398 fibonacci.push_back(8);
1399 std::copy(fibonacci.begin(), fibonacci.end(),
1400 RepeatedFieldBackInserter(protobuffer.mutable_repeated_int32()));
1401
1402 halves.push_back(1.0);
1403 halves.push_back(0.5);
1404 halves.push_back(0.25);
1405 halves.push_back(0.125);
1406 halves.push_back(0.0625);
1407 std::copy(halves.begin(), halves.end(),
1408 RepeatedFieldBackInserter(protobuffer.mutable_repeated_double()));
1409
1410 words.push_back("Able");
1411 words.push_back("was");
1412 words.push_back("I");
1413 words.push_back("ere");
1414 words.push_back("I");
1415 words.push_back("saw");
1416 words.push_back("Elba");
1417 std::copy(words.begin(), words.end(),
1418 RepeatedFieldBackInserter(protobuffer.mutable_repeated_string()));
1419
1420 nesteds[0].set_bb(17);
1421 nesteds[1].set_bb(4711);
1422 std::copy(&nesteds[0], &nesteds[2],
1423 RepeatedFieldBackInserter(
1424 protobuffer.mutable_repeated_nested_message()));
1425
1426 nested_ptrs.push_back(new Nested);
1427 nested_ptrs.back()->set_bb(170);
1428 nested_ptrs.push_back(new Nested);
1429 nested_ptrs.back()->set_bb(47110);
1430 std::copy(nested_ptrs.begin(), nested_ptrs.end(),
1431 RepeatedFieldBackInserter(
1432 protobuffer.mutable_repeated_nested_message()));
1433 }
1434
TearDown()1435 virtual void TearDown() {
1436 STLDeleteContainerPointers(nested_ptrs.begin(), nested_ptrs.end());
1437 }
1438 };
1439
TEST_F(RepeatedFieldInsertionIteratorsTest,Fibonacci)1440 TEST_F(RepeatedFieldInsertionIteratorsTest, Fibonacci) {
1441 EXPECT_TRUE(std::equal(fibonacci.begin(),
1442 fibonacci.end(),
1443 protobuffer.repeated_int32().begin()));
1444 EXPECT_TRUE(std::equal(protobuffer.repeated_int32().begin(),
1445 protobuffer.repeated_int32().end(),
1446 fibonacci.begin()));
1447 }
1448
TEST_F(RepeatedFieldInsertionIteratorsTest,Halves)1449 TEST_F(RepeatedFieldInsertionIteratorsTest, Halves) {
1450 EXPECT_TRUE(std::equal(halves.begin(),
1451 halves.end(),
1452 protobuffer.repeated_double().begin()));
1453 EXPECT_TRUE(std::equal(protobuffer.repeated_double().begin(),
1454 protobuffer.repeated_double().end(),
1455 halves.begin()));
1456 }
1457
TEST_F(RepeatedFieldInsertionIteratorsTest,Words)1458 TEST_F(RepeatedFieldInsertionIteratorsTest, Words) {
1459 ASSERT_EQ(words.size(), protobuffer.repeated_string_size());
1460 for (int i = 0; i < words.size(); ++i)
1461 EXPECT_EQ(words.at(i), protobuffer.repeated_string(i));
1462 }
1463
TEST_F(RepeatedFieldInsertionIteratorsTest,Words2)1464 TEST_F(RepeatedFieldInsertionIteratorsTest, Words2) {
1465 words.clear();
1466 words.push_back("sing");
1467 words.push_back("a");
1468 words.push_back("song");
1469 words.push_back("of");
1470 words.push_back("six");
1471 words.push_back("pence");
1472 protobuffer.mutable_repeated_string()->Clear();
1473 std::copy(words.begin(), words.end(), RepeatedPtrFieldBackInserter(
1474 protobuffer.mutable_repeated_string()));
1475 ASSERT_EQ(words.size(), protobuffer.repeated_string_size());
1476 for (int i = 0; i < words.size(); ++i)
1477 EXPECT_EQ(words.at(i), protobuffer.repeated_string(i));
1478 }
1479
TEST_F(RepeatedFieldInsertionIteratorsTest,Nesteds)1480 TEST_F(RepeatedFieldInsertionIteratorsTest, Nesteds) {
1481 ASSERT_EQ(protobuffer.repeated_nested_message_size(), 4);
1482 EXPECT_EQ(protobuffer.repeated_nested_message(0).bb(), 17);
1483 EXPECT_EQ(protobuffer.repeated_nested_message(1).bb(), 4711);
1484 EXPECT_EQ(protobuffer.repeated_nested_message(2).bb(), 170);
1485 EXPECT_EQ(protobuffer.repeated_nested_message(3).bb(), 47110);
1486 }
1487
TEST_F(RepeatedFieldInsertionIteratorsTest,AllocatedRepeatedPtrFieldWithStringIntData)1488 TEST_F(RepeatedFieldInsertionIteratorsTest,
1489 AllocatedRepeatedPtrFieldWithStringIntData) {
1490 vector<Nested*> data;
1491 TestAllTypes goldenproto;
1492 for (int i = 0; i < 10; ++i) {
1493 Nested* new_data = new Nested;
1494 new_data->set_bb(i);
1495 data.push_back(new_data);
1496
1497 new_data = goldenproto.add_repeated_nested_message();
1498 new_data->set_bb(i);
1499 }
1500 TestAllTypes testproto;
1501 std::copy(data.begin(), data.end(),
1502 AllocatedRepeatedPtrFieldBackInserter(
1503 testproto.mutable_repeated_nested_message()));
1504 EXPECT_EQ(testproto.DebugString(), goldenproto.DebugString());
1505 }
1506
TEST_F(RepeatedFieldInsertionIteratorsTest,AllocatedRepeatedPtrFieldWithString)1507 TEST_F(RepeatedFieldInsertionIteratorsTest,
1508 AllocatedRepeatedPtrFieldWithString) {
1509 vector<string*> data;
1510 TestAllTypes goldenproto;
1511 for (int i = 0; i < 10; ++i) {
1512 string* new_data = new string;
1513 *new_data = "name-" + SimpleItoa(i);
1514 data.push_back(new_data);
1515
1516 new_data = goldenproto.add_repeated_string();
1517 *new_data = "name-" + SimpleItoa(i);
1518 }
1519 TestAllTypes testproto;
1520 std::copy(data.begin(), data.end(), AllocatedRepeatedPtrFieldBackInserter(
1521 testproto.mutable_repeated_string()));
1522 EXPECT_EQ(testproto.DebugString(), goldenproto.DebugString());
1523 }
1524
TEST_F(RepeatedFieldInsertionIteratorsTest,UnsafeArenaAllocatedRepeatedPtrFieldWithStringIntData)1525 TEST_F(RepeatedFieldInsertionIteratorsTest,
1526 UnsafeArenaAllocatedRepeatedPtrFieldWithStringIntData) {
1527 vector<Nested*> data;
1528 TestAllTypes goldenproto;
1529 for (int i = 0; i < 10; ++i) {
1530 Nested* new_data = new Nested;
1531 new_data->set_bb(i);
1532 data.push_back(new_data);
1533
1534 new_data = goldenproto.add_repeated_nested_message();
1535 new_data->set_bb(i);
1536 }
1537 TestAllTypes testproto;
1538 std::copy(data.begin(), data.end(),
1539 UnsafeArenaAllocatedRepeatedPtrFieldBackInserter(
1540 testproto.mutable_repeated_nested_message()));
1541 EXPECT_EQ(testproto.DebugString(), goldenproto.DebugString());
1542 }
1543
TEST_F(RepeatedFieldInsertionIteratorsTest,UnsafeArenaAllocatedRepeatedPtrFieldWithString)1544 TEST_F(RepeatedFieldInsertionIteratorsTest,
1545 UnsafeArenaAllocatedRepeatedPtrFieldWithString) {
1546 vector<string*> data;
1547 TestAllTypes goldenproto;
1548 for (int i = 0; i < 10; ++i) {
1549 string* new_data = new string;
1550 *new_data = "name-" + SimpleItoa(i);
1551 data.push_back(new_data);
1552
1553 new_data = goldenproto.add_repeated_string();
1554 *new_data = "name-" + SimpleItoa(i);
1555 }
1556 TestAllTypes testproto;
1557 std::copy(data.begin(), data.end(),
1558 UnsafeArenaAllocatedRepeatedPtrFieldBackInserter(
1559 testproto.mutable_repeated_string()));
1560 EXPECT_EQ(testproto.DebugString(), goldenproto.DebugString());
1561 }
1562
1563 } // namespace
1564
1565 } // namespace protobuf
1566 } // namespace google
1567