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
61int 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>(func: [](T* from, T*){
69 std::forward_list<T> c;
70 c.push_front(val: *from);
71 });
72
73 // iterator insert_after(const_iterator p, const value_type& v);
74 test_exception_safety_throwing_copy</*ThrowOn=*/1, Size>(func: [](T* from, T*){
75 std::forward_list<T> c;
76 c.insert_after(pos: c.before_begin(), val: *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>(func: [](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>(func: [](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>(func: [](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>(func: [](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>(func: [](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>(func: [](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>(func: [](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>(func: [](T* from, T* to) {
150 std::forward_list<T> c;
151 c.assign(first: from, last: 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>(func: [](T* from, T*) {
165 std::forward_list<T> c;
166 c.assign(n: Size, val: *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>(func: [](T* from, T*) {
180 std::forward_list<T> c;
181 c.insert_after(pos: c.before_begin(), n: Size, val: *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>(func: [](T* from, T* to) {
188 std::forward_list<T> c;
189 c.insert_after(pos: c.before_begin(), first: from, last: 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>(func: [](T* from, T*) {
203 std::forward_list<T> c;
204 c.resize(sz: Size, val: *from);
205 });
206 }
207
208 return 0;
209}
210

source code of libcxx/test/std/containers/sequences/forwardlist/exception_safety.pass.cpp