LCOV - code coverage report
Current view: top level - boost/capy/ex - run_on.hpp (source / functions) Coverage Total Hit
Test: coverage_filtered.info Lines: 100.0 % 21 21
Test Date: 2026-01-22 22:47:31 Functions: 100.0 % 12 12

            Line data    Source code
       1              : //
       2              : // Copyright (c) 2025 Vinnie Falco (vinnie dot falco at gmail dot 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_RUN_ON_HPP
      11              : #define BOOST_CAPY_RUN_ON_HPP
      12              : 
      13              : #include <boost/capy/detail/config.hpp>
      14              : #include <boost/capy/concept/executor.hpp>
      15              : #include <boost/capy/io_awaitable.hpp>
      16              : #include <boost/capy/ex/executor_ref.hpp>
      17              : 
      18              : #include <stop_token>
      19              : #include <utility>
      20              : 
      21              : namespace boost {
      22              : namespace capy {
      23              : namespace detail {
      24              : 
      25              : /** Awaitable that binds an IoAwaitableTask to a specific executor.
      26              : 
      27              :     Stores the executor and inner task by value. When co_awaited, the
      28              :     co_await expression's lifetime extension keeps both alive for the
      29              :     duration of the operation.
      30              : 
      31              :     @tparam Task The IoAwaitableTask type
      32              :     @tparam Ex The executor type
      33              : */
      34              : template<IoLaunchableTask Task, Executor Ex>
      35              : struct [[nodiscard]]
      36              :     run_on_awaitable
      37              : {
      38              :     Ex ex_;
      39              :     Task inner_;
      40              : 
      41            2 :     run_on_awaitable(Ex ex, Task inner)
      42            2 :         : ex_(std::move(ex))
      43            2 :         , inner_(std::move(inner))
      44              :     {
      45            2 :     }
      46              : 
      47            2 :     bool await_ready() const noexcept
      48              :     {
      49            2 :         return inner_.await_ready();
      50              :     }
      51              : 
      52            2 :     auto await_resume()
      53              :     {
      54            2 :         return inner_.await_resume();
      55              :     }
      56              : 
      57              :     // IoAwaitable: receives caller's executor and stop_token for completion dispatch
      58              :     template<typename Caller>
      59            2 :     coro await_suspend(coro cont, Caller const& caller_ex, std::stop_token token)
      60              :     {
      61            2 :         auto h = inner_.handle();
      62            2 :         auto& p = h.promise();
      63            2 :         p.set_executor(ex_);
      64            2 :         p.set_continuation(cont, caller_ex);
      65            2 :         p.set_stop_token(token);
      66            2 :         return h;
      67              :     }
      68              : 
      69              :     // Non-copyable
      70              :     run_on_awaitable(run_on_awaitable const&) = delete;
      71              :     run_on_awaitable& operator=(run_on_awaitable const&) = delete;
      72              : 
      73              :     // Movable
      74            2 :     run_on_awaitable(run_on_awaitable&& other) noexcept
      75            2 :         : ex_(std::move(other.ex_))
      76            2 :         , inner_(std::move(other.inner_))
      77              :     {
      78            2 :     }
      79              : 
      80              :     run_on_awaitable& operator=(run_on_awaitable&& other) noexcept
      81              :     {
      82              :         if(this != &other)
      83              :         {
      84              :             ex_ = std::move(other.ex_);
      85              :             inner_ = std::move(other.inner_);
      86              :         }
      87              :         return *this;
      88              :     }
      89              : };
      90              : 
      91              : } // namespace detail
      92              : 
      93              : /** Binds a task to execute on a specific executor.
      94              : 
      95              :     The executor is stored by value in the returned awaitable.
      96              :     When co_awaited, the inner task receives this executor through
      97              :     direct promise configuration.
      98              : 
      99              :     @param ex The executor on which the task should run (copied by value).
     100              :     @param t The IoAwaitableTask to bind to the executor.
     101              : 
     102              :     @return An awaitable that runs t on the specified executor.
     103              : */
     104              : template<Executor Ex, IoLaunchableTask Task>
     105            2 : [[nodiscard]] auto run_on(Ex ex, Task t)
     106              : {
     107              :     return detail::run_on_awaitable<Task, Ex>{
     108            2 :         std::move(ex), std::move(t)};
     109              : }
     110              : 
     111              : } // namespace capy
     112              : } // namespace boost
     113              : 
     114              : #endif
        

Generated by: LCOV version 2.3