GCC Code Coverage Report


Directory: ./
File: libs/capy/include/boost/capy/buffers/buffer_param.hpp
Date: 2026-01-21 01:18:26
Exec Total Coverage
Lines: 21 21 100.0%
Functions: 9 9 100.0%
Branches: 0 0 -%

Line Branch Exec Source
1 //
2 // Copyright (c) 2025 Vinnie Falco (vinnie dot falco at gmail dot com)
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_BUFFER_PARAM_HPP
11 #define BOOST_CAPY_BUFFERS_BUFFER_PARAM_HPP
12
13 #include <boost/capy/detail/config.hpp>
14 #include <boost/capy/buffers.hpp>
15
16 #include <cstddef>
17
18 namespace boost {
19 namespace capy {
20
21 /** A type-erased buffer sequence I/O parameter.
22
23 This class provides a type-erased interface for iterating
24 over buffer sequences without knowing the concrete type.
25 It allows asynchronous operations to efficiently type-erase
26 the buffer sequence parameter, avoiding the need to
27 templatize the implementation.
28
29 @par Passing Convention
30
31 This type is designed to be passed by value. It contains only
32 two pointers (16 bytes on 64-bit systems), making copies trivial.
33 Pass-by-value is preferred as it clearly communicates the
34 lightweight, transient nature of this parameter type:
35
36 @code
37 // Preferred: pass by value
38 void process_buffers( buffer_param buffers );
39
40 // Also acceptable: pass by const reference
41 void process_buffers( buffer_param const& buffers );
42 @endcode
43
44 @par Example
45
46 The following shows the minimal form of an awaitable, templated on the
47 buffer sequence type, with only an `await_suspend` method. The example
48 demonstrates that you can pass buffers directly to a virtual interface
49 through implicit conversion.
50
51 @code
52 template<class Buffers>
53 struct awaitable
54 {
55 Buffers b;
56
57 void await_suspend( std::coroutine_handle<> )
58 {
59 my_virtual_engine_submit( b );
60 }
61 };
62
63 // Example virtual interface accepting buffer_param by value
64 void my_virtual_engine_submit( buffer_param p )
65 {
66 capy::mutable_buffer temp[8];
67 std::size_t n = p.copy_to( temp, 8 );
68 // ... handle the buffers ...
69 }
70 @endcode
71 */
72 class buffer_param
73 {
74 public:
75 /** Construct from a const buffer sequence.
76
77 @param bs The buffer sequence to adapt.
78 */
79 template<ConstBufferSequence BS>
80 46 buffer_param(BS const& bs) noexcept
81 46 : bs_(&bs)
82 46 , fn_(&copy_impl<BS>)
83 {
84 46 }
85
86 /** Fill an array with buffers from the sequence.
87
88 Copies buffer descriptors from the sequence into the
89 destination array. If the total number of bytes across
90 all copied buffers is zero, returns 0 regardless of
91 how many buffer descriptors were copied.
92
93 @param dest Pointer to array of mutable buffer descriptors.
94 @param n Maximum number of buffers to copy.
95
96 @return The number of buffers actually copied, or 0 if
97 the total byte count is zero.
98 */
99 std::size_t
100 23 copy_to(
101 mutable_buffer* dest,
102 std::size_t n) const noexcept
103 {
104 23 return fn_(bs_, dest, n);
105 }
106
107 private:
108 template<ConstBufferSequence BS>
109 static std::size_t
110 23 copy_impl(
111 void const* p,
112 mutable_buffer* dest,
113 std::size_t n)
114 {
115 23 auto const& bs = *static_cast<BS const*>(p);
116 23 auto it = begin(bs);
117 23 auto const end_it = end(bs);
118
119 23 std::size_t i = 0;
120 23 std::size_t bytes = 0;
121 if constexpr (MutableBufferSequence<BS>)
122 {
123 10 for(; it != end_it && i < n; ++it, ++i)
124 {
125 6 dest[i] = *it;
126 6 bytes += dest[i].size();
127 }
128 }
129 else
130 {
131 52 for(; it != end_it && i < n; ++it, ++i)
132 {
133 33 auto const& buf = *it;
134 66 dest[i] = mutable_buffer(
135 const_cast<char*>(
136 33 static_cast<char const*>(buf.data())),
137 buf.size());
138 33 bytes += buf.size();
139 }
140 }
141 // Return 0 if total bytes is 0 (empty buffer sequence)
142 23 return bytes == 0 ? 0 : i;
143 }
144
145 using fn_t = std::size_t(*)(void const*,
146 mutable_buffer*, std::size_t);
147
148 void const* bs_;
149 fn_t fn_;
150 };
151
152 } // namespace capy
153 } // namespace boost
154
155 #endif
156