LCOV - code coverage report
Current view: top level - capy/asio/detail - continuation.hpp (source / functions) Coverage Total Hit Missed
Test: coverage_remapped.info Lines: 85.1 % 47 40 7
Test Date: 2026-05-01 02:54:45 Functions: 62.5 % 96 60 36

           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_CONTINUATION_HPP
      11                 : #define BOOST_CAPY_ASIO_CONTINUATION_HPP
      12                 : 
      13                 : #include <boost/capy/continuation.hpp>
      14                 : #include <boost/capy/concept/executor.hpp>
      15                 : 
      16                 : #include <memory>
      17                 : 
      18                 : namespace boost::capy
      19                 : {
      20                 : 
      21                 : namespace detail
      22                 : {
      23                 : 
      24                 : template<typename Allocator>
      25                 : struct continuation_handle_promise_base_
      26                 : {
      27                 :   using alloc_t = std::allocator_traits<Allocator>
      28                 :                       ::template rebind_alloc<char>;
      29                 :                       
      30                 :   template<typename Func>
      31 HIT           5 :   void * operator new(std::size_t n, Func &, Allocator &allocator_)
      32                 :   {
      33               5 :     alloc_t alloc(allocator_);
      34               5 :     std::size_t m = n;
      35               5 :     if (n % alignof(alloc_t) > 0)
      36 MIS           0 :       m += alignof(alloc_t) - (n % alignof(alloc_t));
      37                 : 
      38 HIT           5 :     char * mem = alloc.allocate(m + sizeof(alloc));
      39                 : 
      40               5 :     new (mem + m) alloc_t(std::move(alloc));
      41               5 :     return mem;
      42                 :   }
      43                 : 
      44               5 :   void operator delete(void * p, std::size_t n)
      45                 :   {
      46               5 :     std::size_t m = n;
      47               5 :     if (n % alignof(alloc_t) > 0)
      48 MIS           0 :       m += alignof(alloc_t) - (n % alignof(alloc_t));
      49                 : 
      50 HIT           5 :     auto * a = reinterpret_cast<alloc_t*>(static_cast<char*>(p) + m);
      51                 : 
      52               5 :     alloc_t alloc(std::move(*a));
      53               5 :     a->~alloc_t();
      54                 : 
      55               5 :     alloc.deallocate(static_cast<char*>(p), n);
      56               5 :   }
      57                 : };
      58                 : 
      59                 : 
      60                 : template<>
      61                 : struct continuation_handle_promise_base_<std::allocator<void>>
      62                 : {
      63                 : };
      64                 : 
      65                 : template<typename Allocator>
      66                 : struct continuation_handle_promise_type 
      67                 :     : continuation_handle_promise_base_<Allocator>
      68                 : {
      69                 : 
      70                 :   struct initial_aw_t
      71                 :   {
      72              11 :     bool await_ready() const {return false;}
      73              11 :     void await_suspend(
      74                 :       std::coroutine_handle<continuation_handle_promise_type<Allocator>> h)
      75                 :     {
      76              11 :       auto & c = h.promise().cont;
      77              11 :       c.h = h;
      78              11 :       c.next = nullptr;
      79              11 :     }
      80              11 :     void await_resume() {}
      81                 :   };
      82                 : 
      83              11 :   initial_aw_t initial_suspend() const noexcept  
      84                 :   {
      85              11 :     return initial_aw_t{};
      86                 :   }
      87 MIS           0 :   std::suspend_never    final_suspend() const noexcept  {return {};}
      88                 : 
      89                 :   template<typename Function>
      90 HIT          11 :   auto yield_value(Function & func)
      91                 :   {
      92                 :     struct yielder
      93                 :     {
      94                 :       Function func;
      95                 : 
      96              11 :       bool await_ready() const {return false;}
      97              11 :       void await_suspend(std::coroutine_handle<> h)
      98                 :       {
      99              11 :         auto f = std::move(func);
     100              11 :         h.destroy();
     101                 : 
     102                 : #if defined(__GNUC__) && !defined(__clang__) && (__GNUC__ <= 14)
     103                 : #pragma GCC diagnostic push
     104                 : #pragma GCC diagnostic ignored "-Warray-bounds"
     105                 : #endif
     106                 :         
     107              11 :         std::move(f)();
     108                 : 
     109                 : #if defined(__GNUC__) && !defined(__clang__) && (__GNUC__ <= 14)
     110                 : #pragma GCC diagnostic pop
     111                 : #endif
     112                 : 
     113              11 :       }
     114 MIS           0 :       void await_resume() {}
     115                 :     };
     116                 : 
     117 HIT          11 :     return yielder{std::move(func)};
     118                 :   }
     119                 : 
     120 MIS           0 :   void unhandled_exception() { throw; }
     121               0 :   void return_void() {}
     122                 :   
     123                 :   continuation cont;
     124                 : 
     125                 :   struct helper 
     126                 :   {
     127                 :     continuation * cont;
     128                 :     using promise_type = continuation_handle_promise_type;
     129                 :   };
     130                 :   
     131 HIT          11 :   helper get_return_object() 
     132                 :   {
     133              11 :     return helper{&cont};
     134                 :   }
     135                 : };
     136                 : 
     137                 : #if defined(__GNUC__) && !defined(__clang__)
     138                 : #pragma GCC diagnostic push
     139                 : #pragma GCC diagnostic ignored "-Wmismatched-new-delete"
     140                 : #endif
     141                 : 
     142                 : template<std::invocable<> Function, typename Allocator>
     143              11 : auto make_continuation_helper(
     144                 :     Function func, 
     145                 :     Allocator)
     146                 :     -> continuation_handle_promise_type<Allocator>::helper
     147                 : {
     148                 :   co_yield func;
     149              22 : }
     150                 : 
     151                 : #if defined(__GNUC__) && !defined(__clang__)
     152                 : #pragma GCC diagnostic pop
     153                 : #endif
     154                 : 
     155                 : template<std::invocable<> Function, typename Allocator>
     156              11 : continuation & make_continuation(
     157                 :     Function && func, 
     158                 :     Allocator && alloc)
     159                 : {
     160              11 :   continuation * c = detail::make_continuation_helper(
     161 MIS           0 :           std::forward<Function>(func), 
     162 HIT          11 :           std::forward<Allocator>(alloc)).cont;
     163              11 :   return *c;
     164                 : }
     165                 : 
     166                 : }
     167                 : 
     168                 : 
     169                 : }
     170                 : 
     171                 : #endif 
     172                 : 
        

Generated by: LCOV version 2.3