]>
git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/leaf/example/capture_in_result.cpp
1 // Copyright 2018-2022 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 is a simple program that demonstrates the use of LEAF to transport error
7 // objects between threads, without using exception handling. See capture_eh.cpp
8 // for the version that uses exception handling.
10 #include <boost/leaf.hpp>
18 namespace leaf
= boost::leaf
;
20 // Define several error types.
21 struct e_thread_id
{ std::thread::id value
; };
22 struct e_failure_info1
{ std::string value
; };
23 struct e_failure_info2
{ int value
; };
25 // A type that represents a successfully returned result from a task.
26 struct task_result
{ };
28 // This is our task function. It produces objects of type task_result, but it
30 leaf::result
<task_result
> task()
32 bool succeed
= (rand()%4) != 0; //...at random.
36 return leaf::new_error(
37 e_thread_id
{std::this_thread::get_id()},
38 e_failure_info1
{"info"},
39 e_failure_info2
{42} );
44 int const task_count
= 42;
46 // The error_handlers are used in this thread (see leaf::try_handle_all
47 // below). The arguments passed to individual lambdas are transported from
48 // the worker thread to the main thread automatically.
49 auto error_handlers
= std::make_tuple(
50 []( e_failure_info1
const & v1
, e_failure_info2
const & v2
, e_thread_id
const & tid
)
52 std::cerr
<< "Error in thread " << tid
.value
<< "! failure_info1: " << v1
.value
<< ", failure_info2: " << v2
.value
<< std::endl
;
54 []( leaf::diagnostic_info
const & unmatched
)
57 "Unknown failure detected" << std::endl
<<
58 "Cryptic diagnostic information follows" << std::endl
<<
62 // Container to collect the generated std::future objects.
63 std::vector
<std::future
<leaf::result
<task_result
>>> fut
;
65 // Launch the tasks, but rather than launching the task function directly,
66 // we launch a wrapper function which calls leaf::capture, passing a context
67 // object that will hold the error objects reported from the task in case of
68 // an error. The error types the context is able to hold statically are
69 // automatically deduced from the type of the error_handlers tuple.
70 std::generate_n( std::back_inserter(fut
), task_count
,
77 return leaf::capture(leaf::make_shared_context(error_handlers
), &task
);
81 // Wait on the futures, get the task results, handle errors.
87 [&]() -> leaf::result
<void>
89 BOOST_LEAF_AUTO(r
,f
.get());
91 // Success! Use r to access task_result.
92 std::cout
<< "Success!" << std::endl
;
93 (void) r
; // Presumably we'll somehow use the task_result.
100 ////////////////////////////////////////
102 #ifdef BOOST_LEAF_NO_EXCEPTIONS
106 BOOST_LEAF_NORETURN
void throw_exception( std::exception
const & e
)
108 std::cerr
<< "Terminating due to a C++ exception under BOOST_LEAF_NO_EXCEPTIONS: " << e
.what();
112 struct source_location
;
113 BOOST_LEAF_NORETURN
void throw_exception( std::exception
const & e
, boost::source_location
const & )