include/boost/capy/detail/consuming_buffers.hpp

100.0% Lines (16 / 16) 76.9% Functions (20 / 26)
consuming_buffers.hpp
f(x) Functions (26)
Function Calls Lines Blocks
boost::capy::detail::consuming_buffers<boost::capy::(anonymous namespace)::ambiguous_range_of_const>::consuming_buffers(boost::capy::(anonymous namespace)::ambiguous_range_of_const const&) :59 1x 100.0% 100.0% boost::capy::detail::consuming_buffers<boost::capy::(anonymous namespace)::converts_to_const_range_of_mutable>::consuming_buffers(boost::capy::(anonymous namespace)::converts_to_const_range_of_mutable const&) :59 1x 100.0% 100.0% boost::capy::detail::consuming_buffers<boost::capy::const_buffer>::consuming_buffers(boost::capy::const_buffer const&) :59 102x 100.0% 100.0% boost::capy::detail::consuming_buffers<boost::capy::mutable_buffer>::consuming_buffers(boost::capy::mutable_buffer const&) :59 101x 100.0% 100.0% boost::capy::detail::consuming_buffers<std::array<boost::capy::(anonymous namespace)::user_buffer, 2ul> >::consuming_buffers(std::array<boost::capy::(anonymous namespace)::user_buffer, 2ul> const&) :59 1x 100.0% 100.0% boost::capy::detail::consuming_buffers<std::array<boost::capy::const_buffer, 100ul> >::consuming_buffers(std::array<boost::capy::const_buffer, 100ul> const&) :59 0 0.0% 0.0% boost::capy::detail::consuming_buffers<std::array<boost::capy::const_buffer, 1ul> >::consuming_buffers(std::array<boost::capy::const_buffer, 1ul> const&) :59 0 0.0% 0.0% boost::capy::detail::consuming_buffers<std::array<boost::capy::const_buffer, 256ul> >::consuming_buffers(std::array<boost::capy::const_buffer, 256ul> const&) :59 0 0.0% 0.0% boost::capy::detail::consuming_buffers<std::array<boost::capy::const_buffer, 2ul> >::consuming_buffers(std::array<boost::capy::const_buffer, 2ul> const&) :59 54x 100.0% 100.0% boost::capy::detail::consuming_buffers<std::array<boost::capy::const_buffer, 5ul> >::consuming_buffers(std::array<boost::capy::const_buffer, 5ul> const&) :59 1x 100.0% 100.0% boost::capy::detail::consuming_buffers<std::array<boost::capy::mutable_buffer, 1ul> >::consuming_buffers(std::array<boost::capy::mutable_buffer, 1ul> const&) :59 1x 100.0% 100.0% boost::capy::detail::consuming_buffers<std::array<boost::capy::mutable_buffer, 2ul> >::consuming_buffers(std::array<boost::capy::mutable_buffer, 2ul> const&) :59 44x 100.0% 100.0% boost::capy::detail::consuming_buffers<boost::capy::(anonymous namespace)::ambiguous_range_of_const>::data() const :76 1x 100.0% 100.0% boost::capy::detail::consuming_buffers<boost::capy::(anonymous namespace)::converts_to_const_range_of_mutable>::data() const :76 1x 100.0% 100.0% boost::capy::detail::consuming_buffers<boost::capy::const_buffer>::data() const :76 125x 100.0% 100.0% boost::capy::detail::consuming_buffers<boost::capy::mutable_buffer>::data() const :76 113x 100.0% 100.0% boost::capy::detail::consuming_buffers<std::array<boost::capy::(anonymous namespace)::user_buffer, 2ul> >::data() const :76 1x 100.0% 100.0% boost::capy::detail::consuming_buffers<std::array<boost::capy::const_buffer, 100ul> >::data() const :76 0 0.0% 0.0% boost::capy::detail::consuming_buffers<std::array<boost::capy::const_buffer, 1ul> >::data() const :76 0 0.0% 0.0% boost::capy::detail::consuming_buffers<std::array<boost::capy::const_buffer, 256ul> >::data() const :76 0 0.0% 0.0% boost::capy::detail::consuming_buffers<std::array<boost::capy::const_buffer, 2ul> >::data() const :76 54x 100.0% 100.0% boost::capy::detail::consuming_buffers<std::array<boost::capy::const_buffer, 5ul> >::data() const :76 1x 100.0% 100.0% boost::capy::detail::consuming_buffers<std::array<boost::capy::mutable_buffer, 1ul> >::data() const :76 2x 100.0% 100.0% boost::capy::detail::consuming_buffers<std::array<boost::capy::mutable_buffer, 2ul> >::data() const :76 56x 100.0% 100.0% boost::capy::detail::consuming_buffers<boost::capy::const_buffer>::consume(unsigned long) :88 7x 100.0% 100.0% boost::capy::detail::consuming_buffers<boost::capy::mutable_buffer>::consume(unsigned long) :88 34x 100.0% 100.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_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 */
59 306x explicit consuming_buffers(Seq const& s) noexcept
60 306x : first_(capy::buffer_sequence_begin(s))
61 306x , last_(capy::buffer_sequence_end(s))
62 {
63 306x }
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>
76 354x data() const noexcept
77 {
78 354x 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
88 262x consume(std::size_t n) noexcept
89 {
90 387x while (n > 0 && first_ != last_)
91 {
92 199x std::size_t const sz = buffer_type(*first_).size();
93 199x std::size_t const avail = sz - front_skip_;
94 199x if (n < avail)
95 {
96 74x front_skip_ += n;
97 74x return;
98 }
99 125x n -= avail;
100 125x ++first_;
101 125x 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
118