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