OLD | NEW |
| (Empty) |
1 /* | |
2 * Copyright (C) 2011 Apple Inc. All rights reserved. | |
3 * | |
4 * Redistribution and use in source and binary forms, with or without | |
5 * modification, are permitted provided that the following conditions | |
6 * are met: | |
7 * 1. Redistributions of source code must retain the above copyright | |
8 * notice, this list of conditions and the following disclaimer. | |
9 * 2. Redistributions in binary form must reproduce the above copyright | |
10 * notice, this list of conditions and the following disclaimer in the | |
11 * documentation and/or other materials provided with the distribution. | |
12 * | |
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' | |
14 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, | |
15 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | |
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS | |
17 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | |
18 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | |
19 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |
20 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | |
21 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | |
22 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF | |
23 * THE POSSIBILITY OF SUCH DAMAGE. | |
24 */ | |
25 | |
26 #include "wtf/Vector.h" | |
27 | |
28 #include "testing/gtest/include/gtest/gtest.h" | |
29 #include "wtf/HashSet.h" | |
30 #include "wtf/Optional.h" | |
31 #include "wtf/PtrUtil.h" | |
32 #include "wtf/text/WTFString.h" | |
33 #include <memory> | |
34 | |
35 namespace WTF { | |
36 | |
37 namespace { | |
38 | |
39 TEST(VectorTest, Basic) { | |
40 Vector<int> intVector; | |
41 EXPECT_TRUE(intVector.isEmpty()); | |
42 EXPECT_EQ(0ul, intVector.size()); | |
43 EXPECT_EQ(0ul, intVector.capacity()); | |
44 } | |
45 | |
46 TEST(VectorTest, Reverse) { | |
47 Vector<int> intVector; | |
48 intVector.push_back(10); | |
49 intVector.push_back(11); | |
50 intVector.push_back(12); | |
51 intVector.push_back(13); | |
52 intVector.reverse(); | |
53 | |
54 EXPECT_EQ(13, intVector[0]); | |
55 EXPECT_EQ(12, intVector[1]); | |
56 EXPECT_EQ(11, intVector[2]); | |
57 EXPECT_EQ(10, intVector[3]); | |
58 | |
59 intVector.push_back(9); | |
60 intVector.reverse(); | |
61 | |
62 EXPECT_EQ(9, intVector[0]); | |
63 EXPECT_EQ(10, intVector[1]); | |
64 EXPECT_EQ(11, intVector[2]); | |
65 EXPECT_EQ(12, intVector[3]); | |
66 EXPECT_EQ(13, intVector[4]); | |
67 } | |
68 | |
69 TEST(VectorTest, Remove) { | |
70 Vector<int> intVector; | |
71 intVector.push_back(0); | |
72 intVector.push_back(1); | |
73 intVector.push_back(2); | |
74 intVector.push_back(3); | |
75 | |
76 EXPECT_EQ(4u, intVector.size()); | |
77 EXPECT_EQ(0, intVector[0]); | |
78 EXPECT_EQ(1, intVector[1]); | |
79 EXPECT_EQ(2, intVector[2]); | |
80 EXPECT_EQ(3, intVector[3]); | |
81 | |
82 intVector.remove(2, 0); | |
83 EXPECT_EQ(4u, intVector.size()); | |
84 EXPECT_EQ(2, intVector[2]); | |
85 | |
86 intVector.remove(2, 1); | |
87 EXPECT_EQ(3u, intVector.size()); | |
88 EXPECT_EQ(3, intVector[2]); | |
89 | |
90 intVector.remove(0, 0); | |
91 EXPECT_EQ(3u, intVector.size()); | |
92 EXPECT_EQ(0, intVector[0]); | |
93 | |
94 intVector.remove(0); | |
95 EXPECT_EQ(2u, intVector.size()); | |
96 EXPECT_EQ(1, intVector[0]); | |
97 } | |
98 | |
99 TEST(VectorTest, Iterator) { | |
100 Vector<int> intVector; | |
101 intVector.push_back(10); | |
102 intVector.push_back(11); | |
103 intVector.push_back(12); | |
104 intVector.push_back(13); | |
105 | |
106 Vector<int>::iterator it = intVector.begin(); | |
107 Vector<int>::iterator end = intVector.end(); | |
108 EXPECT_TRUE(end != it); | |
109 | |
110 EXPECT_EQ(10, *it); | |
111 ++it; | |
112 EXPECT_EQ(11, *it); | |
113 ++it; | |
114 EXPECT_EQ(12, *it); | |
115 ++it; | |
116 EXPECT_EQ(13, *it); | |
117 ++it; | |
118 | |
119 EXPECT_TRUE(end == it); | |
120 } | |
121 | |
122 TEST(VectorTest, ReverseIterator) { | |
123 Vector<int> intVector; | |
124 intVector.push_back(10); | |
125 intVector.push_back(11); | |
126 intVector.push_back(12); | |
127 intVector.push_back(13); | |
128 | |
129 Vector<int>::reverse_iterator it = intVector.rbegin(); | |
130 Vector<int>::reverse_iterator end = intVector.rend(); | |
131 EXPECT_TRUE(end != it); | |
132 | |
133 EXPECT_EQ(13, *it); | |
134 ++it; | |
135 EXPECT_EQ(12, *it); | |
136 ++it; | |
137 EXPECT_EQ(11, *it); | |
138 ++it; | |
139 EXPECT_EQ(10, *it); | |
140 ++it; | |
141 | |
142 EXPECT_TRUE(end == it); | |
143 } | |
144 | |
145 class DestructCounter { | |
146 public: | |
147 explicit DestructCounter(int i, int* destructNumber) | |
148 : m_i(i), m_destructNumber(destructNumber) {} | |
149 | |
150 ~DestructCounter() { ++(*m_destructNumber); } | |
151 int get() const { return m_i; } | |
152 | |
153 private: | |
154 int m_i; | |
155 int* m_destructNumber; | |
156 }; | |
157 | |
158 typedef WTF::Vector<std::unique_ptr<DestructCounter>> OwnPtrVector; | |
159 | |
160 TEST(VectorTest, OwnPtr) { | |
161 int destructNumber = 0; | |
162 OwnPtrVector vector; | |
163 vector.push_back(WTF::wrapUnique(new DestructCounter(0, &destructNumber))); | |
164 vector.push_back(WTF::wrapUnique(new DestructCounter(1, &destructNumber))); | |
165 EXPECT_EQ(2u, vector.size()); | |
166 | |
167 std::unique_ptr<DestructCounter>& counter0 = vector.front(); | |
168 ASSERT_EQ(0, counter0->get()); | |
169 int counter1 = vector.back()->get(); | |
170 ASSERT_EQ(1, counter1); | |
171 ASSERT_EQ(0, destructNumber); | |
172 | |
173 size_t index = 0; | |
174 for (OwnPtrVector::iterator iter = vector.begin(); iter != vector.end(); | |
175 ++iter) { | |
176 std::unique_ptr<DestructCounter>* refCounter = iter; | |
177 EXPECT_EQ(index, static_cast<size_t>(refCounter->get()->get())); | |
178 EXPECT_EQ(index, static_cast<size_t>((*refCounter)->get())); | |
179 index++; | |
180 } | |
181 EXPECT_EQ(0, destructNumber); | |
182 | |
183 for (index = 0; index < vector.size(); index++) { | |
184 std::unique_ptr<DestructCounter>& refCounter = vector[index]; | |
185 EXPECT_EQ(index, static_cast<size_t>(refCounter->get())); | |
186 } | |
187 EXPECT_EQ(0, destructNumber); | |
188 | |
189 EXPECT_EQ(0, vector[0]->get()); | |
190 EXPECT_EQ(1, vector[1]->get()); | |
191 vector.remove(0); | |
192 EXPECT_EQ(1, vector[0]->get()); | |
193 EXPECT_EQ(1u, vector.size()); | |
194 EXPECT_EQ(1, destructNumber); | |
195 | |
196 std::unique_ptr<DestructCounter> ownCounter1 = std::move(vector[0]); | |
197 vector.remove(0); | |
198 ASSERT_EQ(counter1, ownCounter1->get()); | |
199 ASSERT_EQ(0u, vector.size()); | |
200 ASSERT_EQ(1, destructNumber); | |
201 | |
202 ownCounter1.reset(); | |
203 EXPECT_EQ(2, destructNumber); | |
204 | |
205 size_t count = 1025; | |
206 destructNumber = 0; | |
207 for (size_t i = 0; i < count; i++) | |
208 vector.push_front(WTF::wrapUnique(new DestructCounter(i, &destructNumber))); | |
209 | |
210 // Vector relocation must not destruct std::unique_ptr element. | |
211 EXPECT_EQ(0, destructNumber); | |
212 EXPECT_EQ(count, vector.size()); | |
213 | |
214 OwnPtrVector copyVector; | |
215 vector.swap(copyVector); | |
216 EXPECT_EQ(0, destructNumber); | |
217 EXPECT_EQ(count, copyVector.size()); | |
218 EXPECT_EQ(0u, vector.size()); | |
219 | |
220 copyVector.clear(); | |
221 EXPECT_EQ(count, static_cast<size_t>(destructNumber)); | |
222 } | |
223 | |
224 class MoveOnly { | |
225 public: | |
226 explicit MoveOnly(int i = 0) : m_i(i) {} | |
227 | |
228 MoveOnly(MoveOnly&& other) : m_i(other.m_i) { other.m_i = 0; } | |
229 | |
230 MoveOnly& operator=(MoveOnly&& other) { | |
231 if (this != &other) { | |
232 m_i = other.m_i; | |
233 other.m_i = 0; | |
234 } | |
235 return *this; | |
236 } | |
237 | |
238 int value() const { return m_i; } | |
239 | |
240 private: | |
241 WTF_MAKE_NONCOPYABLE(MoveOnly); | |
242 int m_i; | |
243 }; | |
244 | |
245 TEST(VectorTest, MoveOnlyType) { | |
246 WTF::Vector<MoveOnly> vector; | |
247 vector.push_back(MoveOnly(1)); | |
248 vector.push_back(MoveOnly(2)); | |
249 EXPECT_EQ(2u, vector.size()); | |
250 | |
251 ASSERT_EQ(1, vector.front().value()); | |
252 ASSERT_EQ(2, vector.back().value()); | |
253 | |
254 vector.remove(0); | |
255 EXPECT_EQ(2, vector[0].value()); | |
256 EXPECT_EQ(1u, vector.size()); | |
257 | |
258 MoveOnly moveOnly(std::move(vector[0])); | |
259 vector.remove(0); | |
260 ASSERT_EQ(2, moveOnly.value()); | |
261 ASSERT_EQ(0u, vector.size()); | |
262 | |
263 size_t count = vector.capacity() + 1; | |
264 for (size_t i = 0; i < count; i++) | |
265 vector.push_back( | |
266 MoveOnly(i + 1)); // +1 to distinguish from default-constructed. | |
267 | |
268 // Reallocation did not affect the vector's content. | |
269 EXPECT_EQ(count, vector.size()); | |
270 for (size_t i = 0; i < vector.size(); i++) | |
271 EXPECT_EQ(static_cast<int>(i + 1), vector[i].value()); | |
272 | |
273 WTF::Vector<MoveOnly> otherVector; | |
274 vector.swap(otherVector); | |
275 EXPECT_EQ(count, otherVector.size()); | |
276 EXPECT_EQ(0u, vector.size()); | |
277 | |
278 vector = std::move(otherVector); | |
279 EXPECT_EQ(count, vector.size()); | |
280 } | |
281 | |
282 // WrappedInt class will fail if it was memmoved or memcpyed. | |
283 static HashSet<void*> constructedWrappedInts; | |
284 class WrappedInt { | |
285 public: | |
286 WrappedInt(int i = 0) : m_originalThisPtr(this), m_i(i) { | |
287 constructedWrappedInts.insert(this); | |
288 } | |
289 | |
290 WrappedInt(const WrappedInt& other) | |
291 : m_originalThisPtr(this), m_i(other.m_i) { | |
292 constructedWrappedInts.insert(this); | |
293 } | |
294 | |
295 WrappedInt& operator=(const WrappedInt& other) { | |
296 m_i = other.m_i; | |
297 return *this; | |
298 } | |
299 | |
300 ~WrappedInt() { | |
301 EXPECT_EQ(m_originalThisPtr, this); | |
302 EXPECT_TRUE(constructedWrappedInts.contains(this)); | |
303 constructedWrappedInts.erase(this); | |
304 } | |
305 | |
306 int get() const { return m_i; } | |
307 | |
308 private: | |
309 void* m_originalThisPtr; | |
310 int m_i; | |
311 }; | |
312 | |
313 TEST(VectorTest, SwapWithInlineCapacity) { | |
314 const size_t inlineCapacity = 2; | |
315 Vector<WrappedInt, inlineCapacity> vectorA; | |
316 vectorA.push_back(WrappedInt(1)); | |
317 Vector<WrappedInt, inlineCapacity> vectorB; | |
318 vectorB.push_back(WrappedInt(2)); | |
319 | |
320 EXPECT_EQ(vectorA.size(), vectorB.size()); | |
321 vectorA.swap(vectorB); | |
322 | |
323 EXPECT_EQ(1u, vectorA.size()); | |
324 EXPECT_EQ(2, vectorA.at(0).get()); | |
325 EXPECT_EQ(1u, vectorB.size()); | |
326 EXPECT_EQ(1, vectorB.at(0).get()); | |
327 | |
328 vectorA.push_back(WrappedInt(3)); | |
329 | |
330 EXPECT_GT(vectorA.size(), vectorB.size()); | |
331 vectorA.swap(vectorB); | |
332 | |
333 EXPECT_EQ(1u, vectorA.size()); | |
334 EXPECT_EQ(1, vectorA.at(0).get()); | |
335 EXPECT_EQ(2u, vectorB.size()); | |
336 EXPECT_EQ(2, vectorB.at(0).get()); | |
337 EXPECT_EQ(3, vectorB.at(1).get()); | |
338 | |
339 EXPECT_LT(vectorA.size(), vectorB.size()); | |
340 vectorA.swap(vectorB); | |
341 | |
342 EXPECT_EQ(2u, vectorA.size()); | |
343 EXPECT_EQ(2, vectorA.at(0).get()); | |
344 EXPECT_EQ(3, vectorA.at(1).get()); | |
345 EXPECT_EQ(1u, vectorB.size()); | |
346 EXPECT_EQ(1, vectorB.at(0).get()); | |
347 | |
348 vectorA.push_back(WrappedInt(4)); | |
349 EXPECT_GT(vectorA.size(), inlineCapacity); | |
350 vectorA.swap(vectorB); | |
351 | |
352 EXPECT_EQ(1u, vectorA.size()); | |
353 EXPECT_EQ(1, vectorA.at(0).get()); | |
354 EXPECT_EQ(3u, vectorB.size()); | |
355 EXPECT_EQ(2, vectorB.at(0).get()); | |
356 EXPECT_EQ(3, vectorB.at(1).get()); | |
357 EXPECT_EQ(4, vectorB.at(2).get()); | |
358 | |
359 vectorB.swap(vectorA); | |
360 } | |
361 | |
362 #if defined(ANNOTATE_CONTIGUOUS_CONTAINER) | |
363 TEST(VectorTest, ContainerAnnotations) { | |
364 Vector<int> vectorA; | |
365 vectorA.push_back(10); | |
366 vectorA.reserveCapacity(32); | |
367 | |
368 volatile int* intPointerA = vectorA.data(); | |
369 EXPECT_DEATH(intPointerA[1] = 11, "container-overflow"); | |
370 vectorA.push_back(11); | |
371 intPointerA[1] = 11; | |
372 EXPECT_DEATH(intPointerA[2] = 12, "container-overflow"); | |
373 EXPECT_DEATH((void)intPointerA[2], "container-overflow"); | |
374 vectorA.shrinkToFit(); | |
375 vectorA.reserveCapacity(16); | |
376 intPointerA = vectorA.data(); | |
377 EXPECT_DEATH((void)intPointerA[2], "container-overflow"); | |
378 | |
379 Vector<int> vectorB(vectorA); | |
380 vectorB.reserveCapacity(16); | |
381 volatile int* intPointerB = vectorB.data(); | |
382 EXPECT_DEATH((void)intPointerB[2], "container-overflow"); | |
383 | |
384 Vector<int> vectorC((Vector<int>(vectorA))); | |
385 volatile int* intPointerC = vectorC.data(); | |
386 EXPECT_DEATH((void)intPointerC[2], "container-overflow"); | |
387 vectorC.push_back(13); | |
388 vectorC.swap(vectorB); | |
389 | |
390 volatile int* intPointerB2 = vectorB.data(); | |
391 volatile int* intPointerC2 = vectorC.data(); | |
392 intPointerB2[2] = 13; | |
393 EXPECT_DEATH((void)intPointerB2[3], "container-overflow"); | |
394 EXPECT_DEATH((void)intPointerC2[2], "container-overflow"); | |
395 | |
396 vectorB = vectorC; | |
397 volatile int* intPointerB3 = vectorB.data(); | |
398 EXPECT_DEATH((void)intPointerB3[2], "container-overflow"); | |
399 } | |
400 #endif // defined(ANNOTATE_CONTIGUOUS_CONTAINER) | |
401 | |
402 class Comparable {}; | |
403 bool operator==(const Comparable& a, const Comparable& b) { | |
404 return true; | |
405 } | |
406 | |
407 template <typename T> | |
408 void compare() { | |
409 EXPECT_TRUE(Vector<T>() == Vector<T>()); | |
410 EXPECT_FALSE(Vector<T>(1) == Vector<T>(0)); | |
411 EXPECT_FALSE(Vector<T>() == Vector<T>(1)); | |
412 EXPECT_TRUE(Vector<T>(1) == Vector<T>(1)); | |
413 | |
414 Vector<T, 1> vectorWithInlineCapacity; | |
415 EXPECT_TRUE(vectorWithInlineCapacity == Vector<T>()); | |
416 EXPECT_FALSE(vectorWithInlineCapacity == Vector<T>(1)); | |
417 } | |
418 | |
419 TEST(VectorTest, Compare) { | |
420 compare<int>(); | |
421 compare<Comparable>(); | |
422 compare<WTF::String>(); | |
423 } | |
424 | |
425 TEST(VectorTest, AppendFirst) { | |
426 Vector<WTF::String> vector; | |
427 vector.push_back("string"); | |
428 // Test passes if it does not crash (reallocation did not make | |
429 // the input reference stale). | |
430 size_t limit = vector.capacity() + 1; | |
431 for (size_t i = 0; i < limit; i++) | |
432 vector.push_back(vector.front()); | |
433 | |
434 limit = vector.capacity() + 1; | |
435 for (size_t i = 0; i < limit; i++) | |
436 vector.push_back(const_cast<const WTF::String&>(vector.front())); | |
437 } | |
438 | |
439 // The test below is for the following issue: | |
440 // | |
441 // https://bugs.chromium.org/p/chromium/issues/detail?id=592767 | |
442 // | |
443 // where deleted copy assignment operator made canMoveWithMemcpy true because | |
444 // of the implementation of IsTriviallyMoveAssignable<T>. | |
445 | |
446 class MojoMoveOnlyType final { | |
447 public: | |
448 MojoMoveOnlyType(); | |
449 MojoMoveOnlyType(MojoMoveOnlyType&&); | |
450 MojoMoveOnlyType& operator=(MojoMoveOnlyType&&); | |
451 ~MojoMoveOnlyType(); | |
452 | |
453 private: | |
454 MojoMoveOnlyType(const MojoMoveOnlyType&) = delete; | |
455 void operator=(const MojoMoveOnlyType&) = delete; | |
456 }; | |
457 | |
458 static_assert(!IsTriviallyMoveAssignable<MojoMoveOnlyType>::value, | |
459 "MojoMoveOnlyType isn't trivially move assignable."); | |
460 static_assert(!IsTriviallyCopyAssignable<MojoMoveOnlyType>::value, | |
461 "MojoMoveOnlyType isn't trivially copy assignable."); | |
462 | |
463 static_assert(!VectorTraits<MojoMoveOnlyType>::canMoveWithMemcpy, | |
464 "MojoMoveOnlyType can't be moved with memcpy."); | |
465 static_assert(!VectorTraits<MojoMoveOnlyType>::canCopyWithMemcpy, | |
466 "MojoMoveOnlyType can't be copied with memcpy."); | |
467 | |
468 class LivenessCounter { | |
469 public: | |
470 void ref() { s_live++; } | |
471 void deref() { s_live--; } | |
472 | |
473 static unsigned s_live; | |
474 }; | |
475 | |
476 unsigned LivenessCounter::s_live = 0; | |
477 | |
478 class VectorWithDifferingInlineCapacityTest | |
479 : public ::testing::TestWithParam<size_t> {}; | |
480 | |
481 template <size_t inlineCapacity> | |
482 void testDestructorAndConstructorCallsWhenSwappingWithInlineCapacity() { | |
483 LivenessCounter::s_live = 0; | |
484 LivenessCounter counter; | |
485 EXPECT_EQ(0u, LivenessCounter::s_live); | |
486 | |
487 Vector<RefPtr<LivenessCounter>, inlineCapacity> vector; | |
488 Vector<RefPtr<LivenessCounter>, inlineCapacity> vector2; | |
489 vector.push_back(&counter); | |
490 vector2.push_back(&counter); | |
491 EXPECT_EQ(2u, LivenessCounter::s_live); | |
492 | |
493 for (unsigned i = 0; i < 13; i++) { | |
494 for (unsigned j = 0; j < 13; j++) { | |
495 vector.clear(); | |
496 vector2.clear(); | |
497 EXPECT_EQ(0u, LivenessCounter::s_live); | |
498 | |
499 for (unsigned k = 0; k < j; k++) | |
500 vector.push_back(&counter); | |
501 EXPECT_EQ(j, LivenessCounter::s_live); | |
502 EXPECT_EQ(j, vector.size()); | |
503 | |
504 for (unsigned k = 0; k < i; k++) | |
505 vector2.push_back(&counter); | |
506 EXPECT_EQ(i + j, LivenessCounter::s_live); | |
507 EXPECT_EQ(i, vector2.size()); | |
508 | |
509 vector.swap(vector2); | |
510 EXPECT_EQ(i + j, LivenessCounter::s_live); | |
511 EXPECT_EQ(i, vector.size()); | |
512 EXPECT_EQ(j, vector2.size()); | |
513 | |
514 unsigned size = vector.size(); | |
515 unsigned size2 = vector2.size(); | |
516 | |
517 for (unsigned k = 0; k < 5; k++) { | |
518 vector.swap(vector2); | |
519 std::swap(size, size2); | |
520 EXPECT_EQ(i + j, LivenessCounter::s_live); | |
521 EXPECT_EQ(size, vector.size()); | |
522 EXPECT_EQ(size2, vector2.size()); | |
523 | |
524 vector2.push_back(&counter); | |
525 vector2.remove(0); | |
526 } | |
527 } | |
528 } | |
529 } | |
530 | |
531 TEST(VectorTest, SwapWithConstructorsAndDestructors) { | |
532 testDestructorAndConstructorCallsWhenSwappingWithInlineCapacity<0>(); | |
533 testDestructorAndConstructorCallsWhenSwappingWithInlineCapacity<2>(); | |
534 testDestructorAndConstructorCallsWhenSwappingWithInlineCapacity<10>(); | |
535 } | |
536 | |
537 template <size_t inlineCapacity> | |
538 void testValuesMovedAndSwappedWithInlineCapacity() { | |
539 Vector<unsigned, inlineCapacity> vector; | |
540 Vector<unsigned, inlineCapacity> vector2; | |
541 | |
542 for (unsigned size = 0; size < 13; size++) { | |
543 for (unsigned size2 = 0; size2 < 13; size2++) { | |
544 vector.clear(); | |
545 vector2.clear(); | |
546 for (unsigned i = 0; i < size; i++) | |
547 vector.push_back(i); | |
548 for (unsigned i = 0; i < size2; i++) | |
549 vector2.push_back(i + 42); | |
550 EXPECT_EQ(size, vector.size()); | |
551 EXPECT_EQ(size2, vector2.size()); | |
552 vector.swap(vector2); | |
553 for (unsigned i = 0; i < size; i++) | |
554 EXPECT_EQ(i, vector2[i]); | |
555 for (unsigned i = 0; i < size2; i++) | |
556 EXPECT_EQ(i + 42, vector[i]); | |
557 } | |
558 } | |
559 } | |
560 | |
561 TEST(VectorTest, ValuesMovedAndSwappedWithInlineCapacity) { | |
562 testValuesMovedAndSwappedWithInlineCapacity<0>(); | |
563 testValuesMovedAndSwappedWithInlineCapacity<2>(); | |
564 testValuesMovedAndSwappedWithInlineCapacity<10>(); | |
565 } | |
566 | |
567 TEST(VectorTest, UniquePtr) { | |
568 using Pointer = std::unique_ptr<int>; | |
569 Vector<Pointer> vector; | |
570 vector.push_back(Pointer(new int(1))); | |
571 vector.reserveCapacity(2); | |
572 vector.uncheckedAppend(Pointer(new int(2))); | |
573 vector.insert(2, Pointer(new int(3))); | |
574 vector.push_front(Pointer(new int(0))); | |
575 | |
576 ASSERT_EQ(4u, vector.size()); | |
577 EXPECT_EQ(0, *vector[0]); | |
578 EXPECT_EQ(1, *vector[1]); | |
579 EXPECT_EQ(2, *vector[2]); | |
580 EXPECT_EQ(3, *vector[3]); | |
581 | |
582 vector.shrink(3); | |
583 EXPECT_EQ(3u, vector.size()); | |
584 vector.grow(4); | |
585 ASSERT_EQ(4u, vector.size()); | |
586 EXPECT_TRUE(!vector[3]); | |
587 vector.remove(3); | |
588 vector[0] = Pointer(new int(-1)); | |
589 ASSERT_EQ(3u, vector.size()); | |
590 EXPECT_EQ(-1, *vector[0]); | |
591 } | |
592 | |
593 bool isOneTwoThree(const Vector<int>& vector) { | |
594 return vector.size() == 3 && vector[0] == 1 && vector[1] == 2 && | |
595 vector[2] == 3; | |
596 } | |
597 | |
598 Vector<int> returnOneTwoThree() { | |
599 return {1, 2, 3}; | |
600 } | |
601 | |
602 TEST(VectorTest, InitializerList) { | |
603 Vector<int> empty({}); | |
604 EXPECT_TRUE(empty.isEmpty()); | |
605 | |
606 Vector<int> one({1}); | |
607 ASSERT_EQ(1u, one.size()); | |
608 EXPECT_EQ(1, one[0]); | |
609 | |
610 Vector<int> oneTwoThree({1, 2, 3}); | |
611 ASSERT_EQ(3u, oneTwoThree.size()); | |
612 EXPECT_EQ(1, oneTwoThree[0]); | |
613 EXPECT_EQ(2, oneTwoThree[1]); | |
614 EXPECT_EQ(3, oneTwoThree[2]); | |
615 | |
616 // Put some jank so we can check if the assignments later can clear them. | |
617 empty.push_back(9999); | |
618 one.push_back(9999); | |
619 oneTwoThree.push_back(9999); | |
620 | |
621 empty = {}; | |
622 EXPECT_TRUE(empty.isEmpty()); | |
623 | |
624 one = {1}; | |
625 ASSERT_EQ(1u, one.size()); | |
626 EXPECT_EQ(1, one[0]); | |
627 | |
628 oneTwoThree = {1, 2, 3}; | |
629 ASSERT_EQ(3u, oneTwoThree.size()); | |
630 EXPECT_EQ(1, oneTwoThree[0]); | |
631 EXPECT_EQ(2, oneTwoThree[1]); | |
632 EXPECT_EQ(3, oneTwoThree[2]); | |
633 | |
634 // Other ways of construction: as a function parameter and in a return | |
635 // statement. | |
636 EXPECT_TRUE(isOneTwoThree({1, 2, 3})); | |
637 EXPECT_TRUE(isOneTwoThree(returnOneTwoThree())); | |
638 | |
639 // The tests below correspond to the cases in the "if" branch in | |
640 // operator=(std::initializer_list<T>). | |
641 | |
642 // Shrinking. | |
643 Vector<int, 1> vector1(3); // capacity = 3. | |
644 vector1 = {1, 2}; | |
645 ASSERT_EQ(2u, vector1.size()); | |
646 EXPECT_EQ(1, vector1[0]); | |
647 EXPECT_EQ(2, vector1[1]); | |
648 | |
649 // Expanding. | |
650 Vector<int, 1> vector2(3); | |
651 vector2 = {1, 2, 3, 4}; | |
652 ASSERT_EQ(4u, vector2.size()); | |
653 EXPECT_EQ(1, vector2[0]); | |
654 EXPECT_EQ(2, vector2[1]); | |
655 EXPECT_EQ(3, vector2[2]); | |
656 EXPECT_EQ(4, vector2[3]); | |
657 | |
658 // Exact match. | |
659 Vector<int, 1> vector3(3); | |
660 vector3 = {1, 2, 3}; | |
661 ASSERT_EQ(3u, vector3.size()); | |
662 EXPECT_EQ(1, vector3[0]); | |
663 EXPECT_EQ(2, vector3[1]); | |
664 EXPECT_EQ(3, vector3[2]); | |
665 } | |
666 | |
667 TEST(VectorTest, Optional) { | |
668 Optional<Vector<int>> vector; | |
669 EXPECT_FALSE(vector); | |
670 vector.emplace(3); | |
671 EXPECT_TRUE(vector); | |
672 EXPECT_EQ(3u, vector->size()); | |
673 } | |
674 | |
675 TEST(VectorTest, emplace_back) { | |
676 struct Item { | |
677 Item() = default; | |
678 explicit Item(int value1) : value1(value1), value2() {} | |
679 Item(int value1, int value2) : value1(value1), value2(value2) {} | |
680 int value1; | |
681 int value2; | |
682 }; | |
683 | |
684 Vector<Item> vector; | |
685 vector.emplace_back(1, 2); | |
686 vector.emplace_back(3, 4); | |
687 vector.emplace_back(5); | |
688 vector.emplace_back(); | |
689 | |
690 EXPECT_EQ(4u, vector.size()); | |
691 | |
692 EXPECT_EQ(1, vector[0].value1); | |
693 EXPECT_EQ(2, vector[0].value2); | |
694 | |
695 EXPECT_EQ(3, vector[1].value1); | |
696 EXPECT_EQ(4, vector[1].value2); | |
697 | |
698 EXPECT_EQ(5, vector[2].value1); | |
699 EXPECT_EQ(0, vector[2].value2); | |
700 | |
701 EXPECT_EQ(0, vector[3].value1); | |
702 EXPECT_EQ(0, vector[3].value2); | |
703 | |
704 // Test returned value. | |
705 Item& item = vector.emplace_back(6, 7); | |
706 EXPECT_EQ(6, item.value1); | |
707 EXPECT_EQ(7, item.value2); | |
708 } | |
709 | |
710 static_assert(VectorTraits<int>::canCopyWithMemcpy, | |
711 "int should be copied with memcopy."); | |
712 static_assert(VectorTraits<char>::canCopyWithMemcpy, | |
713 "char should be copied with memcpy."); | |
714 static_assert(VectorTraits<LChar>::canCopyWithMemcpy, | |
715 "LChar should be copied with memcpy."); | |
716 static_assert(VectorTraits<UChar>::canCopyWithMemcpy, | |
717 "UChar should be copied with memcpy."); | |
718 | |
719 class UnknownType; | |
720 static_assert(VectorTraits<UnknownType*>::canCopyWithMemcpy, | |
721 "Pointers should be copied with memcpy."); | |
722 | |
723 } // anonymous namespace | |
724 | |
725 } // namespace WTF | |
OLD | NEW |