LCOV - code coverage report
Current view: top level - boost/capy/buffers - buffer_param.hpp (source / functions) Coverage Total Hit
Test: coverage_filtered.info Lines: 100.0 % 21 21
Test Date: 2026-01-21 01:18:25 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_BUFFERS_BUFFER_PARAM_HPP
      11              : #define BOOST_CAPY_BUFFERS_BUFFER_PARAM_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 Passing Convention
      30              : 
      31              :     This type is designed to be passed by value. It contains only
      32              :     two pointers (16 bytes on 64-bit systems), making copies trivial.
      33              :     Pass-by-value is preferred as it clearly communicates the
      34              :     lightweight, transient nature of this parameter type:
      35              : 
      36              :     @code
      37              :     // Preferred: pass by value
      38              :     void process_buffers( buffer_param buffers );
      39              : 
      40              :     // Also acceptable: pass by const reference
      41              :     void process_buffers( buffer_param const& buffers );
      42              :     @endcode
      43              : 
      44              :     @par Example
      45              : 
      46              :     The following shows the minimal form of an awaitable, templated on the
      47              :     buffer sequence type, with only an `await_suspend` method. The example
      48              :     demonstrates that you can pass buffers directly to a virtual interface
      49              :     through implicit conversion.
      50              : 
      51              :     @code
      52              :     template<class Buffers>
      53              :     struct awaitable
      54              :     {
      55              :         Buffers b;
      56              : 
      57              :         void await_suspend( std::coroutine_handle<> )
      58              :         {
      59              :             my_virtual_engine_submit( b );
      60              :         }
      61              :     };
      62              : 
      63              :     // Example virtual interface accepting buffer_param by value
      64              :     void my_virtual_engine_submit( buffer_param p )
      65              :     {
      66              :         capy::mutable_buffer temp[8];
      67              :         std::size_t n = p.copy_to( temp, 8 );
      68              :         // ... handle the buffers ...
      69              :     }
      70              :     @endcode
      71              : */
      72              : class buffer_param
      73              : {
      74              : public:
      75              :     /** Construct from a const buffer sequence.
      76              : 
      77              :         @param bs The buffer sequence to adapt.
      78              :     */
      79              :     template<ConstBufferSequence BS>
      80           23 :     buffer_param(BS const& bs) noexcept
      81           23 :         : bs_(&bs)
      82           23 :         , fn_(&copy_impl<BS>)
      83              :     {
      84           23 :     }
      85              : 
      86              :     /** Fill an array with buffers from the sequence.
      87              : 
      88              :         Copies buffer descriptors from the sequence into the
      89              :         destination array. If the total number of bytes across
      90              :         all copied buffers is zero, returns 0 regardless of
      91              :         how many buffer descriptors were copied.
      92              : 
      93              :         @param dest Pointer to array of mutable buffer descriptors.
      94              :         @param n Maximum number of buffers to copy.
      95              : 
      96              :         @return The number of buffers actually copied, or 0 if
      97              :             the total byte count is zero.
      98              :     */
      99              :     std::size_t
     100           23 :     copy_to(
     101              :         mutable_buffer* dest,
     102              :         std::size_t n) const noexcept
     103              :     {
     104           23 :         return fn_(bs_, dest, n);
     105              :     }
     106              : 
     107              : private:
     108              :     template<ConstBufferSequence BS>
     109              :     static std::size_t
     110           23 :     copy_impl(
     111              :         void const* p,
     112              :         mutable_buffer* dest,
     113              :         std::size_t n)
     114              :     {
     115           23 :         auto const& bs = *static_cast<BS const*>(p);
     116           23 :         auto it = begin(bs);
     117           23 :         auto const end_it = end(bs);
     118              : 
     119           23 :         std::size_t i = 0;
     120           23 :         std::size_t bytes = 0;
     121              :         if constexpr (MutableBufferSequence<BS>)
     122              :         {
     123           10 :             for(; it != end_it && i < n; ++it, ++i)
     124              :             {
     125            6 :                 dest[i] = *it;
     126            6 :                 bytes += dest[i].size();
     127              :             }
     128              :         }
     129              :         else
     130              :         {
     131           52 :             for(; it != end_it && i < n; ++it, ++i)
     132              :             {
     133           33 :                 auto const& buf = *it;
     134           66 :                 dest[i] = mutable_buffer(
     135              :                     const_cast<char*>(
     136           33 :                         static_cast<char const*>(buf.data())),
     137              :                     buf.size());
     138           33 :                 bytes += buf.size();
     139              :             }
     140              :         }
     141              :         // Return 0 if total bytes is 0 (empty buffer sequence)
     142           23 :         return bytes == 0 ? 0 : i;
     143              :     }
     144              : 
     145              :     using fn_t = std::size_t(*)(void const*,
     146              :         mutable_buffer*, std::size_t);
     147              : 
     148              :     void const* bs_;
     149              :     fn_t fn_;
     150              : };
     151              : 
     152              : } // namespace capy
     153              : } // namespace boost
     154              : 
     155              : #endif
        

Generated by: LCOV version 2.3