0.00% Lines (0/0)
0.00% Functions (0/0)
| TLA | Baseline | Branch | ||||||
|---|---|---|---|---|---|---|---|---|
| Line | Hits | Code | Line | Hits | 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 | - | */ | ||||||
| DCB | 73 | - | 215 | explicit consuming_buffers(BufferSequence const& bufs) noexcept | ||||
| DCB | 74 | - | 215 | : bufs_(bufs) | ||||
| DCB | 75 | - | 215 | , it_(capy::begin(bufs)) | ||||
| DCB | 76 | - | 215 | , end_(capy::end(bufs)) | ||||
| 77 | - | { | ||||||
| DCB | 78 | - | 215 | } | ||||
| 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 | - | */ | ||||||
| DCB | 87 | - | 170 | void consume(std::size_t n) noexcept | ||||
| 88 | - | { | ||||||
| DCB | 89 | - | 290 | while (n > 0 && it_ != end_) | ||||
| 90 | - | { | ||||||
| DCB | 91 | - | 120 | auto const& buf = *it_; | ||||
| DCB | 92 | - | 120 | std::size_t const buf_size = buf.size(); | ||||
| DCB | 93 | - | 120 | std::size_t const remaining = buf_size - consumed_; | ||||
| 94 | - | |||||||
| DCB | 95 | - | 120 | if (n < remaining) | ||||
| 96 | - | { | ||||||
| 97 | - | // Consume part of current buffer | ||||||
| DCB | 98 | - | 30 | consumed_ += n; | ||||
| DCB | 99 | - | 30 | n = 0; | ||||
| 100 | - | } | ||||||
| 101 | - | else | ||||||
| 102 | - | { | ||||||
| 103 | - | // Consume rest of current buffer and move to next | ||||||
| DCB | 104 | - | 90 | n -= remaining; | ||||
| DCB | 105 | - | 90 | consumed_ = 0; | ||||
| DCB | 106 | - | 90 | ++it_; | ||||
| 107 | - | } | ||||||
| 108 | - | } | ||||||
| DCB | 109 | - | 170 | } | ||||
| 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 | - | /// Construct from position and consumed byte count. | ||||||
| DCB | 133 | - | 862 | const_iterator( | ||||
| 134 | - | iterator_type it, | ||||||
| 135 | - | end_iterator_type end, | ||||||
| 136 | - | std::size_t consumed) noexcept | ||||||
| DCB | 137 | - | 862 | : it_(it) | ||||
| DCB | 138 | - | 862 | , end_(end) | ||||
| DCB | 139 | - | 862 | , consumed_(consumed) | ||||
| 140 | - | { | ||||||
| DCB | 141 | - | 862 | } | ||||
| 142 | - | |||||||
| 143 | - | /// Test for equality. | ||||||
| DCB | 144 | - | 544 | bool operator==(const_iterator const& other) const noexcept | ||||
| 145 | - | { | ||||||
| DCB | 146 | - | 544 | return it_ == other.it_ && consumed_ == other.consumed_; | ||||
| 147 | - | } | ||||||
| 148 | - | |||||||
| 149 | - | /// Test for inequality. | ||||||
| DCB | 150 | - | 544 | bool operator!=(const_iterator const& other) const noexcept | ||||
| 151 | - | { | ||||||
| DCB | 152 | - | 544 | return !(*this == other); | ||||
| 153 | - | } | ||||||
| 154 | - | |||||||
| 155 | - | /// Return the current buffer, adjusted for consumed bytes. | ||||||
| DCB | 156 | - | 481 | value_type operator*() const noexcept | ||||
| 157 | - | { | ||||||
| DCB | 158 | - | 481 | auto const& buf = *it_; | ||||
| 159 | - | if constexpr (std::is_same_v<buffer_type, mutable_buffer>) | ||||||
| 160 | - | { | ||||||
| DCB | 161 | - | 609 | return buffer_type( | ||||
| DCB | 162 | - | 203 | static_cast<char*>(buf.data()) + consumed_, | ||||
| DCB | 163 | - | 406 | buf.size() - consumed_); | ||||
| 164 | - | } | ||||||
| 165 | - | else | ||||||
| 166 | - | { | ||||||
| DCB | 167 | - | 834 | return buffer_type( | ||||
| DCB | 168 | - | 278 | static_cast<char const*>(buf.data()) + consumed_, | ||||
| DCB | 169 | - | 556 | buf.size() - consumed_); | ||||
| 170 | - | } | ||||||
| 171 | - | } | ||||||
| 172 | - | |||||||
| 173 | - | /// Advance to the next element. | ||||||
| DCB | 174 | - | 451 | const_iterator& operator++() noexcept | ||||
| 175 | - | { | ||||||
| DCB | 176 | - | 451 | consumed_ = 0; | ||||
| DCB | 177 | - | 451 | ++it_; | ||||
| DCB | 178 | - | 451 | return *this; | ||||
| 179 | - | } | ||||||
| 180 | - | |||||||
| 181 | - | /// Advance to the next element (postfix). | ||||||
| DCB | 182 | - | 286 | const_iterator operator++(int) noexcept | ||||
| 183 | - | { | ||||||
| DCB | 184 | - | 286 | const_iterator tmp = *this; | ||||
| DCB | 185 | - | 286 | ++*this; | ||||
| DCB | 186 | - | 286 | return tmp; | ||||
| 187 | - | } | ||||||
| 188 | - | |||||||
| 189 | - | /// Move to the previous element. | ||||||
| 190 | - | const_iterator& operator--() noexcept | ||||||
| 191 | - | { | ||||||
| 192 | - | if (consumed_ == 0) | ||||||
| 193 | - | { | ||||||
| 194 | - | --it_; | ||||||
| 195 | - | // Set consumed_ to the size of the previous buffer | ||||||
| 196 | - | // This is a simplified implementation for bidirectional requirement | ||||||
| 197 | - | if (it_ != end_) | ||||||
| 198 | - | { | ||||||
| 199 | - | auto const& buf = *it_; | ||||||
| 200 | - | consumed_ = buf.size(); | ||||||
| 201 | - | } | ||||||
| 202 | - | } | ||||||
| 203 | - | else | ||||||
| 204 | - | { | ||||||
| 205 | - | consumed_ = 0; | ||||||
| 206 | - | } | ||||||
| 207 | - | return *this; | ||||||
| 208 | - | } | ||||||
| 209 | - | |||||||
| 210 | - | /// Move to the previous element (postfix). | ||||||
| 211 | - | const_iterator operator--(int) noexcept | ||||||
| 212 | - | { | ||||||
| 213 | - | const_iterator tmp = *this; | ||||||
| 214 | - | --*this; | ||||||
| 215 | - | return tmp; | ||||||
| 216 | - | } | ||||||
| 217 | - | }; | ||||||
| 218 | - | |||||||
| 219 | - | /** Return iterator to beginning of remaining buffers. | ||||||
| 220 | - | |||||||
| 221 | - | @return Iterator pointing to the first remaining buffer, | ||||||
| 222 | - | adjusted for consumed bytes in the current buffer. | ||||||
| 223 | - | */ | ||||||
| DCB | 224 | - | 431 | const_iterator begin() const noexcept | ||||
| 225 | - | { | ||||||
| DCB | 226 | - | 431 | return const_iterator(it_, end_, consumed_); | ||||
| 227 | - | } | ||||||
| 228 | - | |||||||
| 229 | - | /** Return iterator to end of buffer sequence. | ||||||
| 230 | - | |||||||
| 231 | - | @return End iterator. | ||||||
| 232 | - | */ | ||||||
| DCB | 233 | - | 431 | const_iterator end() const noexcept | ||||
| 234 | - | { | ||||||
| DCB | 235 | - | 431 | return const_iterator(end_, end_, 0); | ||||
| 236 | - | } | ||||||
| 237 | - | }; | ||||||
| 238 | - | |||||||
| 239 | - | } // namespace capy | ||||||
| 240 | - | } // namespace boost | ||||||
| 241 | - | |||||||
| 242 | - | #endif | ||||||