120 lines
2.7 KiB
C++
120 lines
2.7 KiB
C++
/*
|
|
* Deque.cpp
|
|
*
|
|
* This source file is part of the FoundationDB open source project
|
|
*
|
|
* Copyright 2013-2022 Apple Inc. and the FoundationDB project authors
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
#include "flow/UnitTest.h"
|
|
#include "flow/Deque.h"
|
|
|
|
TEST_CASE("/flow/Deque/12345") {
|
|
Deque<int> q;
|
|
q.push_back(1);
|
|
q.push_back(2);
|
|
q.push_back(3);
|
|
q.pop_front();
|
|
q.push_back(4);
|
|
q.pop_back();
|
|
q.push_back(5);
|
|
q.push_back(6);
|
|
q.pop_front();
|
|
q.pop_back();
|
|
ASSERT(q.size() == 2 && q[0] == 3 && q[1] == 5);
|
|
return Void();
|
|
}
|
|
|
|
TEST_CASE("/flow/Deque/queue") {
|
|
std::queue<int, Deque<int>> q;
|
|
|
|
int to_push = 0, to_pop = 0;
|
|
while (to_pop != 1000) {
|
|
if (to_push != 1000 && (q.empty() || deterministicRandom()->random01() < 0.55)) {
|
|
q.push(to_push++);
|
|
} else {
|
|
ASSERT(q.front() == to_pop++);
|
|
q.pop();
|
|
}
|
|
}
|
|
ASSERT(q.empty());
|
|
return Void();
|
|
}
|
|
|
|
TEST_CASE("/flow/Deque/max_size") {
|
|
Deque<uint8_t> q;
|
|
for (int i = 0; i < 10; i++)
|
|
q.push_back(i);
|
|
q.pop_front();
|
|
for (int64_t i = 10; i <= q.max_size(); i++)
|
|
q.push_back(i);
|
|
for (int i = 0; i < 100; i++) {
|
|
q.pop_front();
|
|
q.push_back(1);
|
|
}
|
|
for (int i = 0; i < 100; i++)
|
|
ASSERT(q[q.size() - 100 + i] == 1);
|
|
for (int64_t i = 101; i <= q.max_size(); i++) {
|
|
ASSERT(q[i - 101] == uint8_t(i));
|
|
}
|
|
ASSERT(&q.back() + 1 == &q.front());
|
|
try {
|
|
q.push_back(1);
|
|
ASSERT(false);
|
|
} catch (std::bad_alloc&) {
|
|
}
|
|
|
|
return Void();
|
|
}
|
|
|
|
struct RandomlyThrows {
|
|
int data = 0;
|
|
RandomlyThrows() = default;
|
|
explicit RandomlyThrows(int data) : data(data) {}
|
|
~RandomlyThrows() = default;
|
|
RandomlyThrows(const RandomlyThrows& other) : data(other.data) { randomlyThrow(); }
|
|
RandomlyThrows& operator=(const RandomlyThrows& other) {
|
|
data = other.data;
|
|
randomlyThrow();
|
|
return *this;
|
|
}
|
|
|
|
private:
|
|
void randomlyThrow() {
|
|
if (deterministicRandom()->random01() < 0.1) {
|
|
throw success();
|
|
}
|
|
}
|
|
};
|
|
|
|
TEST_CASE("/flow/Deque/grow_exception_safety") {
|
|
Deque<RandomlyThrows> q;
|
|
for (int i = 0; i < 100; ++i) {
|
|
loop {
|
|
try {
|
|
q.push_back(RandomlyThrows{ i });
|
|
break;
|
|
} catch (Error& e) {
|
|
}
|
|
}
|
|
}
|
|
for (int i = 0; i < 100; ++i) {
|
|
ASSERT(q[i].data == i);
|
|
}
|
|
return Void();
|
|
}
|
|
|
|
void forceLinkDequeTests() {}
|