LCOV - code coverage report
Current view: top level - boost/capy/buffers - consuming_buffers.hpp (source / functions) Coverage Total Hit
Test: coverage_filtered.info Lines: 100.0 % 42 42
Test Date: 2026-01-24 00:02:10 Functions: 100.0 % 28 28

            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_CONSUMING_BUFFERS_HPP
      11              : #define BOOST_CAPY_BUFFERS_CONSUMING_BUFFERS_HPP
      12              : 
      13              : #include <boost/capy/detail/config.hpp>
      14              : #include <boost/capy/buffers.hpp>
      15              : 
      16              : #include <cstddef>
      17              : #include <iterator>
      18              : #include <ranges>
      19              : #include <type_traits>
      20              : 
      21              : namespace boost {
      22              : namespace capy {
      23              : 
      24              : namespace detail {
      25              : 
      26              : template<class T>
      27              : struct buffer_type_for;
      28              : 
      29              : template<MutableBufferSequence T>
      30              : struct buffer_type_for<T>
      31              : {
      32              :     using type = mutable_buffer;
      33              : };
      34              : 
      35              : template<ConstBufferSequence T>
      36              :     requires (!MutableBufferSequence<T>)
      37              : struct buffer_type_for<T>
      38              : {
      39              :     using type = const_buffer;
      40              : };
      41              : 
      42              : } // namespace detail
      43              : 
      44              : /** Wrapper for consuming a buffer sequence incrementally.
      45              : 
      46              :     This class wraps a buffer sequence and tracks the current
      47              :     position. It provides a `consume(n)` function that advances
      48              :     through the sequence as bytes are processed.
      49              : 
      50              :     Works with both mutable and const buffer sequences.
      51              : 
      52              :     @tparam BufferSequence The buffer sequence type.
      53              : */
      54              : template<class BufferSequence>
      55              :     requires MutableBufferSequence<BufferSequence> ||
      56              :              ConstBufferSequence<BufferSequence>
      57              : class consuming_buffers
      58              : {
      59              :     using iterator_type = decltype(capy::begin(std::declval<BufferSequence const&>()));
      60              :     using end_iterator_type = decltype(capy::end(std::declval<BufferSequence const&>()));
      61              :     using buffer_type = typename detail::buffer_type_for<BufferSequence>::type;
      62              : 
      63              :     BufferSequence const& bufs_;
      64              :     iterator_type it_;
      65              :     end_iterator_type end_;
      66              :     std::size_t consumed_ = 0;  // Bytes consumed in current buffer
      67              : 
      68              : public:
      69              :     /** Construct from a buffer sequence.
      70              : 
      71              :         @param bufs The buffer sequence to wrap.
      72              :     */
      73           19 :     explicit consuming_buffers(BufferSequence const& bufs) noexcept
      74           19 :         : bufs_(bufs)
      75           19 :         , it_(capy::begin(bufs))
      76           19 :         , end_(capy::end(bufs))
      77              :     {
      78           19 :     }
      79              : 
      80              :     /** Consume n bytes from the buffer sequence.
      81              : 
      82              :         Advances the current position by n bytes, moving to the
      83              :         next buffer when the current one is exhausted.
      84              : 
      85              :         @param n The number of bytes to consume.
      86              :     */
      87           29 :     void consume(std::size_t n) noexcept
      88              :     {
      89           58 :         while (n > 0 && it_ != end_)
      90              :         {
      91           29 :             auto const& buf = *it_;
      92           29 :             std::size_t const buf_size = buf.size();
      93           29 :             std::size_t const remaining = buf_size - consumed_;
      94              : 
      95           29 :             if (n < remaining)
      96              :             {
      97              :                 // Consume part of current buffer
      98           18 :                 consumed_ += n;
      99           18 :                 n = 0;
     100              :             }
     101              :             else
     102              :             {
     103              :                 // Consume rest of current buffer and move to next
     104           11 :                 n -= remaining;
     105           11 :                 consumed_ = 0;
     106           11 :                 ++it_;
     107              :             }
     108              :         }
     109           29 :     }
     110              : 
     111              :     /** Iterator for the consuming buffer sequence.
     112              : 
     113              :         Returns buffers starting from the current position,
     114              :         with the first buffer adjusted for consumed bytes.
     115              :     */
     116              :     class const_iterator
     117              :     {
     118              :         iterator_type it_;
     119              :         end_iterator_type end_;
     120              :         std::size_t consumed_;
     121              : 
     122              :     public:
     123              :         using iterator_category = std::bidirectional_iterator_tag;
     124              :         using value_type = buffer_type;
     125              :         using difference_type = std::ptrdiff_t;
     126              :         using pointer = value_type*;
     127              :         using reference = value_type;
     128              : 
     129              :         // Default constructor required for forward_iterator
     130              :         const_iterator() noexcept = default;
     131              : 
     132           40 :         const_iterator(
     133              :             iterator_type it,
     134              :             end_iterator_type end,
     135              :             std::size_t consumed) noexcept
     136           40 :             : it_(it)
     137           40 :             , end_(end)
     138           40 :             , consumed_(consumed)
     139              :         {
     140           40 :         }
     141              : 
     142            6 :         bool operator==(const_iterator const& other) const noexcept
     143              :         {
     144            6 :             return it_ == other.it_ && consumed_ == other.consumed_;
     145              :         }
     146              : 
     147              :         // != operator required for equality_comparable
     148            6 :         bool operator!=(const_iterator const& other) const noexcept
     149              :         {
     150            6 :             return !(*this == other);
     151              :         }
     152              : 
     153           37 :         value_type operator*() const noexcept
     154              :         {
     155           37 :             auto const& buf = *it_;
     156              :             if constexpr (std::is_same_v<buffer_type, mutable_buffer>)
     157              :             {
     158           48 :                 return buffer_type(
     159           16 :                     static_cast<char*>(buf.data()) + consumed_,
     160           32 :                     buf.size() - consumed_);
     161              :             }
     162              :             else
     163              :             {
     164           63 :                 return buffer_type(
     165           21 :                     static_cast<char const*>(buf.data()) + consumed_,
     166           42 :                     buf.size() - consumed_);
     167              :             }
     168              :         }
     169              : 
     170            3 :         const_iterator& operator++() noexcept
     171              :         {
     172            3 :             consumed_ = 0;
     173            3 :             ++it_;
     174            3 :             return *this;
     175              :         }
     176              : 
     177              :         const_iterator operator++(int) noexcept
     178              :         {
     179              :             const_iterator tmp = *this;
     180              :             ++*this;
     181              :             return tmp;
     182              :         }
     183              : 
     184              :         const_iterator& operator--() noexcept
     185              :         {
     186              :             if (consumed_ == 0)
     187              :             {
     188              :                 --it_;
     189              :                 // Set consumed_ to the size of the previous buffer
     190              :                 // This is a simplified implementation for bidirectional requirement
     191              :                 if (it_ != end_)
     192              :                 {
     193              :                     auto const& buf = *it_;
     194              :                     consumed_ = buf.size();
     195              :                 }
     196              :             }
     197              :             else
     198              :             {
     199              :                 consumed_ = 0;
     200              :             }
     201              :             return *this;
     202              :         }
     203              : 
     204              :         const_iterator operator--(int) noexcept
     205              :         {
     206              :             const_iterator tmp = *this;
     207              :             --*this;
     208              :             return tmp;
     209              :         }
     210              :     };
     211              : 
     212              :     /** Return iterator to beginning of remaining buffers.
     213              : 
     214              :         @return Iterator pointing to the first remaining buffer,
     215              :             adjusted for consumed bytes in the current buffer.
     216              :     */
     217           37 :     const_iterator begin() const noexcept
     218              :     {
     219           37 :         return const_iterator(it_, end_, consumed_);
     220              :     }
     221              : 
     222              :     /** Return iterator to end of buffer sequence.
     223              : 
     224              :         @return End iterator.
     225              :     */
     226            3 :     const_iterator end() const noexcept
     227              :     {
     228            3 :         return const_iterator(end_, end_, 0);
     229              :     }
     230              : };
     231              : 
     232              : } // namespace capy
     233              : } // namespace boost
     234              : 
     235              : #endif
        

Generated by: LCOV version 2.3