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 1857 : void operator()() const noexcept
33 : {
34 1857 : }
35 :
36 1037 : void operator()(std::exception_ptr ep) const
37 : {
38 1037 : if(!ep)
39 1 : return;
40 : try
41 : {
42 2072 : std::rethrow_exception(ep);
43 : }
44 1036 : catch(stop_requested_exception const&)
45 : {
46 : // Cancellation is a normal completion, not an error.
47 6 : }
48 : }
49 : };
50 :
51 : template<class H1, class H2>
52 : struct handler_pair
53 : {
54 : static_assert(
55 : std::is_nothrow_move_constructible_v<H1> &&
56 : std::is_nothrow_move_constructible_v<H2>,
57 : "Handlers must be nothrow move constructible");
58 :
59 : H1 h1_;
60 : H2 h2_;
61 :
62 : template<class T>
63 80 : void operator()(T&& v)
64 : {
65 80 : h1_(std::forward<T>(v));
66 80 : }
67 :
68 21 : void operator()()
69 : {
70 21 : h1_();
71 21 : }
72 :
73 32 : void operator()(std::exception_ptr ep)
74 : {
75 32 : h2_(ep);
76 31 : }
77 : };
78 :
79 : template<class H1>
80 : struct handler_pair<H1, default_handler>
81 : {
82 : static_assert(
83 : std::is_nothrow_move_constructible_v<H1>,
84 : "Handler must be nothrow move constructible");
85 :
86 : H1 h1_;
87 :
88 : template<class T>
89 137 : void operator()(T&& v)
90 : {
91 137 : h1_(std::forward<T>(v));
92 137 : }
93 :
94 3565 : void operator()()
95 : {
96 3565 : h1_();
97 3565 : }
98 :
99 2059 : void operator()(std::exception_ptr ep)
100 : {
101 : if constexpr(std::invocable<H1, std::exception_ptr>)
102 2058 : h1_(ep);
103 : else
104 2 : default_handler{}(ep);
105 1032 : }
106 : };
107 :
108 : } // namespace detail
109 : } // namespace capy
110 : } // namespace boost
111 :
112 : #endif
|