LCOV - code coverage report
Current view: top level - boost/capy/buffers - dynamic_buffer.hpp (source / functions) Coverage Total Hit
Test: coverage_filtered.info Lines: 81.6 % 38 31
Test Date: 2026-01-15 18:27:21 Functions: 69.2 % 13 9

            Line data    Source code
       1              : //
       2              : // Copyright (c) 2023 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_BUFFERS_DYNAMIC_BUFFER_HPP
      11              : #define BOOST_CAPY_BUFFERS_DYNAMIC_BUFFER_HPP
      12              : 
      13              : #include <boost/capy/detail/config.hpp>
      14              : #include <boost/capy/buffers.hpp>
      15              : #include <boost/capy/concept/dynamic_buffer.hpp>
      16              : #include <boost/core/span.hpp>
      17              : #include <cstdlib>
      18              : 
      19              : namespace boost {
      20              : namespace capy {
      21              : 
      22              : /** Metafunction to detect if a type is a dynamic buffer.
      23              : */
      24              : template<class T>
      25              : struct is_dynamic_buffer
      26              :     : std::bool_constant<dynamic_buffer<T>>
      27              : {
      28              : };
      29              : 
      30              : /** An abstract, type-erased dynamic buffer.
      31              : */
      32              : struct BOOST_SYMBOL_VISIBLE
      33              :     any_dynamic_buffer
      34              : {
      35              :     using const_buffers_type = span<const_buffer const>;
      36              :     using mutable_buffers_type = span<mutable_buffer const>;
      37              : 
      38         4096 :     virtual ~any_dynamic_buffer() = default;
      39              :     virtual std::size_t size() const = 0;
      40              :     virtual std::size_t max_size() const = 0;
      41              :     virtual std::size_t capacity() const = 0;
      42              :     virtual const_buffers_type data() const = 0;
      43              :     virtual mutable_buffers_type prepare(std::size_t) = 0;
      44              :     virtual void commit(std::size_t) = 0;
      45              :     virtual void consume(std::size_t) = 0;
      46              : };
      47              : 
      48              : //-----------------------------------------------
      49              : 
      50              : /** A type-erased dynamic buffer.
      51              : */
      52              : template<
      53              :     dynamic_buffer DynamicBuffer,
      54              :     std::size_t N = 8>
      55              : class any_dynamic_buffer_impl
      56              :     : public any_dynamic_buffer
      57              : {
      58              :     DynamicBuffer b_;
      59              :     const_buffer data_[N];
      60              :     mutable_buffer out_[N];
      61              :     std::size_t data_len_ = 0;
      62              :     std::size_t out_len_ = 0;
      63              : 
      64              :     template<const_buffer_sequence ConstBufferSequence, class BufferType>
      65              :     static
      66              :     std::size_t
      67        34880 :     unroll(
      68              :         ConstBufferSequence const& bs,
      69              :         BufferType* dest,
      70              :         std::size_t len)
      71              :     {
      72        34880 :         std::size_t i = 0;
      73        34880 :         auto const end_ = end(bs);
      74       104640 :         for(auto it = begin(bs); it != end_; ++it)
      75              :         {
      76        69760 :             dest[i++] = *it;
      77        69760 :             if(i == len)
      78            0 :                 break;
      79              :         }
      80        34880 :         return i;
      81              :     }
      82              : 
      83              : public:
      84              :     template<class DynamicBuffer_>
      85              :     explicit
      86         4096 :     any_dynamic_buffer_impl(
      87              :         DynamicBuffer_&& b)
      88         4096 :         : b_(std::forward<DynamicBuffer_>(b))
      89              :     {
      90         4096 :     }
      91              : 
      92              :     DynamicBuffer&
      93              :     buffer() noexcept
      94              :     {
      95              :         return b_;
      96              :     }
      97              : 
      98              :     DynamicBuffer const&
      99              :     buffer() const noexcept
     100              :     {
     101              :         return b_;
     102              :     }
     103              : 
     104              :     std::size_t
     105            0 :     size() const override
     106              :     {
     107            0 :         return b_.size();
     108              :     }
     109              : 
     110              :     std::size_t
     111            0 :     max_size() const override
     112              :     {
     113            0 :         return b_.max_size();
     114              :     }
     115              : 
     116              :     std::size_t
     117            0 :     capacity() const override
     118              :     {
     119            0 :         return b_.capacity();
     120              :     }
     121              : 
     122              :     const_buffers_type
     123        12288 :     data() const override
     124              :     {
     125        24576 :         return const_buffers_type(
     126        12288 :             data_, data_len_);
     127              :     }
     128              : 
     129              :     auto
     130        11792 :     prepare(
     131              :         std::size_t n) ->
     132              :             mutable_buffers_type override
     133              :     {
     134        11792 :         out_len_ = unroll(
     135        11792 :             b_.prepare(n), out_, N);
     136        23584 :         return mutable_buffers_type(
     137        11792 :             out_, out_len_);
     138              :     }
     139              : 
     140              :     void
     141        11792 :     commit(
     142              :         std::size_t n) override
     143              :     {
     144        11792 :         b_.commit(n);
     145        11792 :         data_len_ = unroll(
     146        11792 :             b_.data(), data_, N);
     147        11792 :     }
     148              : 
     149              :     void
     150        11296 :     consume(
     151              :         std::size_t n) override
     152              :     {
     153        11296 :         b_.consume(n);
     154        11296 :         data_len_ = unroll(
     155        11296 :             b_.data(), data_, N);
     156        11296 :     }
     157              : };
     158              : 
     159              : template<dynamic_buffer DynamicBuffer>
     160              : auto
     161         4096 : make_any(DynamicBuffer&& b) ->
     162              :     any_dynamic_buffer_impl<std::decay_t<DynamicBuffer>>
     163              : {
     164              :     return any_dynamic_buffer_impl<std::decay_t<DynamicBuffer>>(
     165         4096 :             std::forward<DynamicBuffer>(b));
     166              : }
     167              : 
     168              : } // capy
     169              : } // boost
     170              : 
     171              : #endif
        

Generated by: LCOV version 2.3