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