100.00% Lines (10/10) 100.00% Functions (3/3)
TLA Baseline Branch
Line Hits Code Line Hits Code
1   // 1   //
2   // Copyright (c) 2026 Steve Gerbino 2   // Copyright (c) 2026 Steve Gerbino
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_ABANDONABLE_HPP 10   #ifndef BOOST_CAPY_DETAIL_ABANDONABLE_HPP
11   #define BOOST_CAPY_DETAIL_ABANDONABLE_HPP 11   #define BOOST_CAPY_DETAIL_ABANDONABLE_HPP
12   12  
13   #include <boost/capy/detail/config.hpp> 13   #include <boost/capy/detail/config.hpp>
14   #include <boost/capy/ex/abandon.hpp> 14   #include <boost/capy/ex/abandon.hpp>
15   #include <boost/capy/ex/await_context.hpp> 15   #include <boost/capy/ex/await_context.hpp>
16   16  
17   #include <optional> 17   #include <optional>
18   #include <type_traits> 18   #include <type_traits>
19   #include <utility> 19   #include <utility>
20   20  
21   namespace boost { 21   namespace boost {
22   namespace capy { 22   namespace capy {
23   namespace detail { 23   namespace detail {
24   24  
25   /** Await an awaitable on behalf of a segment owner. 25   /** Await an awaitable on behalf of a segment owner.
26   26  
27   An owner suspended here is resumed either when the awaitable 27   An owner suspended here is resumed either when the awaitable
28   completes or to unwind its abandoned segment. In the second case the 28   completes or to unwind its abandoned segment. In the second case the
29   awaitable never completed, so the result is empty (or `false` for an 29   awaitable never completed, so the result is empty (or `false` for an
30   awaitable with no result) and the owner must destroy the awaitable 30   awaitable with no result) and the owner must destroy the awaitable
31   without reading it. 31   without reading it.
32   */ 32   */
33   template<class A> 33   template<class A>
34   struct abandonable 34   struct abandonable
35   { 35   {
36   using result_type = decltype(std::declval<A&>().await_resume()); 36   using result_type = decltype(std::declval<A&>().await_resume());
37   37  
38   A& a_; 38   A& a_;
39   chain_owner* owner_ = nullptr; 39   chain_owner* owner_ = nullptr;
40   40  
HITCBC 41   317 bool await_ready() 41   317 bool await_ready()
42   { 42   {
HITCBC 43   317 return a_.await_ready(); 43   317 return a_.await_ready();
44   } 44   }
45   45  
46   template<class H> 46   template<class H>
HITCBC 47   316 auto await_suspend(H h, await_context const* env) 47   316 auto await_suspend(H h, await_context const* env)
48   { 48   {
HITCBC 49   316 owner_ = env->owner; 49   316 owner_ = env->owner;
HITCBC 50   316 return a_.await_suspend(h, env); 50   316 return a_.await_suspend(h, env);
51   } 51   }
52   52  
HITCBC 53   313 auto await_resume() 53   313 auto await_resume()
54   { 54   {
HITCBC 55   313 bool const unwinding = owner_ && owner_->abandoned(); 55   313 bool const unwinding = owner_ && owner_->abandoned();
56   if constexpr(std::is_void_v<result_type>) 56   if constexpr(std::is_void_v<result_type>)
57   { 57   {
58   if(unwinding) 58   if(unwinding)
59   return false; 59   return false;
60   a_.await_resume(); 60   a_.await_resume();
61   return true; 61   return true;
62   } 62   }
63   else 63   else
64   { 64   {
HITCBC 65   313 if(unwinding) 65   313 if(unwinding)
HITCBC 66   33 return std::optional<result_type>(); 66   33 return std::optional<result_type>();
HITCBC 67   280 return std::optional<result_type>(a_.await_resume()); 67   280 return std::optional<result_type>(a_.await_resume());
68   } 68   }
69   } 69   }
70   }; 70   };
71   71  
72   } // namespace detail 72   } // namespace detail
73   } // namespace capy 73   } // namespace capy
74   } // namespace boost 74   } // namespace boost
75   75  
76   #endif 76   #endif