xref: /llvm-project/libcxx/test/std/containers/sequences/list/exception_safety.pass.cpp (revision ef70fe4d264d20abdd8476605650479a96a62071)
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 
main(int,char **)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>([](T* from, T*){
72       std::list<T> c;
73       c.push_front(*from);
74     });
75 
76     // void push_back(const value_type& v);
77     test_exception_safety_throwing_copy<ThrowOn, Size>([](T* from, T*){
78       std::list<T> c;
79       c.push_back(*from);
80     });
81 
82     // iterator insert(const_iterator p, const value_type& v);
83     test_exception_safety_throwing_copy</*ThrowOn=*/1, Size>([](T* from, T*){
84       std::list<T> c;
85       c.insert(c.end(), *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>([](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>([](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>([](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>([](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>([](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>([](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>([](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>([](T* from, T* to) {
159       std::list<T> c;
160       c.assign(from, 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>([](T* from, T*) {
174       std::list<T> c;
175       c.assign(Size, *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>([](T* from, T*) {
196       std::list<T> c;
197       c.insert(c.end(), Size, *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>([](T* from, T* to) {
204       std::list<T> c;
205       c.insert(c.end(), from, 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>([](T* from, T*) {
219       std::list<T> c;
220       c.resize(Size, *from);
221     });
222   }
223 
224   return 0;
225 }
226