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