LCOV - code coverage report
Current view: top level - boost/capy - any_bufref.hpp (source / functions) Coverage Total Hit
Test: coverage_filtered.info Lines: 100.0 % 21 21
Test Date: 2026-01-20 15:01:59 Functions: 100.0 % 17 17

            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_ANY_BUFREF_HPP
      11              : #define BOOST_CAPY_ANY_BUFREF_HPP
      12              : 
      13              : #include <boost/capy/detail/config.hpp>
      14              : #include <boost/capy/buffers.hpp>
      15              : 
      16              : #include <cstddef>
      17              : 
      18              : namespace boost {
      19              : namespace capy {
      20              : 
      21              : /** A type-erased buffer sequence I/O parameter.
      22              : 
      23              :     This class provides a type-erased interface for iterating
      24              :     over buffer sequences without knowing the concrete type.
      25              :     It allows asynchronous operations to efficiently type-erase
      26              :     the buffer sequence parameter, avoiding the need to
      27              :     templatize the implementation.
      28              : 
      29              :     @par Example
      30              :     The following shows the minimal form of an awaitable, templated on the
      31              :     buffer sequence type, with only an `await_suspend` method. The example
      32              :     demonstrates that you can construct an `any_bufref` in the parameter
      33              :     list when calling a virtual interface; there is no need to create a
      34              :     separate variable if not desired.
      35              : 
      36              :     @code
      37              :     template<class Buffers>
      38              :     struct awaitable
      39              :     {
      40              :         Buffers b;
      41              : 
      42              :         void await_suspend( std::coroutine_handle<> )
      43              :         {
      44              :             my_virtual_engine_submit( any_bufref( b ) );
      45              :         }
      46              :     };
      47              : 
      48              :     // Example virtual interface accepting any_bufref
      49              :     void my_virtual_engine_submit( any_bufref p )
      50              :     {
      51              :         capy::mutable_buffer temp[8];
      52              :         std::size_t n = p.copy_to( temp, 8 );
      53              :         // ... handle the buffers ...
      54              :     }
      55              :     @endcode
      56              : */
      57              : class any_bufref
      58              : {
      59              : public:
      60              :     /** Construct from a const buffer sequence.
      61              : 
      62              :         @param bs The buffer sequence to adapt.
      63              :     */
      64              :     template<ConstBufferSequence BS>
      65              :     explicit
      66           18 :     any_bufref(BS const& bs) noexcept
      67           18 :         : bs_(&bs)
      68           18 :         , fn_(&copy_impl<BS>)
      69              :     {
      70           18 :     }
      71              : 
      72              :     /** Fill an array with buffers from the sequence.
      73              : 
      74              :         Copies buffer descriptors from the sequence into the
      75              :         destination array. If the total number of bytes across
      76              :         all copied buffers is zero, returns 0 regardless of
      77              :         how many buffer descriptors were copied.
      78              : 
      79              :         @param dest Pointer to array of mutable buffer descriptors.
      80              :         @param n Maximum number of buffers to copy.
      81              : 
      82              :         @return The number of buffers actually copied, or 0 if
      83              :             the total byte count is zero.
      84              :     */
      85              :     std::size_t
      86           18 :     copy_to(
      87              :         mutable_buffer* dest,
      88              :         std::size_t n) const noexcept
      89              :     {
      90           18 :         return fn_(bs_, dest, n);
      91              :     }
      92              : 
      93              : private:
      94              :     template<ConstBufferSequence BS>
      95              :     static std::size_t
      96           18 :     copy_impl(
      97              :         void const* p,
      98              :         mutable_buffer* dest,
      99              :         std::size_t n)
     100              :     {
     101           18 :         auto const& bs = *static_cast<BS const*>(p);
     102           18 :         auto it = begin(bs);
     103           18 :         auto const end_it = end(bs);
     104              : 
     105           18 :         std::size_t i = 0;
     106           18 :         std::size_t bytes = 0;
     107              :         if constexpr (MutableBufferSequence<BS>)
     108              :         {
     109           10 :             for(; it != end_it && i < n; ++it, ++i)
     110              :             {
     111            6 :                 dest[i] = *it;
     112            6 :                 bytes += dest[i].size();
     113              :             }
     114              :         }
     115              :         else
     116              :         {
     117           40 :             for(; it != end_it && i < n; ++it, ++i)
     118              :             {
     119           26 :                 auto const& buf = *it;
     120           52 :                 dest[i] = mutable_buffer(
     121              :                     const_cast<char*>(
     122           26 :                         static_cast<char const*>(buf.data())),
     123              :                     buf.size());
     124           26 :                 bytes += buf.size();
     125              :             }
     126              :         }
     127              :         // Return 0 if total bytes is 0 (empty buffer sequence)
     128           18 :         return bytes == 0 ? 0 : i;
     129              :     }
     130              : 
     131              :     using fn_t = std::size_t(*)(void const*,
     132              :         mutable_buffer*, std::size_t);
     133              : 
     134              :     void const* bs_;
     135              :     fn_t fn_;
     136              : };
     137              : 
     138              : } // namespace capy
     139              : } // namespace boost
     140              : 
     141              : #endif
        

Generated by: LCOV version 2.3