1 | //===----------------------------------------------------------------------===// |
2 | // |
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | // See https://llvm.org/LICENSE.txt for license information. |
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | // |
7 | //===----------------------------------------------------------------------===// |
8 | |
9 | // <list> |
10 | |
11 | // UNSUPPORTED: c++03, no-exceptions |
12 | |
13 | // TODO: |
14 | // - throwing upon moving; |
15 | // - initializer lists; |
16 | // - throwing when constructing the element in place. |
17 | |
18 | // list(size_type n, const value_type& v); |
19 | // list(size_type n, const value_type& v, const allocator_type& a); |
20 | // template <class InputIterator> |
21 | // list(InputIterator first, InputIterator last); |
22 | // template <class InputIterator> |
23 | // list(InputIterator first, InputIterator last, const allocator_type& a); |
24 | // template<container-compatible-range<T> R> |
25 | // list(from_range_t, R&& rg, const Allocator& = Allocator()); // C++23 |
26 | // list(const list& x); |
27 | // list(const list& x, const allocator_type& a); |
28 | // |
29 | // list& operator=(const list& x); |
30 | // |
31 | // template <class InputIterator> |
32 | // void assign(InputIterator first, InputIterator last); |
33 | // void assign(size_type n, const value_type& v); |
34 | // template<container-compatible-range<T> R> |
35 | // void assign_range(R&& rg); // C++23 |
36 | // |
37 | // template<container-compatible-range<T> R> |
38 | // void prepend_range(R&& rg); // C++23 |
39 | // void push_back(const value_type& x); |
40 | // template<container-compatible-range<T> R> |
41 | // void append_range(R&& rg); // C++23 |
42 | // void push_front(const value_type& v); |
43 | // |
44 | // iterator insert(const_iterator p, const value_type& v); |
45 | // iterator insert(const_iterator p, size_type n, const value_type& v); |
46 | // template <class InputIterator> |
47 | // iterator insert(const_iterator p, |
48 | // InputIterator first, InputIterator last); |
49 | // template<container-compatible-range<T> R> |
50 | // iterator insert_range(const_iterator position, R&& rg); // C++23 |
51 | // |
52 | // void resize(size_type n, const value_type& v); |
53 | |
54 | #include <list> |
55 | |
56 | #include <cassert> |
57 | #include "../../exception_safety_helpers.h" |
58 | #include "test_macros.h" |
59 | |
60 | #if TEST_STD_VER >= 23 |
61 | #include <ranges> |
62 | #endif |
63 | |
64 | int main(int, char**) { |
65 | { |
66 | constexpr int ThrowOn = 1; |
67 | constexpr int Size = 1; |
68 | using T = ThrowingCopy<ThrowOn>; |
69 | |
70 | // void push_front(const value_type& v); |
71 | test_exception_safety_throwing_copy<ThrowOn, Size>(func: [](T* from, T*){ |
72 | std::list<T> c; |
73 | c.push_front(x: *from); |
74 | }); |
75 | |
76 | // void push_back(const value_type& v); |
77 | test_exception_safety_throwing_copy<ThrowOn, Size>(func: [](T* from, T*){ |
78 | std::list<T> c; |
79 | c.push_back(x: *from); |
80 | }); |
81 | |
82 | // iterator insert(const_iterator p, const value_type& v); |
83 | test_exception_safety_throwing_copy</*ThrowOn=*/1, Size>(func: [](T* from, T*){ |
84 | std::list<T> c; |
85 | c.insert(position: c.end(), x: *from); |
86 | }); |
87 | } |
88 | |
89 | { |
90 | constexpr int ThrowOn = 3; |
91 | constexpr int Size = 5; |
92 | using T = ThrowingCopy<ThrowOn>; |
93 | using C = std::list<T>; |
94 | using Alloc = std::allocator<T>; |
95 | |
96 | // list(size_type n, const value_type& v); |
97 | test_exception_safety_throwing_copy<ThrowOn, Size>(func: [](T* from, T*){ |
98 | std::list<T> c(Size, *from); |
99 | (void)c; |
100 | }); |
101 | |
102 | // list(size_type n, const value_type& v, const allocator_type& a); |
103 | test_exception_safety_throwing_copy<ThrowOn, Size>(func: [](T* from, T*){ |
104 | std::list<T> c(Size, *from, Alloc()); |
105 | (void)c; |
106 | }); |
107 | |
108 | // template <class InputIterator> |
109 | // list(InputIterator first, InputIterator last); |
110 | test_exception_safety_throwing_copy<ThrowOn, Size>(func: [](T* from, T* to){ |
111 | std::list<T> c(from, to); |
112 | (void)c; |
113 | }); |
114 | |
115 | // template <class InputIterator> |
116 | // list(InputIterator first, InputIterator last, const allocator_type& a); |
117 | test_exception_safety_throwing_copy<ThrowOn, Size>(func: [](T* from, T* to){ |
118 | std::list<T> c(from, to, Alloc()); |
119 | (void)c; |
120 | }); |
121 | |
122 | #if TEST_STD_VER >= 23 |
123 | // template<container-compatible-range<T> R> |
124 | // list(from_range_t, R&& rg, const Allocator& = Allocator()); // C++23 |
125 | test_exception_safety_throwing_copy<ThrowOn, Size>([](T* from, T* to){ |
126 | { |
127 | std::list<T> c(std::from_range, std::ranges::subrange(from, to)); |
128 | (void)c; |
129 | } |
130 | |
131 | { |
132 | std::list<T> c(std::from_range, std::ranges::subrange(from, to), Alloc()); |
133 | (void)c; |
134 | } |
135 | }); |
136 | #endif |
137 | |
138 | // list(const list& x); |
139 | test_exception_safety_throwing_copy_container<C, ThrowOn, Size>(func: [](C&& in) { |
140 | std::list<T> c(in); |
141 | (void)c; |
142 | }); |
143 | |
144 | // list(const list& x, const allocator_type& a); |
145 | test_exception_safety_throwing_copy_container<C, ThrowOn, Size>(func: [](C&& in) { |
146 | std::list<T> c(in, Alloc()); |
147 | (void)c; |
148 | }); |
149 | |
150 | // list& operator=(const list& x); |
151 | test_exception_safety_throwing_copy_container<C, ThrowOn, Size>(func: [](C&& in) { |
152 | std::list<T> c; |
153 | c = in; |
154 | }); |
155 | |
156 | // template <class InputIterator> |
157 | // void assign(InputIterator first, InputIterator last); |
158 | test_exception_safety_throwing_copy<ThrowOn, Size>(func: [](T* from, T* to) { |
159 | std::list<T> c; |
160 | c.assign(first: from, last: to); |
161 | }); |
162 | |
163 | #if TEST_STD_VER >= 23 |
164 | // template<container-compatible-range<T> R> |
165 | // void assign_range(R&& rg); // C++23 |
166 | test_exception_safety_throwing_copy<ThrowOn, Size>([](T* from, T* to) { |
167 | std::list<T> c; |
168 | c.assign_range(std::ranges::subrange(from, to)); |
169 | }); |
170 | #endif |
171 | |
172 | // void assign(size_type n, const value_type& v); |
173 | test_exception_safety_throwing_copy<ThrowOn, Size>(func: [](T* from, T*) { |
174 | std::list<T> c; |
175 | c.assign(n: Size, val: *from); |
176 | }); |
177 | |
178 | #if TEST_STD_VER >= 23 |
179 | // template<container-compatible-range<T> R> |
180 | // void prepend_range(R&& rg); // C++23 |
181 | test_exception_safety_throwing_copy<ThrowOn, Size>([](T* from, T* to) { |
182 | std::list<T> c; |
183 | c.prepend_range(std::ranges::subrange(from, to)); |
184 | }); |
185 | |
186 | // template<container-compatible-range<T> R> |
187 | // void append_range(R&& rg); // C++23 |
188 | test_exception_safety_throwing_copy<ThrowOn, Size>([](T* from, T* to) { |
189 | std::list<T> c; |
190 | c.append_range(std::ranges::subrange(from, to)); |
191 | }); |
192 | #endif |
193 | |
194 | // iterator insert(const_iterator p, size_type n, const value_type& v); |
195 | test_exception_safety_throwing_copy<ThrowOn, Size>(func: [](T* from, T*) { |
196 | std::list<T> c; |
197 | c.insert(position: c.end(), n: Size, x: *from); |
198 | }); |
199 | |
200 | // template <class InputIterator> |
201 | // iterator insert(const_iterator p, |
202 | // InputIterator first, InputIterator last); |
203 | test_exception_safety_throwing_copy<ThrowOn, Size>(func: [](T* from, T* to) { |
204 | std::list<T> c; |
205 | c.insert(position: c.end(), first: from, last: to); |
206 | }); |
207 | |
208 | #if TEST_STD_VER >= 23 |
209 | // template<container-compatible-range<T> R> |
210 | // iterator insert_range(const_iterator position, R&& rg); // C++23 |
211 | test_exception_safety_throwing_copy<ThrowOn, Size>([](T* from, T* to) { |
212 | std::list<T> c; |
213 | c.insert_range(c.end(), std::ranges::subrange(from, to)); |
214 | }); |
215 | #endif |
216 | |
217 | // void resize(size_type n, const value_type& v); |
218 | test_exception_safety_throwing_copy<ThrowOn, Size>(func: [](T* from, T*) { |
219 | std::list<T> c; |
220 | c.resize(new_size: Size, x: *from); |
221 | }); |
222 | } |
223 | |
224 | return 0; |
225 | } |
226 | |