Added more exception safety to Deque::grow
This commit is contained in:
parent
da28face2c
commit
d6b6626a2b
|
@ -79,4 +79,41 @@ TEST_CASE("/flow/Deque/max_size") {
|
|||
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() {}
|
||||
|
|
|
@ -170,8 +170,15 @@ private:
|
|||
T* newArr = (T*)aligned_alloc(std::max(__alignof(T), sizeof(void*)),
|
||||
newSize * sizeof(T)); // SOMEDAY: FastAllocator
|
||||
ASSERT(newArr != nullptr);
|
||||
try {
|
||||
for (int i = begin; i != end; i++) {
|
||||
new (&newArr[i - begin]) T(std::move_if_noexcept(arr[i & mask]));
|
||||
}
|
||||
} catch (...) {
|
||||
aligned_free(newArr);
|
||||
throw;
|
||||
}
|
||||
for (int i = begin; i != end; i++) {
|
||||
new (&newArr[i - begin]) T(std::move_if_noexcept(arr[i & mask]));
|
||||
static_assert(std::is_nothrow_destructible_v<T>);
|
||||
arr[i&mask].~T();
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue