]>
git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/leaf/examples/exception_to_result.cpp
1 // Copyright (c) 2018-2020 Emil Dotchevski and Reverge Studios, Inc.
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)
6 // This example demonstrates how to transport exceptions thrown by a low level function
7 // through an intermediate scopes that are not exception-safe, to be handled in a high
8 // level function which may or may not be exception-safe.
10 #include <boost/leaf/capture.hpp>
11 #include <boost/leaf/result.hpp>
12 #include <boost/leaf/handle_errors.hpp>
15 namespace leaf
= boost::leaf
;
18 class error_base
: public virtual std::exception
{ };
19 class error_a
: public virtual error_base
{ };
20 class error_b
: public virtual error_base
{ };
21 class error_c
: public virtual error_base
{ };
24 // Lower-level library function which throws exceptions.
25 int compute_answer_throws()
30 case 1: throw error_a();
31 case 2: throw error_b();
32 case 3: throw error_c();
37 // Call compute_answer_throws, switch to result<int> for error handling.
38 leaf::result
<int> compute_answer() noexcept
40 // Convert exceptions of types error_a and error_b to be communicated by leaf::result.
41 // Any other exception will be communicated as a std::exception_ptr.
42 return leaf::exception_to_result
<error_a
, error_b
>(
45 return compute_answer_throws();
50 // Print the answer if the call to compute_answer is successful.
51 leaf::result
<void> print_answer() noexcept
53 BOOST_LEAF_AUTO( answer
, compute_answer());
54 std::cout
<< "Answer: " << answer
<< std::endl
;
61 // Exercise print_answer a few times and handle errors. Note that the exception objects
62 // that compute_answer_throws throws are not handled as exceptions, but as regular
63 // LEAF error error objects...
64 for( int i
=0; i
!=42; ++i
)
67 []() -> leaf::result
<void>
69 BOOST_LEAF_CHECK(print_answer());
73 []( error_a
const & e
)
75 std::cerr
<< "Error A!" << std::endl
;
78 []( error_b
const & e
)
80 std::cerr
<< "Error B!" << std::endl
;
83 //...except for error_c errors, which (for demonstration) are captured as exceptions
84 // into std::exception_ptr as "unknown" exceptions. Presumably this should not
85 // happen, therefore at this point we treat this situation as a logic error: we print
86 // diagnostic information and bail out.
87 []( std::exception_ptr
const * ep
)
89 std::cerr
<< "Got unknown error!" << std::endl
;
91 // Above, why do we take ep as a pointer? Because handle_all requires that the last
92 // handler matches any error and, taken as a pointer, if there isn't a std::exception_ptr
93 // associated with the error, the handler will still be matched (with 0 passed for ep).
94 // Had we taken it by value or by const &, the program would not have compiled.
99 std::rethrow_exception(*ep
);
101 []( leaf::error_info
const & unmatched
)
103 std::cerr
<< unmatched
;