1 /*
2 * Copyright (C) 2016 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include "gtest/gtest.h"
18
19 #include "chre/util/dynamic_vector.h"
20 #include "chre/util/macros.h"
21
22 #include <stdint.h>
23
24 using chre::DynamicVector;
25
26 namespace {
27 constexpr int kMaxTestCapacity = 10;
28 int gDestructorCount[kMaxTestCapacity];
29
30 class Dummy {
31 public:
~Dummy()32 ~Dummy() {
33 if (mValue >= 0) {
34 gDestructorCount[mValue]++;
35 }
36 };
setValue(int value)37 void setValue(int value) {
38 mValue = value;
39 }
getValue()40 int getValue() {
41 return mValue;
42 }
43
44 private:
45 int mValue = -1;
46 };
47
resetDestructorCounts()48 void resetDestructorCounts() {
49 for (size_t i = 0; i < ARRAY_SIZE(gDestructorCount); i++) {
50 gDestructorCount[i] = 0;
51 }
52 }
53 }
54
TEST(DynamicVector,EmptyByDefault)55 TEST(DynamicVector, EmptyByDefault) {
56 DynamicVector<int> vector;
57 EXPECT_EQ(vector.data(), nullptr);
58 EXPECT_TRUE(vector.empty());
59 EXPECT_EQ(vector.size(), 0);
60 EXPECT_EQ(vector.capacity(), 0);
61 vector.clear();
62 }
63
TEST(DynamicVector,PushBackAndRead)64 TEST(DynamicVector, PushBackAndRead) {
65 DynamicVector<int> vector;
66 ASSERT_TRUE(vector.push_back(0x1337));
67 EXPECT_EQ(vector.size(), 1);
68 EXPECT_EQ(vector.capacity(), 1);
69 EXPECT_EQ(vector.data(), &vector[0]);
70 EXPECT_FALSE(vector.empty());
71 EXPECT_EQ(vector[0], 0x1337);
72 }
73
TEST(DynamicVector,PushBackReserveAndReadTrivialType)74 TEST(DynamicVector, PushBackReserveAndReadTrivialType) {
75 DynamicVector<int> vector;
76 ASSERT_TRUE(vector.emplace_back(0x1337));
77 ASSERT_TRUE(vector.push_back(0xface));
78 int x = 0xcafe;
79 ASSERT_TRUE(vector.push_back(std::move(x)));
80 ASSERT_TRUE(vector.insert(vector.size(), 0xd00d));
81 EXPECT_EQ(vector.size(), 4);
82 EXPECT_EQ(vector.capacity(), 4);
83 EXPECT_EQ(vector[0], 0x1337);
84 EXPECT_EQ(vector[1], 0xface);
85 EXPECT_EQ(vector[2], 0xcafe);
86 EXPECT_EQ(vector[3], 0xd00d);
87
88 ASSERT_TRUE(vector.reserve(8));
89 EXPECT_EQ(vector.size(), 4);
90 EXPECT_EQ(vector.capacity(), 8);
91 EXPECT_EQ(vector[0], 0x1337);
92 EXPECT_EQ(vector[1], 0xface);
93 EXPECT_EQ(vector[2], 0xcafe);
94 EXPECT_EQ(vector[3], 0xd00d);
95 }
96
TEST(DynamicVector,CompareEqual)97 TEST(DynamicVector, CompareEqual) {
98 DynamicVector<int> lhs;
99 ASSERT_TRUE(lhs.push_back(0x1337));
100 ASSERT_TRUE(lhs.push_back(0xface));
101 DynamicVector<int> rhs;
102 ASSERT_TRUE(rhs.push_back(0x1337));
103 ASSERT_TRUE(rhs.push_back(0xface));
104
105 ASSERT_EQ(lhs, rhs); // equal vectors
106
107 ASSERT_TRUE(lhs.push_back(0xb00c));
108 ASSERT_FALSE(lhs == rhs); // different size
109
110 ASSERT_TRUE(rhs.push_back(0xc00b));
111 ASSERT_FALSE(lhs == rhs); // equal size different elements
112 }
113
114 constexpr int kConstructedMagic = 0xdeadbeef;
115
116 class MovableButNonCopyable : public chre::NonCopyable {
117 public:
MovableButNonCopyable(int value)118 MovableButNonCopyable(int value) : mValue(value) {}
119
MovableButNonCopyable(MovableButNonCopyable && other)120 MovableButNonCopyable(MovableButNonCopyable&& other) {
121 mValue = other.mValue;
122 other.mValue = -1;
123 }
124
operator =(MovableButNonCopyable && other)125 MovableButNonCopyable& operator=(MovableButNonCopyable&& other) {
126 assert(mMagic == kConstructedMagic);
127 mValue = other.mValue;
128 other.mValue = -1;
129 return *this;
130 }
131
getValue() const132 int getValue() const {
133 return mValue;
134 }
135
136 private:
137 int mMagic = kConstructedMagic;
138 int mValue;
139 };
140
TEST(DynamicVector,PushBackReserveAndReadMovableButNonCopyable)141 TEST(DynamicVector, PushBackReserveAndReadMovableButNonCopyable) {
142 DynamicVector<MovableButNonCopyable> vector;
143 ASSERT_TRUE(vector.emplace_back(0x1337));
144 ASSERT_TRUE(vector.emplace_back(0xface));
145 MovableButNonCopyable mbnc(0xcafe);
146 ASSERT_TRUE(vector.push_back(std::move(mbnc)));
147 EXPECT_EQ(mbnc.getValue(), -1);
148 MovableButNonCopyable mbnc2(0xd00d);
149 ASSERT_TRUE(vector.insert(vector.size(), std::move(mbnc2)));
150 EXPECT_EQ(mbnc2.getValue(), -1);
151
152 ASSERT_TRUE(vector.reserve(8));
153 EXPECT_EQ(vector[0].getValue(), 0x1337);
154 EXPECT_EQ(vector[1].getValue(), 0xface);
155 EXPECT_EQ(vector[2].getValue(), 0xcafe);
156 EXPECT_EQ(vector[3].getValue(), 0xd00d);
157 EXPECT_EQ(vector.size(), 4);
158 EXPECT_EQ(vector.capacity(), 8);
159 }
160
161 class CopyableButNonMovable {
162 public:
CopyableButNonMovable(int value)163 CopyableButNonMovable(int value) : mValue(value) {}
164
CopyableButNonMovable(const CopyableButNonMovable & other)165 CopyableButNonMovable(const CopyableButNonMovable& other) {
166 mValue = other.mValue;
167 }
168
operator =(const CopyableButNonMovable & other)169 CopyableButNonMovable& operator=(const CopyableButNonMovable& other) {
170 assert(mMagic == kConstructedMagic);
171 mValue = other.mValue;
172 return *this;
173 }
174
175 CopyableButNonMovable(CopyableButNonMovable&& other) = delete;
176 CopyableButNonMovable& operator=(CopyableButNonMovable&& other) = delete;
177
getValue() const178 int getValue() const {
179 return mValue;
180 }
181
182 private:
183 int mMagic = kConstructedMagic;
184 int mValue;
185 };
186
TEST(DynamicVector,PushBackReserveAndReadCopyableButNonMovable)187 TEST(DynamicVector, PushBackReserveAndReadCopyableButNonMovable) {
188 DynamicVector<CopyableButNonMovable> vector;
189 ASSERT_TRUE(vector.emplace_back(0x1337));
190 ASSERT_TRUE(vector.emplace_back(0xface));
191 CopyableButNonMovable cbnm(0xcafe);
192 ASSERT_TRUE(vector.push_back(cbnm));
193 CopyableButNonMovable cbnm2(0xd00d);
194 ASSERT_TRUE(vector.insert(vector.size(), cbnm2));
195
196 ASSERT_TRUE(vector.reserve(8));
197 EXPECT_EQ(vector[0].getValue(), 0x1337);
198 EXPECT_EQ(vector[1].getValue(), 0xface);
199 EXPECT_EQ(vector[2].getValue(), 0xcafe);
200 EXPECT_EQ(vector[3].getValue(), 0xd00d);
201 EXPECT_EQ(vector.size(), 4);
202 EXPECT_EQ(vector.capacity(), 8);
203 }
204
205 class MovableAndCopyable {
206 public:
MovableAndCopyable(int value)207 MovableAndCopyable(int value) : mValue(value) {}
208
MovableAndCopyable(const MovableAndCopyable & other)209 MovableAndCopyable(const MovableAndCopyable& other) {
210 mValue = other.mValue;
211 }
212
MovableAndCopyable(MovableAndCopyable && other)213 MovableAndCopyable(MovableAndCopyable&& other) {
214 // The move constructor multiplies the value by 2 so that we can see that it
215 // was used
216 mValue = other.mValue * 2;
217 }
218
operator =(const MovableAndCopyable & other)219 MovableAndCopyable& operator=(const MovableAndCopyable& other) {
220 assert(mMagic == kConstructedMagic);
221 mValue = other.mValue;
222 return *this;
223 }
224
operator =(MovableAndCopyable && other)225 MovableAndCopyable& operator=(MovableAndCopyable&& other) {
226 assert(mMagic == kConstructedMagic);
227 mValue = other.mValue * 2;
228 other.mValue = -1;
229 return *this;
230 }
231
getValue() const232 int getValue() const {
233 return mValue;
234 }
235
236 private:
237 int mMagic = kConstructedMagic;
238 int mValue;
239 };
240
TEST(DynamicVector,ReservePrefersMove)241 TEST(DynamicVector, ReservePrefersMove) {
242 // Ensure that preference is given to std::move in reserve()
243 DynamicVector<MovableAndCopyable> vector;
244
245 // Reserve enough space for the first two elements.
246 ASSERT_TRUE(vector.reserve(2));
247 ASSERT_TRUE(vector.emplace_back(1000));
248 ASSERT_TRUE(vector.emplace_back(2000));
249
250 // Reserve more than enough space causing a move to be required.
251 ASSERT_TRUE(vector.reserve(4));
252
253 // Move on this type results in a multiplication by 2. Verify that all
254 // elements have been multiplied by 2.
255 EXPECT_EQ(vector[0].getValue(), 2000);
256 EXPECT_EQ(vector[1].getValue(), 4000);
257 }
258
259 /**
260 * A simple test helper object to count number of construction and destructions.
261 */
262 class Foo {
263 public:
264 /**
265 * Construct an object storing a simple integer. Increment the number of
266 * objects that have been constructed of this type.
267 */
Foo(int value)268 Foo(int value) : value(value) {
269 sConstructedCounter++;
270 }
271
Foo(const Foo & other)272 Foo(const Foo& other) {
273 value = other.value;
274 sConstructedCounter++;
275 }
276
277 Foo(Foo&& other) = delete;
278
279 /**
280 * Tear down the object, decrementing the number of objects that have been
281 * constructed of this type.
282 */
~Foo()283 ~Foo() {
284 sConstructedCounter--;
285 }
286
287 //! The number of objects of this type that have been constructed.
288 static ssize_t sConstructedCounter;
289
290 //! The value stored in the object to verify the contents of this object after
291 //! construction.
292 int value;
293 };
294
295 //! Storage for the Foo reference counter.
296 ssize_t Foo::sConstructedCounter = 0;
297
TEST(DynamicVector,EmplaceBackAndDestruct)298 TEST(DynamicVector, EmplaceBackAndDestruct) {
299 Foo::sConstructedCounter = 0;
300 {
301 DynamicVector<Foo> vector;
302 ASSERT_TRUE(vector.emplace_back(1000));
303 ASSERT_TRUE(vector.emplace_back(2000));
304 ASSERT_TRUE(vector.emplace_back(3000));
305 ASSERT_TRUE(vector.emplace_back(4000));
306
307 ASSERT_EQ(vector[0].value, 1000);
308 ASSERT_EQ(vector[1].value, 2000);
309 ASSERT_EQ(vector[2].value, 3000);
310 ASSERT_EQ(vector[3].value, 4000);
311
312 EXPECT_EQ(Foo::sConstructedCounter, 4);
313 }
314
315 EXPECT_EQ(Foo::sConstructedCounter, 0);
316 }
317
TEST(DynamicVector,InsertEmpty)318 TEST(DynamicVector, InsertEmpty) {
319 DynamicVector<int> vector;
320 EXPECT_CHRE_ASSERT(EXPECT_FALSE(vector.insert(1, 0x1337)));
321
322 // Insert to empty vector
323 ASSERT_TRUE(vector.insert(0, 0x1337));
324 EXPECT_EQ(vector[0], 0x1337);
325
326 // Insert at end triggering grow
327 ASSERT_EQ(vector.capacity(), 1);
328 EXPECT_TRUE(vector.insert(1, 0xface));
329 EXPECT_EQ(vector[0], 0x1337);
330 EXPECT_EQ(vector[1], 0xface);
331
332 // Insert at beginning triggering grow
333 ASSERT_EQ(vector.capacity(), 2);
334 EXPECT_TRUE(vector.insert(0, 0xcafe));
335 EXPECT_EQ(vector[0], 0xcafe);
336 EXPECT_EQ(vector[1], 0x1337);
337 EXPECT_EQ(vector[2], 0xface);
338
339 // Insert at middle with spare capacity
340 ASSERT_EQ(vector.capacity(), 4);
341 EXPECT_TRUE(vector.insert(1, 0xdead));
342 EXPECT_EQ(vector[0], 0xcafe);
343 EXPECT_EQ(vector[1], 0xdead);
344 EXPECT_EQ(vector[2], 0x1337);
345 EXPECT_EQ(vector[3], 0xface);
346
347 // Insert at middle triggering grow
348 ASSERT_EQ(vector.capacity(), 4);
349 EXPECT_TRUE(vector.insert(2, 0xbeef));
350 EXPECT_EQ(vector[0], 0xcafe);
351 EXPECT_EQ(vector[1], 0xdead);
352 EXPECT_EQ(vector[2], 0xbeef);
353 EXPECT_EQ(vector[3], 0x1337);
354 EXPECT_EQ(vector[4], 0xface);
355
356 // Insert at beginning with spare capacity
357 ASSERT_EQ(vector.capacity(), 8);
358 ASSERT_EQ(vector.size(), 5);
359 EXPECT_TRUE(vector.insert(0, 0xabad));
360 EXPECT_EQ(vector[0], 0xabad);
361 EXPECT_EQ(vector[1], 0xcafe);
362 EXPECT_EQ(vector[2], 0xdead);
363 EXPECT_EQ(vector[3], 0xbeef);
364 EXPECT_EQ(vector[4], 0x1337);
365 EXPECT_EQ(vector[5], 0xface);
366
367 // Insert at end with spare capacity
368 ASSERT_EQ(vector.size(), 6);
369 EXPECT_TRUE(vector.insert(vector.size(), 0xc0de));
370 EXPECT_EQ(vector[0], 0xabad);
371 EXPECT_EQ(vector[1], 0xcafe);
372 EXPECT_EQ(vector[2], 0xdead);
373 EXPECT_EQ(vector[3], 0xbeef);
374 EXPECT_EQ(vector[4], 0x1337);
375 EXPECT_EQ(vector[5], 0xface);
376 EXPECT_EQ(vector[6], 0xc0de);
377 }
378
TEST(DynamicVector,PushBackInsertInMiddleAndRead)379 TEST(DynamicVector, PushBackInsertInMiddleAndRead) {
380 DynamicVector<int> vector;
381 ASSERT_TRUE(vector.push_back(0x1337));
382 ASSERT_TRUE(vector.push_back(0xface));
383 ASSERT_TRUE(vector.push_back(0xcafe));
384 ASSERT_TRUE(vector.insert(1, 0xbeef));
385
386 ASSERT_EQ(vector[0], 0x1337);
387 ASSERT_EQ(vector[1], 0xbeef);
388 ASSERT_EQ(vector[2], 0xface);
389 ASSERT_EQ(vector[3], 0xcafe);
390 }
391
TEST(DynamicVector,PushBackAndErase)392 TEST(DynamicVector, PushBackAndErase) {
393 DynamicVector<int> vector;
394 ASSERT_TRUE(vector.push_back(0x1337));
395 ASSERT_TRUE(vector.push_back(0xcafe));
396 ASSERT_TRUE(vector.push_back(0xbeef));
397 ASSERT_TRUE(vector.push_back(0xface));
398
399 vector.erase(1);
400
401 ASSERT_EQ(vector[0], 0x1337);
402 ASSERT_EQ(vector[1], 0xbeef);
403 ASSERT_EQ(vector[2], 0xface);
404 ASSERT_EQ(vector.size(), 3);
405 }
406
TEST(DynamicVector,FindEmpty)407 TEST(DynamicVector, FindEmpty) {
408 DynamicVector<int> vector;
409 ASSERT_EQ(vector.find(0), 0);
410 }
411
TEST(DynamicVector,FindWithElements)412 TEST(DynamicVector, FindWithElements) {
413 DynamicVector<int> vector;
414 ASSERT_TRUE(vector.push_back(0x1337));
415 ASSERT_TRUE(vector.push_back(0xcafe));
416 ASSERT_TRUE(vector.push_back(0xbeef));
417
418 ASSERT_EQ(vector.find(0x1337), 0);
419 ASSERT_EQ(vector.find(0xcafe), 1);
420 ASSERT_EQ(vector.find(0xbeef), 2);
421 ASSERT_EQ(vector.find(1000), 3);
422 }
423
TEST(DynamicVector,EraseDestructorCalled)424 TEST(DynamicVector, EraseDestructorCalled) {
425 resetDestructorCounts();
426
427 DynamicVector<Dummy> vector;
428 vector.reserve(4);
429 for (size_t i = 0; i < 4; ++i) {
430 vector.emplace_back();
431 vector[i].setValue(i);
432 }
433
434 // last item before erase is '3'.
435 vector.erase(1);
436 EXPECT_EQ(0, gDestructorCount[0]);
437 EXPECT_EQ(0, gDestructorCount[1]);
438 EXPECT_EQ(0, gDestructorCount[2]);
439 EXPECT_EQ(1, gDestructorCount[3]);
440
441 // last item before erase is still '3'.
442 vector.erase(2);
443 EXPECT_EQ(0, gDestructorCount[0]);
444 EXPECT_EQ(0, gDestructorCount[1]);
445 EXPECT_EQ(0, gDestructorCount[2]);
446 EXPECT_EQ(2, gDestructorCount[3]);
447
448 // last item before erase is now '2'.
449 vector.erase(0);
450 EXPECT_EQ(0, gDestructorCount[0]);
451 EXPECT_EQ(0, gDestructorCount[1]);
452 EXPECT_EQ(1, gDestructorCount[2]);
453 EXPECT_EQ(2, gDestructorCount[3]);
454 }
455
TEST(DynamicVector,Clear)456 TEST(DynamicVector, Clear) {
457 resetDestructorCounts();
458
459 DynamicVector<Dummy> vector;
460 vector.reserve(4);
461 for (size_t i = 0; i < 4; ++i) {
462 vector.emplace_back();
463 vector[i].setValue(i);
464 }
465
466 vector.clear();
467 EXPECT_EQ(vector.size(), 0);
468 EXPECT_EQ(vector.capacity(), 4);
469
470 for (size_t i = 0; i < 4; ++i) {
471 EXPECT_EQ(gDestructorCount[i], 1);
472 }
473 }
474
475 // Make sure that a vector wrapping an array doesn't call the destructor when
476 // the vector is destructed
TEST(DynamicVector,WrapDoesntCallDestructor)477 TEST(DynamicVector, WrapDoesntCallDestructor) {
478 resetDestructorCounts();
479
480 Dummy array[4];
481 for (size_t i = 0; i < 4; ++i) {
482 array[i].setValue(i);
483 }
484
485 {
486 DynamicVector<Dummy> vector;
487 vector.wrap(array, ARRAY_SIZE(array));
488 }
489
490 for (size_t i = 0; i < 4; ++i) {
491 EXPECT_EQ(gDestructorCount[i], 0);
492 }
493 }
494
495 // Make sure that a wrapped vector does call the destructor when it's expected
496 // as part of an API call
TEST(DynamicVector,WrapExplicitlyCallsDestructor)497 TEST(DynamicVector, WrapExplicitlyCallsDestructor) {
498 resetDestructorCounts();
499
500 Dummy array[4];
501 constexpr size_t kSize = ARRAY_SIZE(array);
502 static_assert(ARRAY_SIZE(array) <= ARRAY_SIZE(gDestructorCount),
503 "gDestructorCount array must fit test array");
504 for (size_t i = 0; i < kSize; ++i) {
505 array[i].setValue(i);
506 }
507 DynamicVector<Dummy> vector;
508 vector.wrap(array, ARRAY_SIZE(array));
509
510 vector.erase(kSize - 1);
511 for (size_t i = 0; i < kSize - 1; i++) {
512 EXPECT_EQ(gDestructorCount[i], 0);
513 }
514 EXPECT_EQ(gDestructorCount[kSize - 1], 1);
515
516 vector.clear();
517 for (size_t i = 0; i < kSize; ++i) {
518 EXPECT_EQ(gDestructorCount[i], 1);
519 }
520 }
521
TEST(DynamicVectorDeathTest,SwapWithInvalidIndex)522 TEST(DynamicVectorDeathTest, SwapWithInvalidIndex) {
523 DynamicVector<int> vector;
524 vector.push_back(0x1337);
525 vector.push_back(0xcafe);
526 EXPECT_DEATH(vector.swap(0, 2), "");
527 }
528
TEST(DynamicVectorDeathTest,SwapWithInvalidIndices)529 TEST(DynamicVectorDeathTest, SwapWithInvalidIndices) {
530 DynamicVector<int> vector;
531 vector.push_back(0x1337);
532 vector.push_back(0xcafe);
533 EXPECT_DEATH(vector.swap(2, 3), "");
534 }
535
TEST(DynamicVector,Swap)536 TEST(DynamicVector, Swap) {
537 DynamicVector<int> vector;
538 vector.push_back(0x1337);
539 vector.push_back(0xcafe);
540
541 vector.swap(0, 1);
542 EXPECT_EQ(vector[0], 0xcafe);
543 EXPECT_EQ(vector[1], 0x1337);
544 }
545
TEST(DynamicVector,BackFront)546 TEST(DynamicVector, BackFront) {
547 DynamicVector<int> vector;
548 vector.push_back(0x1337);
549 EXPECT_EQ(vector.front(), 0x1337);
550 EXPECT_EQ(vector.back(), 0x1337);
551 vector.push_back(0xcafe);
552 EXPECT_EQ(vector.front(), 0x1337);
553 EXPECT_EQ(vector.back(), 0xcafe);
554 vector.erase(0);
555 EXPECT_EQ(vector.front(), 0xcafe);
556 EXPECT_EQ(vector.back(), 0xcafe);
557 }
558
TEST(DynamicVector,Iterator)559 TEST(DynamicVector, Iterator) {
560 DynamicVector<int> vector;
561 vector.push_back(0);
562 vector.push_back(1);
563 vector.push_back(2);
564
565 size_t index = 0;
566 for (DynamicVector<int>::iterator it = vector.begin();
567 it != vector.end(); ++it) {
568 EXPECT_EQ(vector[index++], *it);
569 }
570
571 DynamicVector<int>::iterator it = vector.begin() + vector.size() - 1;
572 EXPECT_EQ(vector[vector.size() - 1], *it);
573
574 it = vector.begin() + vector.size();
575 EXPECT_TRUE(it == vector.end());
576 }
577
TEST(DynamicVector,ConstIterator)578 TEST(DynamicVector, ConstIterator) {
579 DynamicVector<int> vector;
580 vector.push_back(0);
581 vector.push_back(1);
582 vector.push_back(2);
583
584 size_t index = 0;
585 for (DynamicVector<int>::const_iterator cit = vector.cbegin();
586 cit != vector.cend(); ++cit) {
587 EXPECT_EQ(vector[index++], *cit);
588 }
589
590 DynamicVector<int>::const_iterator cit = vector.cbegin() + vector.size() - 1;
591 EXPECT_EQ(vector[vector.size() - 1], *cit);
592
593 cit = vector.cbegin() + vector.size();
594 EXPECT_TRUE(cit == vector.cend());
595 }
596
TEST(DynamicVector,IteratorAndPushBack)597 TEST(DynamicVector, IteratorAndPushBack) {
598 DynamicVector<int> vector;
599 vector.push_back(0);
600 vector.push_back(1);
601 vector.push_back(2);
602 size_t oldCapacity = vector.capacity();
603
604 DynamicVector<int>::iterator it_b = vector.begin();
605 DynamicVector<int>::iterator it_e = vector.end();
606
607 vector.push_back(3);
608 ASSERT_TRUE(oldCapacity == vector.capacity());
609
610 size_t index = 0;
611 for (; it_b != it_e; ++it_b) {
612 EXPECT_EQ(vector[index++], *it_b);
613 }
614 }
615
TEST(DynamicVector,IteratorAndEmplaceBack)616 TEST(DynamicVector, IteratorAndEmplaceBack) {
617 DynamicVector<int> vector;
618 vector.push_back(0);
619 vector.push_back(1);
620 vector.push_back(2);
621 size_t oldCapacity = vector.capacity();
622
623 DynamicVector<int>::iterator it_b = vector.begin();
624 DynamicVector<int>::iterator it_e = vector.end();
625
626 vector.emplace_back(3);
627 ASSERT_TRUE(oldCapacity == vector.capacity());
628
629 size_t index = 0;
630 for (; it_b != it_e; ++it_b) {
631 EXPECT_EQ(vector[index++], *it_b);
632 }
633 }
634
TEST(DynamicVector,IteratorAndReserve)635 TEST(DynamicVector, IteratorAndReserve) {
636 DynamicVector<int> vector;
637 vector.push_back(0);
638 vector.push_back(1);
639 vector.push_back(2);
640 size_t oldCapacity = vector.capacity();
641
642 DynamicVector<int>::iterator it_b = vector.begin();
643 DynamicVector<int>::iterator it_e = vector.end();
644
645 vector.reserve(oldCapacity);
646 ASSERT_TRUE(oldCapacity == vector.capacity());
647
648 size_t index = 0;
649 for (; it_b != it_e; ++it_b) {
650 EXPECT_EQ(vector[index++], *it_b);
651 }
652 }
653
TEST(DynamicVector,IteratorAndInsert)654 TEST(DynamicVector, IteratorAndInsert) {
655 DynamicVector<int> vector;
656 vector.push_back(0);
657 vector.push_back(1);
658 vector.push_back(2);
659 size_t oldCapacity = vector.capacity();
660
661 DynamicVector<int>::iterator it_b = vector.begin();
662
663 vector.insert(2, 3);
664 ASSERT_TRUE(oldCapacity == vector.capacity());
665
666 size_t index = 0;
667 while (index < 2) {
668 EXPECT_EQ(vector[index++], *it_b++);
669 }
670 }
671
TEST(DynamicVector,IteratorAndErase)672 TEST(DynamicVector, IteratorAndErase) {
673 DynamicVector<int> vector;
674 vector.push_back(0);
675 vector.push_back(1);
676 vector.push_back(2);
677
678 DynamicVector<int>::iterator it_b = vector.begin();
679
680 vector.erase(2);
681
682 size_t index = 0;
683 while (index < 2) {
684 EXPECT_EQ(vector[index++], *it_b++);
685 }
686 }
687
TEST(DynamicVector,IteratorAndSwap)688 TEST(DynamicVector, IteratorAndSwap) {
689 DynamicVector<int> vector;
690 vector.push_back(0);
691 vector.push_back(1);
692 vector.push_back(2);
693 vector.push_back(3);
694
695 DynamicVector<int>::iterator it_b = vector.begin();
696
697 vector.swap(1, 3);
698
699 size_t index = 0;
700 while (index < 4) {
701 if (index != 1 && index != 3) {
702 EXPECT_EQ(vector[index], *it_b);
703 }
704 index++;
705 it_b++;
706 }
707 }
708
TEST(DynamicVector,MoveConstruct)709 TEST(DynamicVector, MoveConstruct) {
710 DynamicVector<int> vector;
711 ASSERT_TRUE(vector.push_back(0));
712 ASSERT_TRUE(vector.push_back(1));
713 ASSERT_TRUE(vector.push_back(2));
714
715 DynamicVector<int> movedVector(std::move(vector));
716 EXPECT_EQ(vector.data(), nullptr);
717 EXPECT_NE(movedVector.data(), nullptr);
718 EXPECT_EQ(vector.size(), 0);
719 EXPECT_EQ(movedVector.size(), 3);
720 EXPECT_EQ(vector.capacity(), 0);
721 EXPECT_EQ(movedVector.capacity(), 4);
722 }
723
TEST(DynamicVector,MoveAssignmentConstruct)724 TEST(DynamicVector, MoveAssignmentConstruct) {
725 DynamicVector<int> vector;
726 ASSERT_TRUE(vector.push_back(0));
727 ASSERT_TRUE(vector.push_back(1));
728 ASSERT_TRUE(vector.push_back(2));
729
730 DynamicVector<int> movedVector;
731 movedVector = std::move(vector);
732 EXPECT_EQ(vector.data(), nullptr);
733 EXPECT_NE(movedVector.data(), nullptr);
734 EXPECT_EQ(vector.size(), 0);
735 EXPECT_EQ(movedVector.size(), 3);
736 EXPECT_EQ(vector.capacity(), 0);
737 EXPECT_EQ(movedVector.capacity(), 4);
738 }
739
740 // Tests basic functionality of a vector wrapping an array
TEST(DynamicVector,Wrap)741 TEST(DynamicVector, Wrap) {
742 constexpr size_t kSize = 4;
743 int buf[kSize];
744 for (size_t i = 0; i < kSize; i++) {
745 buf[i] = i;
746 }
747
748 DynamicVector<int> vector;
749 EXPECT_TRUE(vector.owns_data());
750 vector.wrap(buf, kSize);
751 EXPECT_FALSE(vector.owns_data());
752 EXPECT_EQ(vector.size(), kSize);
753 EXPECT_EQ(vector.capacity(), kSize);
754 EXPECT_EQ(vector.data(), buf);
755
756 EXPECT_CHRE_ASSERT(EXPECT_FALSE(vector.reserve(8)));
757 EXPECT_CHRE_ASSERT(EXPECT_FALSE(vector.push_back(-1)));
758 EXPECT_CHRE_ASSERT(EXPECT_FALSE(vector.emplace_back(-1)));
759 EXPECT_CHRE_ASSERT(EXPECT_FALSE(vector.insert(1, -1)));
760 EXPECT_CHRE_ASSERT(EXPECT_FALSE(vector.copy_array(buf, kSize)));
761
762 for (size_t i = 0; i < kSize; i++) {
763 EXPECT_EQ(vector[i], i);
764 }
765
766 vector.erase(0);
767 for (size_t i = 0; i < kSize - 1; i++) {
768 EXPECT_EQ(vector[i], i + 1);
769 }
770
771 EXPECT_TRUE(vector.push_back(kSize + 1));
772 EXPECT_EQ(vector.back(), kSize + 1);
773 }
774
TEST(DynamicVector,MoveWrappedVector)775 TEST(DynamicVector, MoveWrappedVector) {
776 constexpr size_t kSize = 4;
777 int buf[kSize];
778 for (size_t i = 0; i < kSize; i++) {
779 buf[i] = i;
780 }
781
782 DynamicVector<int> vector1;
783 vector1.wrap(buf, kSize);
784
785 DynamicVector<int> vector2 = std::move(vector1);
786 EXPECT_TRUE(vector1.owns_data());
787 EXPECT_EQ(vector1.size(), 0);
788 EXPECT_EQ(vector1.capacity(), 0);
789 EXPECT_EQ(vector1.data(), nullptr);
790
791 EXPECT_FALSE(vector2.owns_data());
792 EXPECT_EQ(vector2.size(), kSize);
793 EXPECT_EQ(vector2.capacity(), kSize);
794 EXPECT_EQ(vector2.data(), buf);
795 }
796
TEST(DynamicVector,Unwrap)797 TEST(DynamicVector, Unwrap) {
798 constexpr size_t kSize = 4;
799 int buf[kSize];
800 for (size_t i = 0; i < kSize; i++) {
801 buf[i] = i;
802 }
803
804 DynamicVector<int> vec;
805 vec.wrap(buf, kSize);
806 ASSERT_FALSE(vec.owns_data());
807
808 vec.unwrap();
809 EXPECT_TRUE(vec.owns_data());
810 EXPECT_EQ(vec.size(), 0);
811 EXPECT_EQ(vec.capacity(), 0);
812 EXPECT_EQ(vec.data(), nullptr);
813
814 EXPECT_TRUE(vec.push_back(1));
815 }
816
TEST(DynamicVector,CopyArray)817 TEST(DynamicVector, CopyArray) {
818 constexpr size_t kSize = 4;
819 int buf[kSize];
820 for (size_t i = 0; i < kSize; i++) {
821 buf[i] = i;
822 }
823
824 DynamicVector<int> vec;
825 ASSERT_TRUE(vec.copy_array(buf, kSize));
826 EXPECT_TRUE(vec.owns_data());
827
828 EXPECT_EQ(vec.size(), kSize);
829 EXPECT_EQ(vec.capacity(), kSize);
830 EXPECT_NE(vec.data(), buf);
831
832 EXPECT_TRUE(vec.push_back(kSize));
833 EXPECT_EQ(vec.size(), kSize + 1);
834 EXPECT_GE(vec.capacity(), kSize + 1);
835
836 for (size_t i = 0; i < kSize + 1; i++) {
837 EXPECT_EQ(vec[i], i);
838 }
839 }
840
TEST(DynamicVector,CopyArrayHandlesDestructor)841 TEST(DynamicVector, CopyArrayHandlesDestructor) {
842 resetDestructorCounts();
843 constexpr size_t kSize = 4;
844
845 {
846 DynamicVector<Dummy> vec;
847 {
848 Dummy array[kSize];
849 for (size_t i = 0; i < kSize; i++) {
850 array[i].setValue(i);
851 }
852
853 ASSERT_TRUE(vec.copy_array(array, kSize));
854 }
855
856 for (size_t i = 0; i < kSize; i++) {
857 EXPECT_EQ(gDestructorCount[i], 1);
858 }
859
860 for (size_t i = 0; i < kSize; i++) {
861 ASSERT_TRUE(vec[i].getValue() == i);
862 }
863 }
864
865 for (size_t i = 0; i < kSize; i++) {
866 EXPECT_EQ(gDestructorCount[i], 2);
867 }
868 }
869
TEST(DynamicVector,CopyEmptyArray)870 TEST(DynamicVector, CopyEmptyArray) {
871 DynamicVector<int> vec;
872
873 EXPECT_TRUE(vec.copy_array(nullptr, 0));
874 EXPECT_EQ(vec.size(), 0);
875
876 vec.emplace_back(1);
877 EXPECT_TRUE(vec.copy_array(nullptr, 0));
878 EXPECT_EQ(vec.size(), 0);
879 }
880
TEST(DynamicVector,PrepareForPush)881 TEST(DynamicVector, PrepareForPush) {
882 DynamicVector<int> vector;
883 EXPECT_EQ(vector.size(), 0);
884 EXPECT_EQ(vector.capacity(), 0);
885
886 // Perform an initial prepareForPush operation which causes a size of one.
887 ASSERT_TRUE(vector.prepareForPush());
888 EXPECT_EQ(vector.size(), 0);
889 EXPECT_EQ(vector.capacity(), 1);
890 ASSERT_TRUE(vector.push_back(0xcafe));
891 EXPECT_EQ(vector.size(), 1);
892 EXPECT_EQ(vector.capacity(), 1);
893
894 // Verify that it becomes larger
895 ASSERT_TRUE(vector.prepareForPush());
896 EXPECT_EQ(vector[0], 0xcafe);
897 EXPECT_EQ(vector.size(), 1);
898 EXPECT_EQ(vector.capacity(), 2);
899
900 // The vector should not become any larger than necessary.
901 ASSERT_TRUE(vector.prepareForPush());
902 EXPECT_EQ(vector[0], 0xcafe);
903 EXPECT_EQ(vector.size(), 1);
904 EXPECT_EQ(vector.capacity(), 2);
905 }
906
TEST(DynamicVector,RidiculouslyHugeReserveFails)907 TEST(DynamicVector, RidiculouslyHugeReserveFails) {
908 DynamicVector<int> vector;
909 ASSERT_FALSE(vector.reserve(SIZE_MAX));
910 }
911
TEST(DynamicVector,PopBack)912 TEST(DynamicVector, PopBack) {
913 DynamicVector<int> vector;
914 constexpr size_t kSize = 4;
915 for (int i = 0; i < kSize; i++) {
916 vector.push_back(i);
917 }
918
919 for (int i = kSize - 1; i >= 0; i--) {
920 EXPECT_EQ(vector.back(), i);
921 vector.pop_back();
922 }
923 EXPECT_TRUE(vector.empty());
924 }
925
926 /**
927 * A test class to default construct an integer with an incrementing value.
928 */
929 struct FancyInt {
930 static int index;
931 int value;
932
FancyIntFancyInt933 FancyInt() : value(index++) {}
934 };
935
936 int FancyInt::index = 0;
937
TEST(DynamicVector,Resize)938 TEST(DynamicVector, Resize) {
939 DynamicVector<FancyInt> vector;
940 ASSERT_TRUE(vector.resize(4));
941 ASSERT_EQ(vector.size(), 4);
942
943 EXPECT_EQ(vector[0].value, 0);
944 EXPECT_EQ(vector[1].value, 1);
945 EXPECT_EQ(vector[2].value, 2);
946 EXPECT_EQ(vector[3].value, 3);
947
948 ASSERT_TRUE(vector.resize(2));
949 ASSERT_EQ(vector.size(), 2);
950
951 EXPECT_EQ(vector[0].value, 0);
952 EXPECT_EQ(vector[1].value, 1);
953
954 ASSERT_TRUE(vector.resize(4));
955 ASSERT_EQ(vector.size(), 4);
956
957 EXPECT_EQ(vector[0].value, 0);
958 EXPECT_EQ(vector[1].value, 1);
959 EXPECT_EQ(vector[2].value, 4);
960 EXPECT_EQ(vector[3].value, 5);
961 }
962