]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/leaf/test/exception_test.cpp
update ceph source to reef 18.1.2
[ceph.git] / ceph / src / boost / libs / leaf / test / exception_test.cpp
1 // Copyright 2018-2022 Emil Dotchevski and Reverge Studios, Inc.
2
3 // Distributed under the Boost Software License, Version 1.0. (See accompanying
4 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
5
6 #include <boost/leaf/config.hpp>
7
8 #ifdef BOOST_LEAF_NO_EXCEPTIONS
9
10 #include <iostream>
11
12 int main()
13 {
14 std::cout << "Unit test not applicable." << std::endl;
15 return 0;
16 }
17
18 #else
19
20 #ifdef BOOST_LEAF_TEST_SINGLE_HEADER
21 # include "leaf.hpp"
22 #else
23 # include <boost/leaf/handle_errors.hpp>
24 # include <boost/leaf/pred.hpp>
25 # include <boost/leaf/exception.hpp>
26 # include <boost/leaf/on_error.hpp>
27 #endif
28
29 #include "lightweight_test.hpp"
30
31 namespace leaf = boost::leaf;
32
33 struct info { int value; };
34
35 struct abstract_base_exception
36 {
37 virtual ~abstract_base_exception() { }
38 virtual int get_val() const = 0;
39 };
40
41 struct my_exception:
42 std::exception,
43 abstract_base_exception
44 {
45 int val;;
46 explicit my_exception(int val): val{val} { }
47 int get_val() const { return val; }
48 };
49
50 int get_val( abstract_base_exception const & ex )
51 {
52 return ex.get_val();
53 }
54
55 int get_val( my_exception const & ex )
56 {
57 return ex.val;
58 }
59
60 int get_val( leaf::catch_<abstract_base_exception> const & ex )
61 {
62 return ex.matched.get_val();
63 }
64
65 int get_val( leaf::catch_<my_exception> const & ex )
66 {
67 return ex.matched.val;
68 }
69
70 template <class Ex, class F>
71 int test( F && f )
72 {
73 return leaf::try_catch(
74 [&]() -> int
75 {
76 f();
77 return 0;
78 },
79
80 []( Ex ex, leaf::match_value<info,42>, leaf::e_source_location )
81 {
82 BOOST_TEST_EQ(get_val(ex), 42);
83 return 20;
84 },
85 []( Ex ex, leaf::match_value<info,42>, info x )
86 {
87 BOOST_TEST_EQ(get_val(ex), 42);
88 return 21;
89 },
90 []( Ex ex, leaf::e_source_location )
91 {
92 BOOST_TEST_EQ(get_val(ex), 42);
93 return 22;
94 },
95 []( Ex ex )
96 {
97 BOOST_TEST_EQ(get_val(ex), 42);
98 return 23;
99 },
100 []( leaf::match_value<info,42>, leaf::e_source_location )
101 {
102 return 40;
103 },
104 []( leaf::match_value<info,42>, info x )
105 {
106 return 41;
107 },
108 []( leaf::e_source_location )
109 {
110 return 42;
111 },
112 []
113 {
114 return 43;
115 } );
116 }
117
118 int main()
119 {
120 BOOST_TEST_EQ(20, test<leaf::catch_<my_exception>>([]{ BOOST_LEAF_THROW_EXCEPTION(my_exception(42), info{42}); }));
121 BOOST_TEST_EQ(20, test<leaf::catch_<my_exception>>([]{ throw BOOST_LEAF_EXCEPTION(my_exception(42), info{42}); }));
122 BOOST_TEST_EQ(21, test<leaf::catch_<my_exception>>([]{ throw leaf::exception(my_exception(42), info{42}); }));
123 BOOST_TEST_EQ(21, test<leaf::catch_<my_exception>>([]{ my_exception exc(42); throw leaf::exception(exc, info{42}); }));
124 BOOST_TEST_EQ(21, test<leaf::catch_<my_exception>>([]{ my_exception const exc(42); throw leaf::exception(exc, info{42}); }));
125 BOOST_TEST_EQ(22, test<leaf::catch_<my_exception>>([]{ BOOST_LEAF_THROW_EXCEPTION(my_exception(42)); }));
126 BOOST_TEST_EQ(22, test<leaf::catch_<my_exception>>([]{ throw BOOST_LEAF_EXCEPTION(my_exception(42)); }));
127 BOOST_TEST_EQ(23, test<leaf::catch_<my_exception>>([]{ throw leaf::exception(my_exception(42)); }));
128 BOOST_TEST_EQ(23, test<leaf::catch_<my_exception>>([]{ my_exception exc(42); throw leaf::exception(exc); }));
129 BOOST_TEST_EQ(23, test<leaf::catch_<my_exception>>([]{ my_exception const exc(42); throw leaf::exception(exc); }));
130
131 BOOST_TEST_EQ(20, test<my_exception const &>([]{ BOOST_LEAF_THROW_EXCEPTION(my_exception(42), info{42}); }));
132 BOOST_TEST_EQ(20, test<my_exception const &>([]{ throw BOOST_LEAF_EXCEPTION(my_exception(42), info{42}); }));
133 BOOST_TEST_EQ(21, test<my_exception const &>([]{ throw leaf::exception(my_exception(42), info{42}); }));
134 BOOST_TEST_EQ(21, test<my_exception const &>([]{ my_exception exc(42); throw leaf::exception(exc, info{42}); }));
135 BOOST_TEST_EQ(21, test<my_exception const &>([]{ my_exception const exc(42); throw leaf::exception(exc, info{42}); }));
136 BOOST_TEST_EQ(22, test<my_exception const &>([]{ BOOST_LEAF_THROW_EXCEPTION(my_exception(42)); }));
137 BOOST_TEST_EQ(22, test<my_exception const &>([]{ throw BOOST_LEAF_EXCEPTION(my_exception(42)); }));
138 BOOST_TEST_EQ(23, test<my_exception const &>([]{ throw leaf::exception(my_exception(42)); }));
139 BOOST_TEST_EQ(23, test<my_exception const &>([]{ my_exception exc(42); throw leaf::exception(exc); }));
140 BOOST_TEST_EQ(23, test<my_exception const &>([]{ my_exception const exc(42); throw leaf::exception(exc); }));
141
142 BOOST_TEST_EQ(40, test<my_exception &>([]{ BOOST_LEAF_THROW_EXCEPTION(info{42}); }));
143 BOOST_TEST_EQ(40, test<my_exception &>([]{ throw BOOST_LEAF_EXCEPTION(info{42}); }));
144 BOOST_TEST_EQ(41, test<my_exception &>([]{ throw leaf::exception(info{42}); }));
145 BOOST_TEST_EQ(41, test<my_exception &>([]{ info inf{42}; throw leaf::exception(inf); }));
146 BOOST_TEST_EQ(41, test<my_exception &>([]{ info const inf{42}; throw leaf::exception(inf); }));
147 BOOST_TEST_EQ(42, test<my_exception &>([]{ BOOST_LEAF_THROW_EXCEPTION(); }));
148 BOOST_TEST_EQ(42, test<my_exception &>([]{ throw BOOST_LEAF_EXCEPTION(); }));
149 BOOST_TEST_EQ(43, test<my_exception &>([]{ throw leaf::exception(); }));
150 BOOST_TEST_EQ(23, test<my_exception &>([]{ my_exception exc(42); throw leaf::exception(exc); }));
151 BOOST_TEST_EQ(23, test<my_exception &>([]{ my_exception const exc(42); throw leaf::exception(exc); }));
152
153 BOOST_TEST_EQ(20, test<my_exception const>([]{ BOOST_LEAF_THROW_EXCEPTION(my_exception(42), info{42}); }));
154 BOOST_TEST_EQ(20, test<my_exception const>([]{ throw BOOST_LEAF_EXCEPTION(my_exception(42), info{42}); }));
155 BOOST_TEST_EQ(21, test<my_exception const>([]{ throw leaf::exception(my_exception(42), info{42}); }));
156 BOOST_TEST_EQ(21, test<my_exception const>([]{ my_exception exc(42); throw leaf::exception(exc, info{42}); }));
157 BOOST_TEST_EQ(21, test<my_exception const>([]{ my_exception const exc(42); throw leaf::exception(exc, info{42}); }));
158 BOOST_TEST_EQ(22, test<my_exception const>([]{ BOOST_LEAF_THROW_EXCEPTION(my_exception(42)); }));
159 BOOST_TEST_EQ(22, test<my_exception const>([]{ throw BOOST_LEAF_EXCEPTION(my_exception(42)); }));
160 BOOST_TEST_EQ(23, test<my_exception const>([]{ throw leaf::exception(my_exception(42)); }));
161 BOOST_TEST_EQ(23, test<my_exception const>([]{ my_exception exc(42); throw leaf::exception(exc); }));
162 BOOST_TEST_EQ(23, test<my_exception const>([]{ my_exception const exc(42); throw leaf::exception(exc); }));
163
164 BOOST_TEST_EQ(40, test<my_exception>([]{ BOOST_LEAF_THROW_EXCEPTION(info{42}); }));
165 BOOST_TEST_EQ(40, test<my_exception>([]{ throw BOOST_LEAF_EXCEPTION(info{42}); }));
166 BOOST_TEST_EQ(41, test<my_exception>([]{ throw leaf::exception(info{42}); }));
167 BOOST_TEST_EQ(41, test<my_exception>([]{ info inf{42}; throw leaf::exception(inf); }));
168 BOOST_TEST_EQ(41, test<my_exception>([]{ info const inf{42}; throw leaf::exception(inf); }));
169 BOOST_TEST_EQ(42, test<my_exception>([]{ BOOST_LEAF_THROW_EXCEPTION(); }));
170 BOOST_TEST_EQ(42, test<my_exception>([]{ throw BOOST_LEAF_EXCEPTION(); }));
171 BOOST_TEST_EQ(43, test<my_exception>([]{ throw leaf::exception(); }));
172 BOOST_TEST_EQ(23, test<my_exception>([]{ my_exception exc(42); throw leaf::exception(exc); }));
173 BOOST_TEST_EQ(23, test<my_exception>([]{ my_exception const exc(42); throw leaf::exception(exc); }));
174
175 BOOST_TEST_EQ(20, test<leaf::catch_<abstract_base_exception>>([]{ BOOST_LEAF_THROW_EXCEPTION(my_exception(42), info{42}); }));
176 BOOST_TEST_EQ(20, test<leaf::catch_<abstract_base_exception>>([]{ throw BOOST_LEAF_EXCEPTION(my_exception(42), info{42}); }));
177 BOOST_TEST_EQ(21, test<leaf::catch_<abstract_base_exception>>([]{ throw leaf::exception(my_exception(42), info{42}); }));
178 BOOST_TEST_EQ(21, test<leaf::catch_<abstract_base_exception>>([]{ my_exception exc(42); throw leaf::exception(exc, info{42}); }));
179 BOOST_TEST_EQ(21, test<leaf::catch_<abstract_base_exception>>([]{ my_exception const exc(42); throw leaf::exception(exc, info{42}); }));
180 BOOST_TEST_EQ(22, test<leaf::catch_<abstract_base_exception>>([]{ BOOST_LEAF_THROW_EXCEPTION(my_exception(42)); }));
181 BOOST_TEST_EQ(22, test<leaf::catch_<abstract_base_exception>>([]{ throw BOOST_LEAF_EXCEPTION(my_exception(42)); }));
182 BOOST_TEST_EQ(23, test<leaf::catch_<abstract_base_exception>>([]{ throw leaf::exception(my_exception(42)); }));
183 BOOST_TEST_EQ(23, test<leaf::catch_<abstract_base_exception>>([]{ my_exception exc(42); throw leaf::exception(exc); }));
184 BOOST_TEST_EQ(23, test<leaf::catch_<abstract_base_exception>>([]{ my_exception const exc(42); throw leaf::exception(exc); }));
185
186 BOOST_TEST_EQ(20, test<abstract_base_exception const &>([]{ BOOST_LEAF_THROW_EXCEPTION(my_exception(42), info{42}); }));
187 BOOST_TEST_EQ(20, test<abstract_base_exception const &>([]{ throw BOOST_LEAF_EXCEPTION(my_exception(42), info{42}); }));
188 BOOST_TEST_EQ(21, test<abstract_base_exception const &>([]{ throw leaf::exception(my_exception(42), info{42}); }));
189 BOOST_TEST_EQ(21, test<abstract_base_exception const &>([]{ my_exception exc(42); throw leaf::exception(exc, info{42}); }));
190 BOOST_TEST_EQ(21, test<abstract_base_exception const &>([]{ my_exception const exc(42); throw leaf::exception(exc, info{42}); }));
191 BOOST_TEST_EQ(22, test<abstract_base_exception const &>([]{ BOOST_LEAF_THROW_EXCEPTION(my_exception(42)); }));
192 BOOST_TEST_EQ(22, test<abstract_base_exception const &>([]{ throw BOOST_LEAF_EXCEPTION(my_exception(42)); }));
193 BOOST_TEST_EQ(23, test<abstract_base_exception const &>([]{ throw leaf::exception(my_exception(42)); }));
194 BOOST_TEST_EQ(23, test<abstract_base_exception const &>([]{ my_exception exc(42); throw leaf::exception(exc); }));
195 BOOST_TEST_EQ(23, test<abstract_base_exception const &>([]{ my_exception const exc(42); throw leaf::exception(exc); }));
196
197 BOOST_TEST_EQ(40, test<abstract_base_exception &>([]{ BOOST_LEAF_THROW_EXCEPTION(info{42}); }));
198 BOOST_TEST_EQ(40, test<abstract_base_exception &>([]{ throw BOOST_LEAF_EXCEPTION(info{42}); }));
199 BOOST_TEST_EQ(41, test<abstract_base_exception &>([]{ throw leaf::exception(info{42}); }));
200 BOOST_TEST_EQ(41, test<abstract_base_exception &>([]{ info inf{42}; throw leaf::exception(inf); }));
201 BOOST_TEST_EQ(41, test<abstract_base_exception &>([]{ info const inf{42}; throw leaf::exception(inf); }));
202 BOOST_TEST_EQ(42, test<abstract_base_exception &>([]{ BOOST_LEAF_THROW_EXCEPTION(); }));
203 BOOST_TEST_EQ(42, test<abstract_base_exception &>([]{ throw BOOST_LEAF_EXCEPTION(); }));
204 BOOST_TEST_EQ(43, test<abstract_base_exception &>([]{ throw leaf::exception(); }));
205 BOOST_TEST_EQ(23, test<abstract_base_exception &>([]{ my_exception exc(42); throw leaf::exception(exc); }));
206 BOOST_TEST_EQ(23, test<abstract_base_exception &>([]{ my_exception const exc(42); throw leaf::exception(exc); }));
207
208 {
209 char const * wh = 0;
210 leaf::try_catch(
211 []
212 {
213 throw std::runtime_error("Test");
214 },
215 [&]( std::exception const & ex )
216 {
217 wh = ex.what();
218 } );
219 BOOST_TEST(wh!=0 || !strcmp(wh,"Test"));
220 }
221
222 {
223 int const id = leaf::leaf_detail::current_id();
224 BOOST_TEST_EQ( 21, test<my_exception const &>( []
225 {
226 auto load = leaf::on_error(info{42});
227 throw my_exception(42);
228 } ) );
229 BOOST_TEST_NE(id, leaf::leaf_detail::current_id());
230 }
231
232 {
233 int const id = leaf::leaf_detail::current_id();
234 BOOST_TEST_EQ( 21, test<my_exception &>( []
235 {
236 auto load = leaf::on_error(info{42});
237 throw my_exception(42);
238 } ) );
239 BOOST_TEST_NE(id, leaf::leaf_detail::current_id());
240 }
241
242 {
243 BOOST_TEST_EQ( 23, test<my_exception const &>( []
244 {
245 int const id = leaf::leaf_detail::current_id();
246 try
247 {
248 leaf::try_catch(
249 []
250 {
251 throw my_exception(42);
252 } );
253 }
254 catch(...)
255 {
256 BOOST_TEST_EQ(id, leaf::leaf_detail::current_id());
257 throw;
258 }
259 } ) );
260 }
261
262 {
263 BOOST_TEST_EQ( 23, test<my_exception &>( []
264 {
265 int const id = leaf::leaf_detail::current_id();
266 try
267 {
268 leaf::try_catch(
269 []
270 {
271 throw my_exception(42);
272 } );
273 }
274 catch(...)
275 {
276 BOOST_TEST_EQ(id, leaf::leaf_detail::current_id());
277 throw;
278 }
279 } ) );
280 }
281
282 {
283 leaf::try_catch(
284 []
285 {
286 throw leaf::exception( info{42} );
287 },
288 []( info x )
289 {
290 BOOST_TEST_EQ(x.value, 42);
291 } );
292 int r = leaf::try_catch(
293 []() -> int
294 {
295 throw std::exception();
296 },
297 []( info x )
298 {
299 return -1;
300 },
301 []
302 {
303 return 1;
304 } );
305 BOOST_TEST_EQ(r, 1);
306 }
307
308 return boost::report_errors();
309 }
310
311 #endif