Skip to content

Commit 37654f5

Browse files
committed
Add exception tests for vector capacity operations
1 parent c4a1e0e commit 37654f5

File tree

5 files changed

+510
-115
lines changed

5 files changed

+510
-115
lines changed

libcxx/test/std/containers/sequences/vector/common.h

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,89 @@
1616

1717
#include "count_new.h"
1818

19+
template <typename T>
20+
struct move_only_throwing_t {
21+
T data_;
22+
int* throw_after_n_ = nullptr;
23+
bool moved_from_ = false;
24+
25+
move_only_throwing_t(const T& data, int& throw_after_n) : data_(data), throw_after_n_(&throw_after_n) {
26+
if (throw_after_n == 0)
27+
throw 0;
28+
--throw_after_n;
29+
}
30+
31+
move_only_throwing_t(T&& data, int& throw_after_n) : data_(std::move(data)), throw_after_n_(&throw_after_n) {
32+
if (throw_after_n == 0)
33+
throw 0;
34+
--throw_after_n;
35+
}
36+
37+
move_only_throwing_t(const move_only_throwing_t&) = delete;
38+
move_only_throwing_t& operator=(const move_only_throwing_t&) = delete;
39+
40+
move_only_throwing_t(move_only_throwing_t&& rhs) : data_(std::move(rhs.data_)), throw_after_n_(rhs.throw_after_n_) {
41+
rhs.throw_after_n_ = nullptr;
42+
rhs.moved_from_ = true;
43+
if (throw_after_n_ == nullptr || *throw_after_n_ == 0)
44+
throw 1;
45+
--*throw_after_n_;
46+
}
47+
48+
move_only_throwing_t& operator=(move_only_throwing_t&& rhs) {
49+
if (this == &rhs)
50+
return *this;
51+
data_ = std::move(rhs.data_);
52+
throw_after_n_ = rhs.throw_after_n_;
53+
rhs.moved_from_ = true;
54+
rhs.throw_after_n_ = nullptr;
55+
if (throw_after_n_ == nullptr || *throw_after_n_ == 0)
56+
throw 1;
57+
--*throw_after_n_;
58+
return *this;
59+
}
60+
61+
friend bool operator==(const move_only_throwing_t& lhs, const move_only_throwing_t& rhs) {
62+
return lhs.data_ == rhs.data_;
63+
}
64+
friend bool operator!=(const move_only_throwing_t& lhs, const move_only_throwing_t& rhs) {
65+
return lhs.data_ != rhs.data_;
66+
}
67+
};
68+
69+
template <typename T>
70+
struct throwing_data {
71+
T data_;
72+
int* throw_after_n_ = nullptr;
73+
throwing_data() { throw 0; }
74+
75+
throwing_data(const T& data, int& throw_after_n) : data_(data), throw_after_n_(&throw_after_n) {
76+
if (throw_after_n == 0)
77+
throw 0;
78+
--throw_after_n;
79+
}
80+
81+
throwing_data(const throwing_data& rhs) : data_(rhs.data_), throw_after_n_(rhs.throw_after_n_) {
82+
if (throw_after_n_ == nullptr || *throw_after_n_ == 0)
83+
throw 1;
84+
--*throw_after_n_;
85+
}
86+
87+
throwing_data& operator=(const throwing_data& rhs) {
88+
data_ = rhs.data_;
89+
throw_after_n_ = rhs.throw_after_n_;
90+
if (throw_after_n_ == nullptr || *throw_after_n_ == 0)
91+
throw 1;
92+
--*throw_after_n_;
93+
return *this;
94+
}
95+
96+
friend bool operator==(const throwing_data& lhs, const throwing_data& rhs) {
97+
return lhs.data_ == rhs.data_ && lhs.throw_after_n_ == rhs.throw_after_n_;
98+
}
99+
friend bool operator!=(const throwing_data& lhs, const throwing_data& rhs) { return !(lhs == rhs); }
100+
};
101+
19102
template <class T>
20103
struct throwing_allocator {
21104
using value_type = T;

libcxx/test/std/containers/sequences/vector/vector.capacity/reserve.pass.cpp

Lines changed: 65 additions & 115 deletions
Original file line numberDiff line numberDiff line change
@@ -19,126 +19,76 @@
1919
#include "asan_testing.h"
2020

2121
TEST_CONSTEXPR_CXX20 bool tests() {
22-
{
23-
std::vector<int> v;
24-
v.reserve(10);
25-
assert(v.capacity() >= 10);
26-
assert(is_contiguous_container_asan_correct(v));
27-
}
28-
{
29-
std::vector<int> v(100);
30-
assert(v.capacity() == 100);
31-
v.reserve(50);
32-
assert(v.size() == 100);
33-
assert(v.capacity() == 100);
34-
v.reserve(150);
35-
assert(v.size() == 100);
36-
assert(v.capacity() == 150);
37-
assert(is_contiguous_container_asan_correct(v));
38-
}
39-
{
40-
// Add 1 for implementations that dynamically allocate a container proxy.
41-
std::vector<int, limited_allocator<int, 250 + 1> > v(100);
42-
assert(v.capacity() == 100);
43-
v.reserve(50);
44-
assert(v.size() == 100);
45-
assert(v.capacity() == 100);
46-
v.reserve(150);
47-
assert(v.size() == 100);
48-
assert(v.capacity() == 150);
49-
assert(is_contiguous_container_asan_correct(v));
50-
}
51-
#ifndef TEST_HAS_NO_EXCEPTIONS
52-
if (!TEST_IS_CONSTANT_EVALUATED) {
53-
std::vector<int> v;
54-
std::size_t sz = v.max_size() + 1;
55-
56-
try {
57-
v.reserve(sz);
58-
assert(false);
59-
} catch (const std::length_error&) {
60-
assert(v.size() == 0);
61-
assert(v.capacity() == 0);
62-
}
63-
}
64-
if (!TEST_IS_CONSTANT_EVALUATED) {
65-
std::vector<int> v(10, 42);
66-
int* previous_data = v.data();
67-
std::size_t previous_capacity = v.capacity();
68-
std::size_t sz = v.max_size() + 1;
69-
70-
try {
71-
v.reserve(sz);
72-
assert(false);
73-
} catch (std::length_error&) {
74-
assert(v.size() == 10);
75-
assert(v.capacity() == previous_capacity);
76-
assert(v.data() == previous_data);
77-
78-
for (int i = 0; i < 10; ++i) {
79-
assert(v[i] == 42);
80-
}
81-
}
82-
}
83-
#endif
22+
{
23+
std::vector<int> v;
24+
v.reserve(10);
25+
assert(v.capacity() >= 10);
26+
assert(is_contiguous_container_asan_correct(v));
27+
}
28+
{
29+
std::vector<int> v(100);
30+
assert(v.capacity() == 100);
31+
v.reserve(50);
32+
assert(v.size() == 100);
33+
assert(v.capacity() == 100);
34+
v.reserve(150);
35+
assert(v.size() == 100);
36+
assert(v.capacity() == 150);
37+
assert(is_contiguous_container_asan_correct(v));
38+
}
39+
{
40+
// Add 1 for implementations that dynamically allocate a container proxy.
41+
std::vector<int, limited_allocator<int, 250 + 1> > v(100);
42+
assert(v.capacity() == 100);
43+
v.reserve(50);
44+
assert(v.size() == 100);
45+
assert(v.capacity() == 100);
46+
v.reserve(150);
47+
assert(v.size() == 100);
48+
assert(v.capacity() == 150);
49+
assert(is_contiguous_container_asan_correct(v));
50+
}
8451
#if TEST_STD_VER >= 11
85-
{
86-
std::vector<int, min_allocator<int>> v;
87-
v.reserve(10);
88-
assert(v.capacity() >= 10);
89-
assert(is_contiguous_container_asan_correct(v));
90-
}
91-
{
92-
std::vector<int, min_allocator<int>> v(100);
93-
assert(v.capacity() == 100);
94-
v.reserve(50);
95-
assert(v.size() == 100);
96-
assert(v.capacity() == 100);
97-
v.reserve(150);
98-
assert(v.size() == 100);
99-
assert(v.capacity() == 150);
100-
assert(is_contiguous_container_asan_correct(v));
101-
}
102-
{
103-
std::vector<int, safe_allocator<int>> v;
104-
v.reserve(10);
105-
assert(v.capacity() >= 10);
106-
assert(is_contiguous_container_asan_correct(v));
107-
}
108-
{
109-
std::vector<int, safe_allocator<int>> v(100);
110-
assert(v.capacity() == 100);
111-
v.reserve(50);
112-
assert(v.size() == 100);
113-
assert(v.capacity() == 100);
114-
v.reserve(150);
115-
assert(v.size() == 100);
116-
assert(v.capacity() == 150);
117-
assert(is_contiguous_container_asan_correct(v));
118-
}
119-
#endif
120-
#ifndef TEST_HAS_NO_EXCEPTIONS
121-
if (!TEST_IS_CONSTANT_EVALUATED) {
122-
std::vector<int, limited_allocator<int, 100> > v;
123-
v.reserve(50);
124-
assert(v.capacity() == 50);
125-
assert(is_contiguous_container_asan_correct(v));
126-
try {
127-
v.reserve(101);
128-
assert(false);
129-
} catch (const std::length_error&) {
130-
// no-op
131-
}
132-
assert(v.capacity() == 50);
133-
assert(is_contiguous_container_asan_correct(v));
134-
}
52+
{
53+
std::vector<int, min_allocator<int>> v;
54+
v.reserve(10);
55+
assert(v.capacity() >= 10);
56+
assert(is_contiguous_container_asan_correct(v));
57+
}
58+
{
59+
std::vector<int, min_allocator<int>> v(100);
60+
assert(v.capacity() == 100);
61+
v.reserve(50);
62+
assert(v.size() == 100);
63+
assert(v.capacity() == 100);
64+
v.reserve(150);
65+
assert(v.size() == 100);
66+
assert(v.capacity() == 150);
67+
assert(is_contiguous_container_asan_correct(v));
68+
}
69+
{
70+
std::vector<int, safe_allocator<int>> v;
71+
v.reserve(10);
72+
assert(v.capacity() >= 10);
73+
assert(is_contiguous_container_asan_correct(v));
74+
}
75+
{
76+
std::vector<int, safe_allocator<int>> v(100);
77+
assert(v.capacity() == 100);
78+
v.reserve(50);
79+
assert(v.size() == 100);
80+
assert(v.capacity() == 100);
81+
v.reserve(150);
82+
assert(v.size() == 100);
83+
assert(v.capacity() == 150);
84+
assert(is_contiguous_container_asan_correct(v));
85+
}
13586
#endif
13687

137-
return true;
88+
return true;
13889
}
13990

140-
int main(int, char**)
141-
{
91+
int main(int, char**) {
14292
tests();
14393

14494
#if TEST_STD_VER > 17

0 commit comments

Comments
 (0)