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