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