0.00% Lines (0/0) 0.00% Functions (0/0)
TLA Baseline Branch
Line Hits Code Line Hits Code
1 - //  
2 - // Copyright (c) 2026 Steve Gerbino  
3 - // Copyright (c) 2026 Michael Vandeberg  
4 - //  
5 - // Distributed under the Boost Software License, Version 1.0. (See accompanying  
6 - // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)  
7 - //  
8 - // Official repository: https://github.com/cppalliance/capy  
9 - //  
10 -  
11 - #ifndef BOOST_CAPY_BUFFERS_CONSUMING_BUFFERS_HPP  
12 - #define BOOST_CAPY_BUFFERS_CONSUMING_BUFFERS_HPP  
13 -  
14 - #include <boost/capy/detail/config.hpp>  
15 - #include <boost/capy/buffers.hpp>  
16 - #include <boost/capy/detail/slice_of.hpp>  
17 -  
18 - #include <cstddef>  
19 - #include <utility>  
20 -  
21 - namespace boost {  
22 - namespace capy {  
23 -  
24 - /** A cursor that drives consumption of a buffer sequence.  
25 -  
26 - `consuming_buffers` is the dedicated driver for `read_some`/`write_some`  
27 - loops. It presents the not-yet-consumed bytes of a buffer sequence via  
28 - `data()`, and `consume(n)` advances past `n` transferred bytes **in  
29 - place**.  
30 -  
31 - It is deliberately **not** itself a buffer sequence — it hands out the  
32 - remaining bytes through `data()` (returning a `slice_of` view). It  
33 - **borrows** the underlying sequence (iterators + a consumed-byte offset).  
34 - The sequence must outlive the cursor. That is the natural case when the  
35 - cursor is a local of a composed operation that took its buffers by value.  
36 -  
37 - @par Example  
38 - @par !example example  
39 -  
40 -  
41 - @see @ref buffer_slice  
42 - */  
43 - template<class Seq>  
44 - requires ConstBufferSequence<Seq>  
45 - class consuming_buffers  
46 - {  
47 - public:  
48 - /// Names the buffer type the underlying sequence `Seq` yields.  
49 - using buffer_type = capy::buffer_type<Seq>;  
50 -  
51 - private:  
52 - using iterator_type =  
53 - decltype(capy::begin(std::declval<Seq const&>()));  
54 -  
55 - iterator_type first_{};  
56 - iterator_type last_{};  
57 - std::size_t front_skip_ = 0; // bytes consumed from *first_  
58 -  
59 - public:  
60 - /** Construct a cursor over `s`.  
61 -  
62 - @param s The sequence to consume. Must outlive the cursor.  
63 - */  
DCB 64 - 307 explicit consuming_buffers(Seq const& s) noexcept  
DCB 65 - 307 : first_(capy::begin(s))  
DCB 66 - 307 , last_(capy::end(s))  
67 - {  
DCB 68 - 307 }  
69 -  
70 - /** Reject construction from a temporary (the view would dangle).  
71 -  
72 - @param s The sequence that would be consumed.  
73 - */  
74 - consuming_buffers(Seq const&& s) = delete;  
75 -  
76 - /** Return the remaining (unconsumed) bytes as a buffer sequence.  
77 -  
78 - @return The bytes not yet consumed, as a buffer sequence.  
79 - */  
80 - detail::slice_of<Seq>  
DCB 81 - 357 data() const noexcept  
82 - {  
DCB 83 - 357 return detail::slice_of<Seq>(first_, last_, front_skip_, 0);  
84 - }  
85 -  
86 - /** Discard `n` bytes from the front, in place.  
87 -  
88 - Advances past `min(n, remaining)` bytes.  
89 -  
90 - @param n The number of bytes consumed.  
91 - */  
92 - void  
DCB 93 - 265 consume(std::size_t n) noexcept  
94 - {  
DCB 95 - 395 while (n > 0 && first_ != last_)  
96 - {  
DCB 97 - 204 std::size_t const sz = buffer_type(*first_).size();  
DCB 98 - 204 std::size_t const avail = sz - front_skip_;  
DCB 99 - 204 if (n < avail)  
100 - {  
DCB 101 - 74 front_skip_ += n;  
DCB 102 - 74 return;  
103 - }  
DCB 104 - 130 n -= avail;  
DCB 105 - 130 ++first_;  
DCB 106 - 130 front_skip_ = 0;  
107 - }  
108 - }  
109 - };  
110 -  
111 - /** Deduce the sequence type from the constructor argument.  
112 -  
113 - @tparam Seq The buffer sequence type.  
114 - */  
115 - template<class Seq>  
116 - consuming_buffers(Seq const&) -> consuming_buffers<Seq>;  
117 -  
118 - } // namespace capy  
119 - } // namespace boost  
120 -  
121 - #endif