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