foundationdb/flow/Deque.cpp

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() {}