LCOV - code coverage report
Current view: top level - boost/buffers - dynamic_buffer.hpp (source / functions) Coverage Total Hit
Test: coverage_filtered.info Lines: 81.6 % 38 31
Test Date: 2025-12-06 02:12:43 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/buffers
       8              : //
       9              : 
      10              : #ifndef BOOST_BUFFERS_DYNAMIC_BUFFER_HPP
      11              : #define BOOST_BUFFERS_DYNAMIC_BUFFER_HPP
      12              : 
      13              : #include <boost/buffers/detail/config.hpp>
      14              : #include <boost/buffers/buffer.hpp>
      15              : #include <boost/core/span.hpp>
      16              : #include <cstdlib>
      17              : 
      18              : namespace boost {
      19              : namespace buffers {
      20              : 
      21              : /** Determine if T is a DynamicBuffer
      22              : */
      23              : template<
      24              :     class T,
      25              :     class = void>
      26              : struct is_dynamic_buffer : std::false_type {};
      27              : 
      28              : template<class T>
      29              : struct is_dynamic_buffer<
      30              :     T, detail::void_t<decltype(
      31              :         std::declval<std::size_t&>() = std::declval<T const&>().size(),
      32              :         std::declval<std::size_t&>() = std::declval<T const&>().max_size(),
      33              :         std::declval<std::size_t&>() = std::declval<T const&>().capacity(),
      34              :         std::declval<T&>().commit(std::declval<std::size_t>()),
      35              :         std::declval<T&>().consume(std::declval<std::size_t>())
      36              :     )
      37              :     ,typename std::enable_if<
      38              :         is_const_buffer_sequence<typename T::const_buffers_type>::value &&
      39              :         is_mutable_buffer_sequence<typename T::mutable_buffers_type>::value
      40              :         >::type
      41              :     ,typename std::enable_if<
      42              :         std::is_same<decltype(
      43              :             std::declval<T const&>().data()),
      44              :             typename T::const_buffers_type>::value
      45              :         && std::is_same<decltype(
      46              :             std::declval<T&>().prepare(
      47              :                 std::declval<std::size_t>())),
      48              :             typename T::mutable_buffers_type>::value
      49              :         >::type
      50              :     > > : std::true_type
      51              : {
      52              : };
      53              : 
      54              : /** An abstract, type-erased dynamic buffer.
      55              : */
      56              : struct BOOST_SYMBOL_VISIBLE
      57              :     any_dynamic_buffer
      58              : {
      59              :     using const_buffers_type = span<const_buffer const>;
      60              :     using mutable_buffers_type = span<mutable_buffer const>;
      61              : 
      62         4096 :     virtual ~any_dynamic_buffer() = default;
      63              :     virtual std::size_t size() const = 0;
      64              :     virtual std::size_t max_size() const = 0;
      65              :     virtual std::size_t capacity() const = 0;
      66              :     virtual const_buffers_type data() const = 0;
      67              :     virtual mutable_buffers_type prepare(std::size_t) = 0;
      68              :     virtual void commit(std::size_t) = 0;
      69              :     virtual void consume(std::size_t) = 0;
      70              : };
      71              : 
      72              : //-----------------------------------------------
      73              : 
      74              : /** A type-erased dynamic buffer.
      75              : */
      76              : template<
      77              :     class DynamicBuffer,
      78              :     std::size_t N = 8>
      79              : class any_dynamic_buffer_impl
      80              :     : public any_dynamic_buffer
      81              : {
      82              :     DynamicBuffer b_;
      83              :     const_buffer data_[N];
      84              :     mutable_buffer out_[N];
      85              :     std::size_t data_len_ = 0;
      86              :     std::size_t out_len_ = 0;
      87              : 
      88              :     template<class ConstBufferSequence, class BufferType>
      89              :     static
      90              :     std::size_t
      91        34880 :     unroll(
      92              :         ConstBufferSequence const& bs,
      93              :         BufferType* dest,
      94              :         std::size_t len)
      95              :     {
      96        34880 :         std::size_t i = 0;
      97        34880 :         auto const end_ = end(bs);
      98       104640 :         for(auto it = begin(bs); it != end_; ++it)
      99              :         {
     100        69760 :             dest[i++] = *it;
     101        69760 :             if(i == len)
     102            0 :                 break;
     103              :         }
     104        34880 :         return i;
     105              :     }
     106              : 
     107              : public:
     108              :     template<class DynamicBuffer_>
     109              :     explicit
     110         4096 :     any_dynamic_buffer_impl(
     111              :         DynamicBuffer_&& b)
     112         4096 :         : b_(std::forward<DynamicBuffer_>(b))
     113              :     {
     114         4096 :     }
     115              : 
     116              :     DynamicBuffer&
     117              :     buffer() noexcept
     118              :     {
     119              :         return b_;
     120              :     }
     121              : 
     122              :     DynamicBuffer const&
     123              :     buffer() const noexcept
     124              :     {
     125              :         return b_;
     126              :     }
     127              : 
     128              :     std::size_t
     129            0 :     size() const override
     130              :     {
     131            0 :         return b_.size();
     132              :     }
     133              : 
     134              :     std::size_t
     135            0 :     max_size() const override
     136              :     {
     137            0 :         return b_.max_size();
     138              :     }
     139              : 
     140              :     std::size_t
     141            0 :     capacity() const override
     142              :     {
     143            0 :         return b_.capacity();
     144              :     }
     145              : 
     146              :     const_buffers_type
     147        12288 :     data() const override
     148              :     {
     149        24576 :         return const_buffers_type(
     150        12288 :             data_, data_len_);
     151              :     }
     152              : 
     153              :     auto
     154        11792 :     prepare(
     155              :         std::size_t n) ->
     156              :             mutable_buffers_type override
     157              :     {
     158        11792 :         out_len_ = unroll(
     159        11792 :             b_.prepare(n), out_, N);
     160        23584 :         return mutable_buffers_type(
     161        11792 :             out_, out_len_);
     162              :     }
     163              : 
     164              :     void
     165        11792 :     commit(
     166              :         std::size_t n) override
     167              :     {
     168        11792 :         b_.commit(n);
     169        11792 :         data_len_ = unroll(
     170        11792 :             b_.data(), data_, N);
     171        11792 :     }
     172              : 
     173              :     void
     174        11296 :     consume(
     175              :         std::size_t n) override
     176              :     {
     177        11296 :         b_.consume(n);
     178        11296 :         data_len_ = unroll(
     179        11296 :             b_.data(), data_, N);
     180        11296 :     }
     181              : };
     182              : 
     183              : template<
     184              :     class DynamicBuffer
     185              :     , class = typename std::enable_if<
     186              :         is_dynamic_buffer<
     187              :         typename std::decay<DynamicBuffer>::type
     188              :             >::value>::type
     189              : >
     190              : auto
     191         4096 : make_any(DynamicBuffer&& b) ->
     192              :     any_dynamic_buffer_impl<typename
     193              :         std::decay<DynamicBuffer>::type>
     194              : {
     195              :     return any_dynamic_buffer_impl<typename
     196              :         std::decay<DynamicBuffer>::type>(
     197         4096 :             std::forward<DynamicBuffer>(b));
     198              : }
     199              : 
     200              : } // buffers
     201              : } // boost
     202              : 
     203              : #endif
        

Generated by: LCOV version 2.1