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_DETAIL_CONSUMING_BUFFERS_HPP  
12 - #define BOOST_CAPY_DETAIL_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 - namespace detail {  
24 -  
25 - /** A cursor that drives consumption of a buffer sequence.  
26 -  
27 - `consuming_buffers` is the dedicated driver for `read_some`/`write_some`  
28 - loops. It presents the not-yet-consumed bytes of a buffer sequence via  
29 - `data()`, and `consume(n)` advances past `n` transferred bytes **in  
30 - place**.  
31 -  
32 - It is deliberately **not** itself a buffer sequence — it hands out the  
33 - remaining bytes through `data()` (returning a `slice_of` view). It  
34 - **borrows** the underlying sequence (iterators + a consumed-byte offset).  
35 - The sequence must outlive the cursor. That is the natural case when the  
36 - cursor is a local of a composed operation that took its buffers by value.  
37 - */  
38 - template<class Seq>  
39 - requires ConstBufferSequence<Seq>  
40 - class consuming_buffers  
41 - {  
42 - public:  
43 - /// Names the buffer type the underlying sequence `Seq` yields.  
44 - using buffer_type = capy::buffer_type<Seq>;  
45 -  
46 - private:  
47 - using iterator_type =  
48 - decltype(capy::buffer_sequence_begin(std::declval<Seq const&>()));  
49 -  
50 - iterator_type first_{};  
51 - iterator_type last_{};  
52 - std::size_t front_skip_ = 0; // bytes consumed from *first_  
53 -  
54 - public:  
55 - /** Construct a cursor over `s`.  
56 -  
57 - @param s The sequence to consume. Must outlive the cursor.  
58 - */  
DCB 59 - 306 explicit consuming_buffers(Seq const& s) noexcept  
DCB 60 - 306 : first_(capy::buffer_sequence_begin(s))  
DCB 61 - 306 , last_(capy::buffer_sequence_end(s))  
62 - {  
DCB 63 - 306 }  
64 -  
65 - /** Reject construction from a temporary (the view would dangle).  
66 -  
67 - @param s The sequence that would be consumed.  
68 - */  
69 - consuming_buffers(Seq const&& s) = delete;  
70 -  
71 - /** Return the remaining (unconsumed) bytes as a buffer sequence.  
72 -  
73 - @return The bytes not yet consumed, as a buffer sequence.  
74 - */  
75 - slice_of<Seq>  
DCB 76 - 354 data() const noexcept  
77 - {  
DCB 78 - 354 return slice_of<Seq>(first_, last_, front_skip_, 0);  
79 - }  
80 -  
81 - /** Discard `n` bytes from the front, in place.  
82 -  
83 - Advances past `min(n, remaining)` bytes.  
84 -  
85 - @param n The number of bytes consumed.  
86 - */  
87 - void  
DCB 88 - 262 consume(std::size_t n) noexcept  
89 - {  
DCB 90 - 387 while (n > 0 && first_ != last_)  
91 - {  
DCB 92 - 199 std::size_t const sz = buffer_type(*first_).size();  
DCB 93 - 199 std::size_t const avail = sz - front_skip_;  
DCB 94 - 199 if (n < avail)  
95 - {  
DCB 96 - 74 front_skip_ += n;  
DCB 97 - 74 return;  
98 - }  
DCB 99 - 125 n -= avail;  
DCB 100 - 125 ++first_;  
DCB 101 - 125 front_skip_ = 0;  
102 - }  
103 - }  
104 - };  
105 -  
106 - /** Deduce the sequence type from the constructor argument.  
107 -  
108 - @tparam Seq The buffer sequence type.  
109 - */  
110 - template<class Seq>  
111 - consuming_buffers(Seq const&) -> consuming_buffers<Seq>;  
112 -  
113 - } // namespace detail  
114 - } // namespace capy  
115 - } // namespace boost  
116 -  
117 - #endif