LCOV - code coverage report
Current view: top level - capy/asio - spawn.hpp (source / functions) Coverage Total Hit
Test: coverage_remapped.info Lines: 100.0 % 10 10
Test Date: 2026-05-01 02:54:45 Functions: 100.0 % 9 9

           TLA  Line data    Source code
       1                 : //
       2                 : // Copyright (c) 2026 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_ASIO_SPAWN_HPP
      11                 : #define BOOST_CAPY_ASIO_SPAWN_HPP
      12                 : 
      13                 : 
      14                 : #include <boost/capy/asio/executor_adapter.hpp>
      15                 : #include <boost/capy/asio/detail/completion_traits.hpp>
      16                 : #include <boost/capy/ex/frame_allocator.hpp>
      17                 : #include <boost/capy/concept/execution_context.hpp>
      18                 : #include <boost/capy/concept/executor.hpp>
      19                 : #include <boost/capy/concept/io_awaitable.hpp>
      20                 : 
      21                 : 
      22                 : namespace boost::capy
      23                 : {
      24                 : 
      25                 : /** @addtogroup asio
      26                 :  *  @{
      27                 :  */
      28                 : 
      29                 : namespace detail
      30                 : {
      31                 : 
      32                 : /** @brief Helper for initializing spawned coroutines with Boost.Asio tokens.
      33                 :  *  @internal
      34                 :  *
      35                 :  *  Specialized in `boost.hpp` for actual Boost.Asio completion tokens.
      36                 :  */
      37                 : template<typename Awaitable, typename Token>
      38                 : struct initialize_asio_spawn_helper;
      39                 : 
      40                 : /** @brief Concept for valid Boost.Asio spawn completion tokens.
      41                 :  *  @internal
      42                 :  *
      43                 :  *  A token satisfies this concept if `initialize_asio_spawn_helper` can
      44                 :  *  initialize the spawn operation with it.
      45                 :  */
      46                 : template<typename Token, typename Executor, typename Awaitable>
      47                 : concept asio_spawn_token =
      48                 :   requires (Token && tk, Executor ex, Awaitable rn)
      49                 :   {
      50                 :     initialize_asio_spawn_helper<Awaitable, Token>::
      51                 :         init(std::move(ex), std::move(rn), std::forward<Token>(tk));
      52                 :   };
      53                 : 
      54                 : /** @brief Helper for initializing spawned coroutines with standalone Asio tokens.
      55                 :  *  @internal
      56                 :  *
      57                 :  *  Specialized in `standalone.hpp` for actual standalone Asio completion tokens.
      58                 :  */
      59                 : template<typename Awaitable, typename Token>
      60                 : struct initialize_asio_standalone_spawn_helper;
      61                 : 
      62                 : /** @brief Concept for valid standalone Asio spawn completion tokens.
      63                 :  *  @internal
      64                 :  *
      65                 :  *  A token satisfies this concept if `initialize_asio_standalone_spawn_helper`
      66                 :  *  can initialize the spawn operation with it.
      67                 :  */
      68                 : template<typename Token, typename Executor, typename Awaitable>
      69                 : concept asio_standalone_spawn_token =
      70                 :   requires (Token && tk, Executor ex, Awaitable rn)
      71                 :   {
      72                 :     initialize_asio_standalone_spawn_helper<Awaitable, Token>::
      73                 :         init(std::move(ex), std::move(rn), std::forward<Token>(tk));
      74                 :   };
      75                 : 
      76                 : 
      77                 : }
      78                 : 
      79                 : /** @brief Deferred spawn operation that can be initiated with a completion token.
      80                 :  *
      81                 :  *  This class represents a spawn operation that has captured an executor and
      82                 :  *  awaitable but hasn't been initiated yet. Call `operator()` with a completion
      83                 :  *  token to start the operation.
      84                 :  *
      85                 :  *  @tparam Executor The executor type for running the coroutine
      86                 :  *  @tparam Awaitable The coroutine type (must satisfy `IoAwaitable`)
      87                 :  *
      88                 :  *  @par Example
      89                 :  *  @code
      90                 :  *  auto op = asio_spawn(executor, my_coroutine());
      91                 :  *
      92                 :  *  // Initiate with different tokens:
      93                 :  *  op(asio::detached);                    // Fire and forget
      94                 :  *  op([](std::exception_ptr) { ... });    // Callback on completion
      95                 :  *  co_await op(asio::use_awaitable);      // Await in another coroutine
      96                 :  *  @endcode
      97                 :  *
      98                 :  *  @see asio_spawn Factory function to create spawn operations
      99                 :  */
     100                 : template<Executor Executor, IoAwaitable Awaitable>
     101                 : struct asio_spawn_op
     102                 : {
     103                 :   /** @brief Constructs the spawn operation.
     104                 :    *  @param executor The executor to run on
     105                 :    *  @param awaitable The coroutine to spawn
     106                 :    */
     107 HIT           4 :   asio_spawn_op(Executor executor, Awaitable awaitable)
     108               4 :     : executor_(std::move(executor)), awaitable_(std::move(awaitable))
     109               4 :   {}
     110                 : 
     111                 :   /** @brief Initiates the spawn with a Boost.Asio completion token.
     112                 :    *
     113                 :    *  @tparam Token A valid Boost.Asio completion token
     114                 :    *  @param token The completion token determining how to handle completion
     115                 :    *  @return Depends on the token (e.g., void for callbacks, awaitable for use_awaitable)
     116                 :    */
     117                 :   template<detail::asio_spawn_token<Executor, Awaitable> Token>
     118               4 :   auto operator()(Token && token)
     119                 :   {
     120               6 :     return detail::initialize_asio_spawn_helper<Awaitable, Token>::init(
     121               4 :             std::move(executor_),
     122               4 :             std::move(awaitable_),
     123                 :             std::forward<Token>(token)
     124               6 :           );
     125                 :   }
     126                 : 
     127                 :   /** @brief Initiates the spawn with a standalone Asio completion token.
     128                 :    *
     129                 :    *  @tparam Token A valid standalone Asio completion token
     130                 :    *  @param token The completion token determining how to handle completion
     131                 :    *  @return Depends on the token
     132                 :    */
     133                 :   template<detail::asio_standalone_spawn_token<Executor, Awaitable> Token>
     134                 :   auto operator()(Token && token)
     135                 :   {
     136                 :     return detail::initialize_asio_standalone_spawn_helper<Awaitable, Token>::init
     137                 :           (
     138                 :             std::move(executor_),
     139                 :             std::move(awaitable_),
     140                 :             std::forward<Token>(token)
     141                 :           );
     142                 :   }
     143                 : 
     144                 :  private:
     145                 :   Executor executor_;
     146                 :   Awaitable awaitable_;
     147                 : };
     148                 : 
     149                 : 
     150                 : /** @brief Spawns a capy coroutine for execution with an Asio completion token.
     151                 :  *
     152                 :  *  Creates a deferred spawn operation that can be initiated with any Asio
     153                 :  *  completion token. The coroutine will run on the specified executor.
     154                 :  *
     155                 :  *  @tparam ExecutorType The executor type (must satisfy `Executor`)
     156                 :  *  @tparam Awaitable The coroutine type (must satisfy `IoAwaitable`)
     157                 :  *  @param exec The executor to run the coroutine on
     158                 :  *  @param awaitable The coroutine to spawn
     159                 :  *  @return An `asio_spawn_op` that can be called with a completion token
     160                 :  *
     161                 :  *  @par Completion Signature
     162                 :  *  The completion signature depends on the coroutine's return type:
     163                 :  *  - `void` return, noexcept: `void()`
     164                 :  *  - `void` return, may throw: `void(std::exception_ptr)`
     165                 :  *  - `T` return, noexcept: `void(T)`
     166                 :  *  - `T` return, may throw: `void(std::exception_ptr, T)`
     167                 :  *
     168                 :  *  @par Example
     169                 :  *  @code
     170                 :  *  capy::task<int> compute() { co_return 42; }
     171                 :  *
     172                 :  *  // Using with Boost.Asio
     173                 :  *  asio_spawn(executor, compute())(
     174                 :  *      [](std::exception_ptr ep, int result) {
     175                 :  *          if (!ep) std::cout << "Result: " << result << "\n";
     176                 :  *      });
     177                 :  *
     178                 :  *  // Using with asio::use_awaitable
     179                 :  *  auto [ep, result] = co_await asio_spawn(executor, compute())(asio::use_awaitable);
     180                 :  *  @endcode
     181                 :  *
     182                 :  *  @see asio_spawn_op The returned operation type
     183                 :  */
     184                 : template<Executor ExecutorType, IoAwaitable Awaitable>
     185               4 : auto asio_spawn(ExecutorType exec, Awaitable && awaitable)
     186                 : {
     187               4 :   return asio_spawn_op(std::move(exec), std::forward<Awaitable>(awaitable));
     188                 : }
     189                 : 
     190                 : /** @brief Spawns a capy coroutine using a context's executor.
     191                 :  *
     192                 :  *  Convenience overload that extracts the executor from an execution context.
     193                 :  *
     194                 :  *  @tparam Context The execution context type (must satisfy `ExecutionContext`)
     195                 :  *  @tparam Awaitable The coroutine type (must satisfy `IoAwaitable`)
     196                 :  *  @param ctx The execution context providing the executor
     197                 :  *  @param awaitable The coroutine to spawn
     198                 :  *  @return An `asio_spawn_op` that can be called with a completion token
     199                 :  *
     200                 :  *  @par Example
     201                 :  *  @code
     202                 :  *  boost::asio::io_context io;
     203                 :  *  asio_spawn(io, my_coroutine())(asio::detached);
     204                 :  *  io.run();
     205                 :  *  @endcode
     206                 :  */
     207                 : template<ExecutionContext Context, IoAwaitable Awaitable>
     208                 : auto asio_spawn(Context & ctx, Awaitable && awaitable)
     209                 : {
     210                 :   return asio_spawn_op(ctx.get_executor(), std::forward<Awaitable>(awaitable));
     211                 : }
     212                 : 
     213                 : /** @} */ // end of asio group
     214                 : 
     215                 : }
     216                 : 
     217                 : #endif
        

Generated by: LCOV version 2.3