LCOV - code coverage report
Current view: top level - capy/buffers - consuming_buffers.hpp (source / functions) Coverage Total Hit
Test: coverage_remapped.info Lines: 100.0 % 46 46
Test Date: 2026-02-17 18:14:47 Functions: 100.0 % 40 40

           TLA  Line data    Source code
       1                 : //
       2                 : // Copyright (c) 2025 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_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 HIT         203 :     explicit consuming_buffers(BufferSequence const& bufs) noexcept
      74             203 :         : bufs_(bufs)
      75             203 :         , it_(capy::begin(bufs))
      76             203 :         , end_(capy::end(bufs))
      77                 :     {
      78             203 :     }
      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              94 :     void consume(std::size_t n) noexcept
      88                 :     {
      89             206 :         while (n > 0 && it_ != end_)
      90                 :         {
      91             112 :             auto const& buf = *it_;
      92             112 :             std::size_t const buf_size = buf.size();
      93             112 :             std::size_t const remaining = buf_size - consumed_;
      94                 : 
      95             112 :             if (n < remaining)
      96                 :             {
      97                 :                 // Consume part of current buffer
      98              30 :                 consumed_ += n;
      99              30 :                 n = 0;
     100                 :             }
     101                 :             else
     102                 :             {
     103                 :                 // Consume rest of current buffer and move to next
     104              82 :                 n -= remaining;
     105              82 :                 consumed_ = 0;
     106              82 :                 ++it_;
     107                 :             }
     108                 :         }
     109              94 :     }
     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             826 :         const_iterator(
     133                 :             iterator_type it,
     134                 :             end_iterator_type end,
     135                 :             std::size_t consumed) noexcept
     136             826 :             : it_(it)
     137             826 :             , end_(end)
     138             826 :             , consumed_(consumed)
     139                 :         {
     140             826 :         }
     141                 : 
     142             518 :         bool operator==(const_iterator const& other) const noexcept
     143                 :         {
     144             518 :             return it_ == other.it_ && consumed_ == other.consumed_;
     145                 :         }
     146                 : 
     147                 :         // != operator required for equality_comparable
     148             518 :         bool operator!=(const_iterator const& other) const noexcept
     149                 :         {
     150             518 :             return !(*this == other);
     151                 :         }
     152                 : 
     153             457 :         value_type operator*() const noexcept
     154                 :         {
     155             457 :             auto const& buf = *it_;
     156                 :             if constexpr (std::is_same_v<buffer_type, mutable_buffer>)
     157                 :             {
     158             579 :                 return buffer_type(
     159             193 :                     static_cast<char*>(buf.data()) + consumed_,
     160             386 :                     buf.size() - consumed_);
     161                 :             }
     162                 :             else
     163                 :             {
     164             792 :                 return buffer_type(
     165             264 :                     static_cast<char const*>(buf.data()) + consumed_,
     166             528 :                     buf.size() - consumed_);
     167                 :             }
     168                 :         }
     169                 : 
     170             427 :         const_iterator& operator++() noexcept
     171                 :         {
     172             427 :             consumed_ = 0;
     173             427 :             ++it_;
     174             427 :             return *this;
     175                 :         }
     176                 : 
     177             274 :         const_iterator operator++(int) noexcept
     178                 :         {
     179             274 :             const_iterator tmp = *this;
     180             274 :             ++*this;
     181             274 :             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             413 :     const_iterator begin() const noexcept
     218                 :     {
     219             413 :         return const_iterator(it_, end_, consumed_);
     220                 :     }
     221                 : 
     222                 :     /** Return iterator to end of buffer sequence.
     223                 : 
     224                 :         @return End iterator.
     225                 :     */
     226             413 :     const_iterator end() const noexcept
     227                 :     {
     228             413 :         return const_iterator(end_, end_, 0);
     229                 :     }
     230                 : };
     231                 : 
     232                 : } // namespace capy
     233                 : } // namespace boost
     234                 : 
     235                 : #endif
        

Generated by: LCOV version 2.3