include/boost/capy/buffers/consuming_buffers.hpp
100.0% Lines (16/16)
73.3% List of functions (11/15)
Functions (15)
Function
Calls
Lines
Blocks
boost::capy::consuming_buffers<boost::capy::const_buffer>::consuming_buffers(boost::capy::const_buffer const&)
:72
94x
100.0%
100.0%
boost::capy::consuming_buffers<boost::capy::mutable_buffer>::consuming_buffers(boost::capy::mutable_buffer const&)
:72
98x
100.0%
100.0%
boost::capy::consuming_buffers<std::array<boost::capy::const_buffer, 1ul> >::consuming_buffers(std::array<boost::capy::const_buffer, 1ul> const&)
:72
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&)
:72
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&)
:72
54x
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&)
:72
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&)
:72
44x
100.0%
100.0%
boost::capy::consuming_buffers<boost::capy::const_buffer>::data() const
:83
115x
100.0%
100.0%
boost::capy::consuming_buffers<boost::capy::mutable_buffer>::data() const
:83
108x
100.0%
100.0%
boost::capy::consuming_buffers<std::array<boost::capy::const_buffer, 1ul> >::data() const
:83
0
0.0%
0.0%
boost::capy::consuming_buffers<std::array<boost::capy::const_buffer, 256ul> >::data() const
:83
0
0.0%
0.0%
boost::capy::consuming_buffers<std::array<boost::capy::const_buffer, 2ul> >::data() const
:83
54x
100.0%
100.0%
boost::capy::consuming_buffers<std::array<boost::capy::mutable_buffer, 1ul> >::data() const
:83
2x
100.0%
100.0%
boost::capy::consuming_buffers<std::array<boost::capy::mutable_buffer, 2ul> >::data() const
:83
56x
100.0%
100.0%
boost::capy::consuming_buffers<boost::capy::mutable_buffer>::consume(unsigned long)
:95
29x
80.0%
88.0%
| Line | TLA | Hits | Source Code |
|---|---|---|---|
| 1 | // | ||
| 2 | // Copyright (c) 2026 Steve Gerbino | ||
| 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 | #include <boost/capy/detail/slice_of.hpp> | ||
| 16 | |||
| 17 | #include <cstddef> | ||
| 18 | #include <utility> | ||
| 19 | |||
| 20 | namespace boost { | ||
| 21 | namespace capy { | ||
| 22 | |||
| 23 | /** A cursor that drives consumption of a buffer sequence. | ||
| 24 | |||
| 25 | `consuming_buffers` is the dedicated driver for `read_some`/`write_some` | ||
| 26 | loops: it presents the not-yet-consumed bytes of a buffer sequence via | ||
| 27 | `data()`, and `consume(n)` advances past `n` transferred bytes **in | ||
| 28 | place**. | ||
| 29 | |||
| 30 | It is deliberately **not** itself a buffer sequence — it hands out the | ||
| 31 | remaining bytes through `data()` (returning a `slice_of` view). It | ||
| 32 | **borrows** the underlying sequence (iterators + a consumed-byte offset); | ||
| 33 | the sequence must outlive the cursor, which is the natural case when the | ||
| 34 | cursor is a local of a composed operation that took its buffers by value. | ||
| 35 | |||
| 36 | @par Example | ||
| 37 | @code | ||
| 38 | consuming_buffers consuming(buffers); | ||
| 39 | std::size_t total = 0, want = buffer_size(buffers); | ||
| 40 | while (total < want) | ||
| 41 | { | ||
| 42 | auto [ec, n] = co_await stream.read_some(consuming.data()); | ||
| 43 | consuming.consume(n); | ||
| 44 | total += n; | ||
| 45 | if (ec && total < want) co_return {ec, total}; | ||
| 46 | } | ||
| 47 | @endcode | ||
| 48 | |||
| 49 | @see buffer_slice, slice_of | ||
| 50 | */ | ||
| 51 | template<class Seq> | ||
| 52 | requires MutableBufferSequence<Seq> || ConstBufferSequence<Seq> | ||
| 53 | class consuming_buffers | ||
| 54 | { | ||
| 55 | public: | ||
| 56 | /// The buffer type of the underlying sequence. | ||
| 57 | using buffer_type = capy::buffer_type<Seq>; | ||
| 58 | |||
| 59 | private: | ||
| 60 | using iterator_type = | ||
| 61 | decltype(capy::begin(std::declval<Seq const&>())); | ||
| 62 | |||
| 63 | iterator_type first_{}; | ||
| 64 | iterator_type last_{}; | ||
| 65 | std::size_t front_skip_ = 0; // bytes consumed from *first_ | ||
| 66 | |||
| 67 | public: | ||
| 68 | /** Construct a cursor over `s`. | ||
| 69 | |||
| 70 | @param s The sequence to consume. Must outlive the cursor. | ||
| 71 | */ | ||
| 72 | 291x | explicit consuming_buffers(Seq const& s) noexcept | |
| 73 | 291x | : first_(capy::begin(s)) | |
| 74 | 291x | , last_(capy::end(s)) | |
| 75 | { | ||
| 76 | 291x | } | |
| 77 | |||
| 78 | /// Reject construction from a temporary (the view would dangle). | ||
| 79 | consuming_buffers(Seq const&&) = delete; | ||
| 80 | |||
| 81 | /// Return the remaining (unconsumed) bytes as a buffer sequence. | ||
| 82 | detail::slice_of<Seq> | ||
| 83 | 335x | data() const noexcept | |
| 84 | { | ||
| 85 | 335x | return detail::slice_of<Seq>(first_, last_, front_skip_, 0); | |
| 86 | } | ||
| 87 | |||
| 88 | /** Discard `n` bytes from the front, in place. | ||
| 89 | |||
| 90 | Advances past `min(n, remaining)` bytes. | ||
| 91 | |||
| 92 | @param n The number of bytes consumed. | ||
| 93 | */ | ||
| 94 | void | ||
| 95 | 245x | consume(std::size_t n) noexcept | |
| 96 | { | ||
| 97 | 358x | while (n > 0 && first_ != last_) | |
| 98 | { | ||
| 99 | 179x | std::size_t const sz = buffer_type(*first_).size(); | |
| 100 | 179x | std::size_t const avail = sz - front_skip_; | |
| 101 | 179x | if (n < avail) | |
| 102 | { | ||
| 103 | 66x | front_skip_ += n; | |
| 104 | 66x | return; | |
| 105 | } | ||
| 106 | 113x | n -= avail; | |
| 107 | 113x | ++first_; | |
| 108 | 113x | front_skip_ = 0; | |
| 109 | } | ||
| 110 | } | ||
| 111 | }; | ||
| 112 | |||
| 113 | // CTAD: deduce the sequence type from the constructor argument. | ||
| 114 | template<class Seq> | ||
| 115 | consuming_buffers(Seq const&) -> consuming_buffers<Seq>; | ||
| 116 | |||
| 117 | } // namespace capy | ||
| 118 | } // namespace boost | ||
| 119 | |||
| 120 | #endif | ||
| 121 |