TLA Line data Source code
1 : //
2 : // Copyright (c) 2025 Vinnie Falco (vinnie.falco@gmail.com)
3 : //
4 : // Distributed under the Boost Software License, Version 1.0. (See accompanying
5 : // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6 : //
7 : // Official repository: https://github.com/cppalliance/capy
8 : //
9 :
10 : #ifndef BOOST_CAPY_DETAIL_RUN_CALLBACKS_HPP
11 : #define BOOST_CAPY_DETAIL_RUN_CALLBACKS_HPP
12 :
13 : #include <boost/capy/detail/config.hpp>
14 : #include <boost/capy/detail/stop_requested_exception.hpp>
15 :
16 : #include <concepts>
17 : #include <exception>
18 : #include <type_traits>
19 : #include <utility>
20 :
21 : namespace boost {
22 : namespace capy {
23 : namespace detail {
24 :
25 : struct default_handler
26 : {
27 : template<class T>
28 HIT 3 : void operator()(T&&) const noexcept
29 : {
30 3 : }
31 :
32 1850 : void operator()() const noexcept
33 : {
34 1850 : }
35 :
36 1034 : void operator()(std::exception_ptr ep) const
37 : {
38 1034 : if(!ep)
39 1 : return;
40 : try
41 : {
42 2066 : std::rethrow_exception(ep);
43 : }
44 1033 : catch(stop_requested_exception const&)
45 : {
46 : // Cancellation is a normal completion, not an error.
47 5 : }
48 : // A real unhandled exception propagates to the trampoline's
49 : // unhandled_exception, which terminates.
50 : }
51 : };
52 :
53 : template<class H1, class H2>
54 : struct handler_pair
55 : {
56 : static_assert(
57 : std::is_nothrow_move_constructible_v<H1> &&
58 : std::is_nothrow_move_constructible_v<H2>,
59 : "Handlers must be nothrow move constructible");
60 :
61 : H1 h1_;
62 : H2 h2_;
63 :
64 : template<class T>
65 80 : void operator()(T&& v)
66 : {
67 80 : h1_(std::forward<T>(v));
68 80 : }
69 :
70 21 : void operator()()
71 : {
72 21 : h1_();
73 21 : }
74 :
75 31 : void operator()(std::exception_ptr ep)
76 : {
77 31 : h2_(ep);
78 31 : }
79 : };
80 :
81 : template<class H1>
82 : struct handler_pair<H1, default_handler>
83 : {
84 : static_assert(
85 : std::is_nothrow_move_constructible_v<H1>,
86 : "Handler must be nothrow move constructible");
87 :
88 : H1 h1_;
89 :
90 : template<class T>
91 137 : void operator()(T&& v)
92 : {
93 137 : h1_(std::forward<T>(v));
94 137 : }
95 :
96 3565 : void operator()()
97 : {
98 3565 : h1_();
99 3565 : }
100 :
101 2059 : void operator()(std::exception_ptr ep)
102 : {
103 : if constexpr(std::invocable<H1, std::exception_ptr>)
104 2058 : h1_(ep);
105 : else
106 2 : default_handler{}(ep);
107 1032 : }
108 : };
109 :
110 : } // namespace detail
111 : } // namespace capy
112 : } // namespace boost
113 :
114 : #endif
|