xref: /llvm-project/libcxx/test/std/containers/sequences/forwardlist/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 // <forward_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 // forward_list(size_type n, const value_type& v);
19 // forward_list(size_type n, const value_type& v, const allocator_type& a);
20 // template <class InputIterator>
21 //     forward_list(InputIterator first, InputIterator last);
22 // template <class InputIterator>
23 //     forward_list(InputIterator first, InputIterator last, const allocator_type& a);
24 // forward_list(const forward_list& x);
25 // forward_list(const forward_list& x, const allocator_type& a);
26 // template<container-compatible-range<T> R>
27 //     forward_list(from_range_t, R&& rg, const Allocator& = Allocator()); // C++23
28 //
29 // forward_list& operator=(const forward_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 // void push_front(const value_type& v);
38 //  template<container-compatible-range<T> R>
39 //    void prepend_range(R&& rg); // C++23
40 //
41 // iterator insert_after(const_iterator p, const value_type& v);
42 // iterator insert_after(const_iterator p, size_type n, const value_type& v);
43 // template <class InputIterator>
44 //     iterator insert_after(const_iterator p,
45 //                           InputIterator first, InputIterator last);
46 //  template<container-compatible-range<T> R>
47 //     iterator insert_range_after(const_iterator position, R&& rg); // C++23
48 //
49 // void resize(size_type n, const value_type& v);
50 
51 #include <forward_list>
52 
53 #include <cassert>
54 #include "../../exception_safety_helpers.h"
55 #include "test_macros.h"
56 
57 #if TEST_STD_VER >= 23
58 #include <ranges>
59 #endif
60 
main(int,char **)61 int main(int, char**) {
62   {
63     constexpr int ThrowOn = 1;
64     constexpr int Size = 1;
65     using T = ThrowingCopy<ThrowOn>;
66 
67     // void push_front(const value_type& v);
68     test_exception_safety_throwing_copy<ThrowOn, Size>([](T* from, T*){
69       std::forward_list<T> c;
70       c.push_front(*from);
71     });
72 
73     // iterator insert_after(const_iterator p, const value_type& v);
74     test_exception_safety_throwing_copy</*ThrowOn=*/1, Size>([](T* from, T*){
75       std::forward_list<T> c;
76       c.insert_after(c.before_begin(), *from);
77     });
78   }
79 
80   {
81     constexpr int ThrowOn = 3;
82     constexpr int Size = 5;
83     using T = ThrowingCopy<ThrowOn>;
84     using C = std::forward_list<T>;
85     using Alloc = std::allocator<T>;
86 
87     // forward_list(size_type n, const value_type& v);
88     test_exception_safety_throwing_copy<ThrowOn, Size>([](T* from, T*){
89       std::forward_list<T> c(Size, *from);
90       (void)c;
91     });
92 
93     // forward_list(size_type n, const value_type& v, const allocator_type& a);
94     test_exception_safety_throwing_copy<ThrowOn, Size>([](T* from, T*){
95       std::forward_list<T> c(Size, *from, Alloc());
96       (void)c;
97     });
98 
99     // template <class InputIterator>
100     //     forward_list(InputIterator first, InputIterator last);
101     test_exception_safety_throwing_copy<ThrowOn, Size>([](T* from, T* to){
102       std::forward_list<T> c(from, to);
103       (void)c;
104     });
105 
106 #if TEST_STD_VER >= 23
107     // template<container-compatible-range<T> R>
108     //     forward_list(from_range_t, R&& rg, const Allocator& = Allocator()); // C++23
109     test_exception_safety_throwing_copy<ThrowOn, Size>([](T* from, T* to){
110       {
111         std::forward_list<T> c(std::from_range, std::ranges::subrange(from, to));
112         (void)c;
113       }
114 
115       {
116         std::forward_list<T> c(std::from_range, std::ranges::subrange(from, to), Alloc());
117         (void)c;
118       }
119     });
120 #endif
121 
122     // template <class InputIterator>
123     //     forward_list(InputIterator first, InputIterator last, const allocator_type& a);
124     test_exception_safety_throwing_copy<ThrowOn, Size>([](T* from, T* to){
125       std::forward_list<T> c(from, to, Alloc());
126       (void)c;
127     });
128 
129     // forward_list(const forward_list& x);
130     test_exception_safety_throwing_copy_container<C, ThrowOn, Size>([](C&& in) {
131       std::forward_list<T> c(in);
132       (void)c;
133     });
134 
135     // forward_list(const forward_list& x, const allocator_type& a);
136     test_exception_safety_throwing_copy_container<C, ThrowOn, Size>([](C&& in) {
137       std::forward_list<T> c(in, Alloc());
138       (void)c;
139     });
140 
141     // forward_list& operator=(const forward_list& x);
142     test_exception_safety_throwing_copy_container<C, ThrowOn, Size>([](C&& in) {
143       std::forward_list<T> c;
144       c = in;
145     });
146 
147     // template <class InputIterator>
148     //     void assign(InputIterator first, InputIterator last);
149     test_exception_safety_throwing_copy<ThrowOn, Size>([](T* from, T* to) {
150       std::forward_list<T> c;
151       c.assign(from, to);
152     });
153 
154 #if TEST_STD_VER >= 23
155     // template<container-compatible-range<T> R>
156     //     void assign_range(R&& rg); // C++23
157     test_exception_safety_throwing_copy<ThrowOn, Size>([](T* from, T* to) {
158       std::forward_list<T> c;
159       c.assign_range(std::ranges::subrange(from, to));
160     });
161 #endif
162 
163     // void assign(size_type n, const value_type& v);
164     test_exception_safety_throwing_copy<ThrowOn, Size>([](T* from, T*) {
165       std::forward_list<T> c;
166       c.assign(Size, *from);
167     });
168 
169 #if TEST_STD_VER >= 23
170     // template<container-compatible-range<T> R>
171     //   void prepend_range(R&& rg); // C++23
172     test_exception_safety_throwing_copy<ThrowOn, Size>([](T* from, T* to) {
173       std::forward_list<T> c;
174       c.prepend_range(std::ranges::subrange(from, to));
175     });
176 #endif
177 
178     // iterator insert_after(const_iterator p, size_type n, const value_type& v);
179     test_exception_safety_throwing_copy<ThrowOn, Size>([](T* from, T*) {
180       std::forward_list<T> c;
181       c.insert_after(c.before_begin(), Size, *from);
182     });
183 
184     // template <class InputIterator>
185     //     iterator insert_after(const_iterator p,
186     //                           InputIterator first, InputIterator last);
187     test_exception_safety_throwing_copy<ThrowOn, Size>([](T* from, T* to) {
188       std::forward_list<T> c;
189       c.insert_after(c.before_begin(), from, to);
190     });
191 
192 #if TEST_STD_VER >= 23
193     // template<container-compatible-range<T> R>
194     //     iterator insert_range_after(const_iterator position, R&& rg); // C++23
195     test_exception_safety_throwing_copy<ThrowOn, Size>([](T* from, T* to) {
196       std::forward_list<T> c;
197       c.insert_range_after(c.before_begin(), std::ranges::subrange(from, to));
198     });
199 #endif
200 
201     // void resize(size_type n, const value_type& v);
202     test_exception_safety_throwing_copy<ThrowOn, Size>([](T* from, T*) {
203       std::forward_list<T> c;
204       c.resize(Size, *from);
205     });
206   }
207 
208   return 0;
209 }
210