include/boost/capy/buffers/consuming_buffers.hpp

100.0% Lines (16/0/16) 66.7% List of functions (16/0/24)
consuming_buffers.hpp
f(x) Functions (24)
Function Calls Lines Blocks
boost::capy::consuming_buffers<boost::capy::const_buffer>::consuming_buffers(boost::capy::const_buffer const&) :73 110x 100.0% 100.0% boost::capy::consuming_buffers<boost::capy::detail::slice_of<std::array<boost::capy::const_buffer, 2ul> > >::consuming_buffers(boost::capy::detail::slice_of<std::array<boost::capy::const_buffer, 2ul> > const&) :73 2x 100.0% 100.0% boost::capy::consuming_buffers<boost::capy::mutable_buffer>::consuming_buffers(boost::capy::mutable_buffer const&) :73 100x 100.0% 100.0% boost::capy::consuming_buffers<std::array<boost::capy::const_buffer, 100ul> >::consuming_buffers(std::array<boost::capy::const_buffer, 100ul> const&) :73 0 0.0% 0.0% boost::capy::consuming_buffers<std::array<boost::capy::const_buffer, 1ul> >::consuming_buffers(std::array<boost::capy::const_buffer, 1ul> const&) :73 0 0.0% 0.0% boost::capy::consuming_buffers<std::array<boost::capy::const_buffer, 256ul> >::consuming_buffers(std::array<boost::capy::const_buffer, 256ul> const&) :73 0 0.0% 0.0% boost::capy::consuming_buffers<std::array<boost::capy::const_buffer, 2ul> >::consuming_buffers(std::array<boost::capy::const_buffer, 2ul> const&) :73 55x 100.0% 100.0% boost::capy::consuming_buffers<std::array<boost::capy::const_buffer, 4ul> >::consuming_buffers(std::array<boost::capy::const_buffer, 4ul> const&) :73 0 0.0% 0.0% boost::capy::consuming_buffers<std::array<boost::capy::const_buffer, 5ul> >::consuming_buffers(std::array<boost::capy::const_buffer, 5ul> const&) :73 1x 100.0% 100.0% boost::capy::consuming_buffers<std::array<boost::capy::mutable_buffer, 1ul> >::consuming_buffers(std::array<boost::capy::mutable_buffer, 1ul> const&) :73 1x 100.0% 100.0% boost::capy::consuming_buffers<std::array<boost::capy::mutable_buffer, 2ul> >::consuming_buffers(std::array<boost::capy::mutable_buffer, 2ul> const&) :73 46x 100.0% 100.0% boost::capy::consuming_buffers<boost::capy::const_buffer>::data() const :90 132x 100.0% 100.0% boost::capy::consuming_buffers<boost::capy::detail::slice_of<std::array<boost::capy::const_buffer, 2ul> > >::data() const :90 2x 100.0% 100.0% boost::capy::consuming_buffers<boost::capy::mutable_buffer>::data() const :90 110x 100.0% 100.0% boost::capy::consuming_buffers<std::array<boost::capy::const_buffer, 100ul> >::data() const :90 0 0.0% 0.0% boost::capy::consuming_buffers<std::array<boost::capy::const_buffer, 1ul> >::data() const :90 0 0.0% 0.0% boost::capy::consuming_buffers<std::array<boost::capy::const_buffer, 256ul> >::data() const :90 0 0.0% 0.0% boost::capy::consuming_buffers<std::array<boost::capy::const_buffer, 2ul> >::data() const :90 55x 100.0% 100.0% boost::capy::consuming_buffers<std::array<boost::capy::const_buffer, 4ul> >::data() const :90 0 0.0% 0.0% boost::capy::consuming_buffers<std::array<boost::capy::const_buffer, 5ul> >::data() const :90 1x 100.0% 100.0% boost::capy::consuming_buffers<std::array<boost::capy::mutable_buffer, 1ul> >::data() const :90 2x 100.0% 100.0% boost::capy::consuming_buffers<std::array<boost::capy::mutable_buffer, 2ul> >::data() const :90 60x 100.0% 100.0% boost::capy::consuming_buffers<boost::capy::const_buffer>::consume(unsigned long) :102 17x 100.0% 100.0% boost::capy::consuming_buffers<boost::capy::mutable_buffer>::consume(unsigned long) :102 31x 80.0% 88.0%
Line TLA Hits Source 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 @code
39 consuming_buffers consuming(buffers);
40 std::size_t total = 0, want = buffer_size(buffers);
41 while (total < want)
42 {
43 auto [ec, n] = co_await stream.read_some(consuming.data());
44 consuming.consume(n);
45 total += n;
46 if (ec && total < want) co_return {ec, total};
47 }
48 @endcode
49
50 @see buffer_slice, slice_of
51 */
52 template<class Seq>
53 requires MutableBufferSequence<Seq> || ConstBufferSequence<Seq>
54 class consuming_buffers
55 {
56 public:
57 /// Names the buffer type the underlying sequence `Seq` yields.
58 using buffer_type = capy::buffer_type<Seq>;
59
60 private:
61 using iterator_type =
62 decltype(capy::begin(std::declval<Seq const&>()));
63
64 iterator_type first_{};
65 iterator_type last_{};
66 std::size_t front_skip_ = 0; // bytes consumed from *first_
67
68 public:
69 /** Construct a cursor over `s`.
70
71 @param s The sequence to consume. Must outlive the cursor.
72 */
73 315x explicit consuming_buffers(Seq const& s) noexcept
74 315x : first_(capy::begin(s))
75 315x , last_(capy::end(s))
76 {
77 315x }
78
79 /** Reject construction from a temporary (the view would dangle).
80
81 @param s The sequence that would be consumed.
82 */
83 consuming_buffers(Seq const&& s) = delete;
84
85 /** Return the remaining (unconsumed) bytes as a buffer sequence.
86
87 @return The bytes not yet consumed, as a buffer sequence.
88 */
89 detail::slice_of<Seq>
90 362x data() const noexcept
91 {
92 362x return detail::slice_of<Seq>(first_, last_, front_skip_, 0);
93 }
94
95 /** Discard `n` bytes from the front, in place.
96
97 Advances past `min(n, remaining)` bytes.
98
99 @param n The number of bytes consumed.
100 */
101 void
102 272x consume(std::size_t n) noexcept
103 {
104 415x while (n > 0 && first_ != last_)
105 {
106 214x std::size_t const sz = buffer_type(*first_).size();
107 214x std::size_t const avail = sz - front_skip_;
108 214x if (n < avail)
109 {
110 71x front_skip_ += n;
111 71x return;
112 }
113 143x n -= avail;
114 143x ++first_;
115 143x front_skip_ = 0;
116 }
117 }
118 };
119
120 /** Deduce the sequence type from the constructor argument.
121
122 @tparam Seq The buffer sequence type.
123 */
124 template<class Seq>
125 consuming_buffers(Seq const&) -> consuming_buffers<Seq>;
126
127 } // namespace capy
128 } // namespace boost
129
130 #endif
131