[libcxx-commits] [libcxx] [libc++][test] Fix and refactor exception tests for std::vector (PR #117662)
Peng Liu via libcxx-commits
libcxx-commits at lists.llvm.org
Tue Nov 26 13:11:25 PST 2024
================
@@ -17,145 +17,65 @@
#include <vector>
#include "count_new.h"
+#include "exception_test_helpers.h"
+#include "test_allocator.h"
#include "test_iterators.h"
-template <class T>
-struct Allocator {
- using value_type = T;
- using is_always_equal = std::false_type;
-
- template <class U>
- Allocator(const Allocator<U>&) {}
-
- Allocator(bool should_throw = true) {
- if (should_throw)
- throw 0;
- }
-
- T* allocate(std::size_t n) { return std::allocator<T>().allocate(n); }
- void deallocate(T* ptr, std::size_t n) { std::allocator<T>().deallocate(ptr, n); }
-
- template <class U>
- friend bool operator==(const Allocator&, const Allocator<U>&) { return true; }
-};
-
-struct ThrowingT {
- int* throw_after_n_ = nullptr;
- ThrowingT() { throw 0; }
-
- ThrowingT(int& throw_after_n) : throw_after_n_(&throw_after_n) {
- if (throw_after_n == 0)
- throw 0;
- --throw_after_n;
- }
-
- ThrowingT(const ThrowingT& rhs) : throw_after_n_(rhs.throw_after_n_) {
- if (throw_after_n_ == nullptr || *throw_after_n_ == 0)
- throw 1;
- --*throw_after_n_;
- }
-
- ThrowingT& operator=(const ThrowingT& rhs) {
- throw_after_n_ = rhs.throw_after_n_;
- if (throw_after_n_ == nullptr || *throw_after_n_ == 0)
- throw 1;
- --*throw_after_n_;
- return *this;
- }
-};
-
-template <class IterCat>
-struct Iterator {
- using iterator_category = IterCat;
- using difference_type = std::ptrdiff_t;
- using value_type = int;
- using reference = int&;
- using pointer = int*;
-
- int i_;
- Iterator(int i = 0) : i_(i) {}
- int& operator*() {
- if (i_ == 1)
- throw 1;
- return i_;
- }
-
- friend bool operator==(const Iterator& lhs, const Iterator& rhs) { return lhs.i_ == rhs.i_; }
-
- friend bool operator!=(const Iterator& lhs, const Iterator& rhs) { return lhs.i_ != rhs.i_; }
-
- Iterator& operator++() {
- ++i_;
- return *this;
- }
-
- Iterator operator++(int) {
- auto tmp = *this;
- ++i_;
- return tmp;
- }
-};
-
-void check_new_delete_called() {
- assert(globalMemCounter.new_called == globalMemCounter.delete_called);
- assert(globalMemCounter.new_array_called == globalMemCounter.delete_array_called);
- assert(globalMemCounter.aligned_new_called == globalMemCounter.aligned_delete_called);
- assert(globalMemCounter.aligned_new_array_called == globalMemCounter.aligned_delete_array_called);
-}
-
int main(int, char**) {
- using AllocVec = std::vector<int, Allocator<int> >;
+ using AllocVec = std::vector<int, throwing_allocator<int> >;
try { // vector()
AllocVec vec;
} catch (int) {
}
check_new_delete_called();
try { // Throw in vector(size_type) from type
- std::vector<ThrowingT> get_alloc(1);
+ std::vector<throwing_t> get_alloc(1);
} catch (int) {
}
check_new_delete_called();
#if TEST_STD_VER >= 14
try { // Throw in vector(size_type, value_type) from type
int throw_after = 1;
- ThrowingT v(throw_after);
- std::vector<ThrowingT> get_alloc(1, v);
+ throwing_t v(throw_after);
+ std::vector<throwing_t> get_alloc(1, v);
} catch (int) {
}
check_new_delete_called();
- try { // Throw in vector(size_type, const allocator_type&) from allocator
- Allocator<int> alloc(false);
+ try { // Throw in vector(size_type, const allocator_type&) from allocator
+ throwing_allocator<int> alloc(false, true); // throw on copy only
AllocVec get_alloc(0, alloc);
} catch (int) {
}
----------------
winner245 wrote:
I think the original test passed false to the constructor to avoid an immediate exception throw. However, the issue is that no exceptions were being thrown elsewhere. That's why I added the throw_on_copy_ flag, allowing us to trigger an exception later when the allocator is copied.
https://github.com/llvm/llvm-project/pull/117662
More information about the libcxx-commits
mailing list