Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(183)

Side by Side Diff: base/containers/circular_deque_unittest.cc

Issue 2898213003: Add skeleton circular queue file.
Patch Set: Fix merge 2 Created 3 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « base/containers/circular_deque.h ('k') | base/containers/queue.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2017 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "base/containers/circular_deque.h"
6
7 #include "base/test/copy_only_int.h"
8 #include "base/test/move_only_int.h"
9 #include "testing/gtest/include/gtest/gtest.h"
10
11 using base::internal::VectorBuffer;
12
13 namespace base {
14
15 namespace {
16
17 circular_deque<int> MakeSequence(size_t max) {
18 circular_deque<int> ret;
19 for (size_t i = 0; i < max; i++)
20 ret.push_back(i);
21 return ret;
22 }
23
24 // Cycles through the queue, popping items from the back and pushing items
25 // at the front to validate behavior across different configurations of the
26 // queue in relation to the underlying buffer. The tester closure is run for
27 // each cycle.
28 template <class QueueT, class Tester>
29 void CycleTest(circular_deque<QueueT>& queue, const Tester& tester) {
30 size_t steps = queue.size() * 2;
31 for (size_t i = 0; i < steps; i++) {
32 tester(queue, i);
33 queue.pop_back();
34 queue.push_front(QueueT());
35 }
36 }
37
38 } // namespace
39
40 TEST(CircularDeque, FillConstructor) {
41 constexpr size_t num_elts = 9;
42
43 std::vector<int> foo(15);
44 EXPECT_EQ(15u, foo.size());
45
46 // Fill with default constructor.
47 {
48 circular_deque<int> buf(num_elts);
49
50 EXPECT_EQ(num_elts, buf.size());
51 EXPECT_EQ(num_elts, static_cast<size_t>(buf.end() - buf.begin()));
52
53 for (size_t i = 0; i < num_elts; i++)
54 EXPECT_EQ(0, buf[i]);
55 }
56
57 // Fill with explicit value.
58 {
59 int value = 199;
60 circular_deque<int> buf(num_elts, value);
61
62 EXPECT_EQ(num_elts, buf.size());
63 EXPECT_EQ(num_elts, static_cast<size_t>(buf.end() - buf.begin()));
64
65 for (size_t i = 0; i < num_elts; i++)
66 EXPECT_EQ(value, buf[i]);
67 }
68 }
69
70 TEST(CircularDeque, CopyAndRangeConstructor) {
71 int values[] = {1, 2, 3, 4, 5, 6};
72 circular_deque<CopyOnlyInt> first(std::begin(values), std::end(values));
73
74 circular_deque<CopyOnlyInt> second(first);
75 EXPECT_EQ(6u, second.size());
76 for (int i = 0; i < 6; i++)
77 EXPECT_EQ(i + 1, second[i].data());
78 }
79
80 TEST(CircularDeque, MoveConstructor) {
81 int values[] = {1, 2, 3, 4, 5, 6};
82 circular_deque<MoveOnlyInt> first(std::begin(values), std::end(values));
83
84 circular_deque<MoveOnlyInt> second(std::move(first));
85 EXPECT_TRUE(first.empty());
86 EXPECT_EQ(6u, second.size());
87 for (int i = 0; i < 6; i++)
88 EXPECT_EQ(i + 1, second[i].data());
89 }
90
91 TEST(CircularDeque, InitializerListConstructor) {
92 circular_deque<int> empty({});
93 ASSERT_TRUE(empty.empty());
94
95 circular_deque<int> first({1, 2, 3, 4, 5, 6});
96 EXPECT_EQ(6u, first.size());
97 for (int i = 0; i < 6; i++)
98 EXPECT_EQ(i + 1, first[i]);
99 }
100
101 TEST(CircularDeque, EqualsCopy) {
102 circular_deque<int> first = {1, 2, 3, 4, 5, 6};
103 circular_deque<int> copy;
104 EXPECT_TRUE(copy.empty());
105 copy = first;
106 EXPECT_EQ(6u, copy.size());
107 for (int i = 0; i < 6; i++) {
108 EXPECT_EQ(i + 1, first[i]);
109 EXPECT_EQ(i + 1, copy[i]);
110 EXPECT_NE(&first[i], &copy[i]);
111 }
112 }
113
114 TEST(CircularDeque, EqualsMove) {
115 circular_deque<int> first = {1, 2, 3, 4, 5, 6};
116 circular_deque<int> move;
117 EXPECT_TRUE(move.empty());
118 move = std::move(first);
119 EXPECT_TRUE(first.empty());
120 EXPECT_EQ(6u, move.size());
121 for (int i = 0; i < 6; i++)
122 EXPECT_EQ(i + 1, move[i]);
123 }
124
125 TEST(CircularDeque, EqualsInitializerList) {
126 circular_deque<int> q;
127 EXPECT_TRUE(q.empty());
128 q = {1, 2, 3, 4, 5, 6};
129 EXPECT_EQ(6u, q.size());
130 for (int i = 0; i < 6; i++)
131 EXPECT_EQ(i + 1, q[i]);
132 }
133
134 TEST(CircularDeque, AssignCountValue) {
135 circular_deque<int> empty;
136 empty.assign(0, 52);
137 EXPECT_EQ(0u, empty.size());
138
139 circular_deque<int> full;
140 size_t count = 13;
141 int value = 12345;
142 full.assign(count, value);
143 EXPECT_EQ(count, full.size());
144
145 for (size_t i = 0; i < count; i++)
146 EXPECT_EQ(value, full[i]);
147 }
148
149 TEST(CircularDeque, AssignIterator) {
150 int range[8] = {11, 12, 13, 14, 15, 16, 17, 18};
151
152 circular_deque<int> empty;
153 empty.assign(std::begin(range), std::begin(range));
154 EXPECT_TRUE(empty.empty());
155
156 circular_deque<int> full;
157 full.assign(std::begin(range), std::end(range));
158 EXPECT_EQ(8u, full.size());
159 for (size_t i = 0; i < 8; i++)
160 EXPECT_EQ(range[i], full[i]);
161 }
162
163 TEST(CircularDeque, AssignInitializerList) {
164 circular_deque<int> empty;
165 empty.assign({});
166 EXPECT_TRUE(empty.empty());
167
168 circular_deque<int> full;
169 full.assign({11, 12, 13, 14, 15, 16, 17, 18});
170 EXPECT_EQ(8u, full.size());
171 for (int i = 0; i < 8; i++)
172 EXPECT_EQ(11 + i, full[i]);
173 }
174
175 // Tests [] and .at().
176 TEST(CircularDeque, At) {
177 circular_deque<int> q = MakeSequence(10);
178 CycleTest(q, [](const circular_deque<int>& q, size_t cycle) {
179 size_t expected_size = 10;
180 EXPECT_EQ(expected_size, q.size());
181
182 // A sequence of 0's.
183 size_t index = 0;
184 size_t num_zeros = std::min(expected_size, cycle);
185 for (size_t i = 0; i < num_zeros; i++, index++) {
186 EXPECT_EQ(0, q[index]);
187 EXPECT_EQ(0, q.at(index));
188 }
189
190 // Followed by a sequence of increasing ints.
191 size_t num_ints = expected_size - num_zeros;
192 for (int i = 0; i < static_cast<int>(num_ints); i++, index++) {
193 EXPECT_EQ(i, q[index]);
194 EXPECT_EQ(i, q.at(index));
195 }
196 });
197 }
198
199 // This also tests the copy constructor with lots of different types of
200 // input configurations.
201 TEST(CircularDeque, FrontBackPushPop) {
202 circular_deque<int> q = MakeSequence(10);
203
204 int expected_front = 0;
205 int expected_back = 9;
206
207 // Go in one direction.
208 for (int i = 0; i < 100; i++) {
209 const circular_deque<int> const_q(q);
210
211 EXPECT_EQ(expected_front, q.front());
212 EXPECT_EQ(expected_back, q.back());
213 EXPECT_EQ(expected_front, const_q.front());
214 EXPECT_EQ(expected_back, const_q.back());
215
216 expected_front++;
217 expected_back++;
218
219 q.pop_front();
220 q.push_back(expected_back);
221 }
222
223 // Go back in reverse.
224 for (int i = 0; i < 100; i++) {
225 const circular_deque<int> const_q(q);
226
227 EXPECT_EQ(expected_front, q.front());
228 EXPECT_EQ(expected_back, q.back());
229 EXPECT_EQ(expected_front, const_q.front());
230 EXPECT_EQ(expected_back, const_q.back());
231
232 expected_front--;
233 expected_back--;
234
235 q.pop_back();
236 q.push_front(expected_front);
237 }
238 }
239
240 TEST(CircularDeque, ReallocateWithSplitBuffer) {
241 // Tests reallocating a deque with an internal buffer that looks like this:
242 // 4 5 x x 0 1 2 3
243 // end-^ ^-begin
244 circular_deque<int> q;
245 q.reserve(7); // Internal buffer is always 1 larger than requested.
246 q.push_back(-1);
247 q.push_back(-1);
248 q.push_back(-1);
249 q.push_back(-1);
250 q.push_back(0);
251 q.pop_front();
252 q.pop_front();
253 q.pop_front();
254 q.pop_front();
255 q.push_back(1);
256 q.push_back(2);
257 q.push_back(3);
258 q.push_back(4);
259 q.push_back(5);
260
261 q.shrink_to_fit();
262 EXPECT_EQ(6u, q.size());
263
264 EXPECT_EQ(0, q[0]);
265 EXPECT_EQ(1, q[1]);
266 EXPECT_EQ(2, q[2]);
267 EXPECT_EQ(3, q[3]);
268 EXPECT_EQ(4, q[4]);
269 EXPECT_EQ(5, q[5]);
270 }
271
272 TEST(CircularDeque, Swap) {
273 circular_deque<int> a = MakeSequence(10);
274 circular_deque<int> b = MakeSequence(100);
275
276 a.swap(b);
277 EXPECT_EQ(100u, a.size());
278 for (int i = 0; i < 100; i++)
279 EXPECT_EQ(i, a[i]);
280
281 EXPECT_EQ(10u, b.size());
282 for (int i = 0; i < 10; i++)
283 EXPECT_EQ(i, b[i]);
284 }
285
286 TEST(CircularDeque, Iteration) {
287 circular_deque<int> q = MakeSequence(10);
288
289 int expected_front = 0;
290 int expected_back = 9;
291
292 // This loop causes various combinations of begin and end to be tested.
293 for (int i = 0; i < 30; i++) {
294 // Range-based for loop going forward.
295 int current_expected = expected_front;
296 for (int cur : q) {
297 EXPECT_EQ(current_expected, cur);
298 current_expected++;
299 }
300
301 // Manually test reverse iterators.
302 current_expected = expected_back;
303 for (auto cur = q.crbegin(); cur < q.crend(); cur++) {
304 EXPECT_EQ(current_expected, *cur);
305 current_expected--;
306 }
307
308 expected_front++;
309 expected_back++;
310
311 q.pop_front();
312 q.push_back(expected_back);
313 }
314
315 // Go back in reverse.
316 for (int i = 0; i < 100; i++) {
317 const circular_deque<int> const_q(q);
318
319 EXPECT_EQ(expected_front, q.front());
320 EXPECT_EQ(expected_back, q.back());
321 EXPECT_EQ(expected_front, const_q.front());
322 EXPECT_EQ(expected_back, const_q.back());
323
324 expected_front--;
325 expected_back--;
326
327 q.pop_back();
328 q.push_front(expected_front);
329 }
330 }
331
332 TEST(CircularDeque, IteratorComparisons) {
333 circular_deque<int> q = MakeSequence(10);
334
335 // This loop causes various combinations of begin and end to be tested.
336 for (int i = 0; i < 30; i++) {
337 EXPECT_LT(q.begin(), q.end());
338 EXPECT_LE(q.begin(), q.end());
339 EXPECT_LE(q.begin(), q.begin());
340
341 EXPECT_GT(q.end(), q.begin());
342 EXPECT_GE(q.end(), q.begin());
343 EXPECT_GE(q.end(), q.end());
344
345 EXPECT_EQ(q.begin(), q.begin());
346 EXPECT_NE(q.begin(), q.end());
347
348 q.push_front(10);
349 q.pop_back();
350 }
351 }
352
353 TEST(CircularDeque, IteratorIntegerOps) {
354 circular_deque<int> q = MakeSequence(10);
355
356 int expected_front = 0;
357 int expected_back = 9;
358
359 for (int i = 0; i < 30; i++) {
360 EXPECT_EQ(0, q.begin() - q.begin());
361 EXPECT_EQ(0, q.end() - q.end());
362 EXPECT_EQ(q.size(), static_cast<size_t>(q.end() - q.begin()));
363
364 // +=
365 circular_deque<int>::iterator eight = q.begin();
366 eight += 8;
367 EXPECT_EQ(8, eight - q.begin());
368 EXPECT_EQ(expected_front + 8, *eight);
369
370 // -=
371 eight -= 8;
372 EXPECT_EQ(q.begin(), eight);
373
374 // +
375 eight = eight + 8;
376 EXPECT_EQ(8, eight - q.begin());
377
378 // -
379 eight = eight - 8;
380 EXPECT_EQ(q.begin(), eight);
381
382 expected_front++;
383 expected_back++;
384
385 q.pop_front();
386 q.push_back(expected_back);
387 }
388 }
389
390 TEST(CircularDeque, CapacityReserveShrink) {
391 circular_deque<int> q;
392
393 // A default constructed queue should have no capacity since it should waste
394 // no space.
395 EXPECT_TRUE(q.empty());
396 EXPECT_EQ(0u, q.size());
397 EXPECT_EQ(0u, q.capacity());
398
399 size_t new_capacity = 100;
400 q.reserve(new_capacity);
401 EXPECT_EQ(new_capacity, q.capacity());
402
403 // Adding that many items should not cause a resize.
404 for (size_t i = 0; i < new_capacity; i++)
405 q.push_back(i);
406 EXPECT_EQ(new_capacity, q.size());
407 EXPECT_EQ(new_capacity, q.capacity());
408
409 // Shrinking doesn't resize capacity.
410 size_t capacity_2 = new_capacity / 2;
411 q.resize(capacity_2);
412 EXPECT_EQ(capacity_2, q.size());
413 EXPECT_EQ(new_capacity, q.capacity());
414
415 // Shrink to fit to that size.
416 q.shrink_to_fit();
417 EXPECT_EQ(capacity_2, q.size());
418 EXPECT_EQ(capacity_2, q.capacity());
419
420 // Shrink to 0, should have the same capacity.
421 q.resize(0);
422 EXPECT_EQ(0u, q.size());
423 EXPECT_EQ(capacity_2, q.capacity());
424
425 // Shrinking to fit should give 0 capacity.
426 q.shrink_to_fit();
427 EXPECT_EQ(0u, q.size());
428 EXPECT_EQ(0u, q.capacity());
429 }
430
431 TEST(CircularDeque, ClearAndEmpty) {
432 circular_deque<int> q;
433 EXPECT_TRUE(q.empty());
434
435 q.resize(10);
436 EXPECT_EQ(10u, q.size());
437 EXPECT_FALSE(q.empty());
438
439 q.clear();
440 EXPECT_EQ(0u, q.size());
441 EXPECT_TRUE(q.empty());
442 }
443
444 TEST(CircularDeque, Resize) {
445 circular_deque<int> q;
446
447 // Resize with default constructor.
448 size_t first_size = 10;
449 q.resize(first_size);
450 EXPECT_EQ(first_size, q.size());
451 for (size_t i = 0; i < first_size; i++)
452 EXPECT_EQ(0, q[i]);
453
454 // Resize with different value.
455 size_t second_expand = 10;
456 q.resize(first_size + second_expand, 3);
457 EXPECT_EQ(first_size + second_expand, q.size());
458 for (size_t i = 0; i < first_size; i++)
459 EXPECT_EQ(0, q[i]);
460 for (size_t i = 0; i < second_expand; i++)
461 EXPECT_EQ(3, q[i + first_size]);
462
463 // Erase from the end and add to the beginning so resize is forced to cross
464 // a circular buffer wrap boundary.
465 q.shrink_to_fit();
466 for (int i = 0; i < 5; i++) {
467 q.pop_back();
468 q.push_front(6);
469 }
470 q.resize(10);
471
472 EXPECT_EQ(6, q[0]);
473 EXPECT_EQ(6, q[1]);
474 EXPECT_EQ(6, q[2]);
475 EXPECT_EQ(6, q[3]);
476 EXPECT_EQ(6, q[4]);
477 EXPECT_EQ(0, q[5]);
478 EXPECT_EQ(0, q[6]);
479 EXPECT_EQ(0, q[7]);
480 EXPECT_EQ(0, q[8]);
481 EXPECT_EQ(0, q[9]);
482 }
483
484 /*
485 This test should assert in a debug build. It tries to dereference an iterator
486 after mutating the container. Uncomment to double-check that this works.
487 TEST(CircularDeque, UseIteratorAfterMutate) {
488 circular_deque<int> q;
489 q.push_back(0);
490
491 auto old_begin = q.begin();
492 EXPECT_EQ(0, *old_begin);
493
494 q.push_back(1);
495 EXPECT_EQ(0, *old_begin); // Should DCHECK.
496 }
497 */
498
499 } // namespace base
OLDNEW
« no previous file with comments | « base/containers/circular_deque.h ('k') | base/containers/queue.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698