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 :
15 : #include <concepts>
16 : #include <exception>
17 : #include <type_traits>
18 : #include <utility>
19 :
20 : namespace boost {
21 : namespace capy {
22 : namespace detail {
23 :
24 : struct default_handler
25 : {
26 : template<class T>
27 HIT 104 : void operator()(T&&) const noexcept
28 : {
29 104 : }
30 :
31 3439 : void operator()() const noexcept
32 : {
33 3439 : }
34 :
35 : // An unhandled exception propagates to the trampoline's
36 : // unhandled_exception, which terminates.
37 336 : void operator()(std::exception_ptr ep) const
38 : {
39 336 : if(ep)
40 335 : std::rethrow_exception(ep);
41 1 : }
42 : };
43 :
44 : template<class H1, class H2>
45 : struct handler_pair
46 : {
47 : static_assert(
48 : std::is_nothrow_move_constructible_v<H1> &&
49 : std::is_nothrow_move_constructible_v<H2>,
50 : "Handlers must be nothrow move constructible");
51 :
52 : H1 h1_;
53 : H2 h2_;
54 :
55 : template<class T>
56 80 : void operator()(T&& v)
57 : {
58 80 : h1_(std::forward<T>(v));
59 80 : }
60 :
61 12 : void operator()()
62 : {
63 12 : h1_();
64 12 : }
65 :
66 28 : void operator()(std::exception_ptr ep)
67 : {
68 28 : h2_(ep);
69 28 : }
70 : };
71 :
72 : template<class H1>
73 : struct handler_pair<H1, default_handler>
74 : {
75 : static_assert(
76 : std::is_nothrow_move_constructible_v<H1>,
77 : "Handler must be nothrow move constructible");
78 :
79 : H1 h1_;
80 :
81 : template<class T>
82 153 : void operator()(T&& v)
83 : {
84 153 : h1_(std::forward<T>(v));
85 153 : }
86 :
87 2004 : void operator()()
88 : {
89 2004 : h1_();
90 2004 : }
91 :
92 673 : void operator()(std::exception_ptr ep)
93 : {
94 : if constexpr(std::invocable<H1, std::exception_ptr>)
95 672 : h1_(ep);
96 : else
97 2 : default_handler{}(ep);
98 339 : }
99 : };
100 :
101 : } // namespace detail
102 : } // namespace capy
103 : } // namespace boost
104 :
105 : #endif
|