libs/capy/include/boost/capy/buffers/some_buffers.hpp

100.0% Lines (55/55) 100.0% Functions (26/26) 65.0% Branches (26/40)
libs/capy/include/boost/capy/buffers/some_buffers.hpp
Line Branch Hits Source Code
1 //
2 // Copyright (c) 2025 Vinnie Falco (vinnie.falco@gmail.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_SOME_BUFFERS_HPP
11 #define BOOST_CAPY_BUFFERS_SOME_BUFFERS_HPP
12
13 #include <boost/capy/detail/config.hpp>
14 #include <boost/capy/buffers.hpp>
15
16 #include <cstddef>
17 #include <new>
18 #include <utility>
19
20 namespace boost {
21 namespace capy {
22
23 namespace detail {
24
25 template<class Buffer, class BS, std::size_t... Is>
26 std::size_t
27 8 fill_buffers_impl(
28 Buffer* arr,
29 BS const& bs,
30 std::index_sequence<Is...>) noexcept
31 {
32 8 auto it = begin(bs);
33 8 auto const last = end(bs);
34 8 std::size_t n = 0;
35
18/32
✓ Branch 0 taken 8 times.
✗ Branch 1 not taken.
✓ Branch 3 taken 2 times.
✓ Branch 4 taken 6 times.
✓ Branch 6 taken 2 times.
✓ Branch 7 taken 6 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 8 times.
✗ Branch 12 not taken.
✓ Branch 13 taken 8 times.
✗ Branch 15 not taken.
✓ Branch 16 taken 8 times.
✗ Branch 18 not taken.
✓ Branch 19 taken 8 times.
✗ Branch 21 not taken.
✓ Branch 22 taken 8 times.
✗ Branch 24 not taken.
✓ Branch 25 taken 8 times.
✗ Branch 27 not taken.
✓ Branch 28 taken 8 times.
✗ Branch 30 not taken.
✓ Branch 31 taken 8 times.
✗ Branch 33 not taken.
✓ Branch 34 taken 8 times.
✗ Branch 36 not taken.
✓ Branch 37 taken 8 times.
✗ Branch 39 not taken.
✓ Branch 40 taken 8 times.
✗ Branch 42 not taken.
✓ Branch 43 taken 8 times.
✗ Branch 45 not taken.
✓ Branch 46 taken 8 times.
8 ((it != last ? (::new(&arr[Is]) Buffer(*it++), ++n, void()) : void()), ...);
36 8 return n;
37 }
38
39 template<class Buffer, class BS>
40 std::size_t
41 8 fill_buffers(Buffer* arr, BS const& bs) noexcept
42 {
43 8 return fill_buffers_impl(
44 8 arr, bs, std::make_index_sequence<max_iovec_>{});
45 }
46
47 } // detail
48
49 //------------------------------------------------
50
51 /** A buffer sequence holding up to max_iovec_ const buffers.
52
53 This class stores a fixed-size array of const_buffer
54 descriptors, populated from an arbitrary buffer sequence.
55 It provides efficient storage for small buffer sequences
56 without dynamic allocation.
57
58 @par Usage
59
60 @code
61 void process(ConstBufferSequence auto const& buffers)
62 {
63 some_const_buffers bufs(buffers);
64 // use bufs.data(), bufs.size()
65 }
66 @endcode
67 */
68 class some_const_buffers
69 {
70 union {
71 int dummy_;
72 const_buffer arr_[detail::max_iovec_];
73 };
74 std::size_t n_ = 0;
75
76 public:
77 /** Default constructor.
78
79 Constructs an empty buffer sequence.
80 */
81 1 some_const_buffers() noexcept
82 1 : dummy_(0)
83 {
84 1 }
85
86 /** Copy constructor.
87 */
88 1 some_const_buffers(some_const_buffers const& other) noexcept
89 1 : n_(other.n_)
90 {
91
2/2
✓ Branch 0 taken 1 time.
✓ Branch 1 taken 1 time.
2 for(std::size_t i = 0; i < n_; ++i)
92 1 ::new(&arr_[i]) const_buffer(other.arr_[i]);
93 1 }
94
95 /** Construct from a buffer sequence.
96
97 Copies up to @ref detail::max_iovec_ buffer descriptors
98 from the source sequence into the internal array.
99
100 @param bs The buffer sequence to copy from.
101 */
102 template<ConstBufferSequence BS>
103 explicit
104 4 some_const_buffers(BS const& bs) noexcept
105 4 : n_(detail::fill_buffers(arr_, bs))
106 {
107 4 }
108
109 /** Destructor.
110 */
111 6 ~some_const_buffers()
112 {
113
2/2
✓ Branch 0 taken 7 times.
✓ Branch 1 taken 6 times.
13 while(n_--)
114 7 arr_[n_].~const_buffer();
115 6 }
116
117 /** Return a pointer to the buffer array.
118 */
119 const_buffer*
120 7 data() noexcept
121 {
122 7 return arr_;
123 }
124
125 /** Return a pointer to the buffer array.
126 */
127 const_buffer const*
128 data() const noexcept
129 {
130 return arr_;
131 }
132
133 /** Return the number of buffers.
134 */
135 std::size_t
136 4 size() const noexcept
137 {
138 4 return n_;
139 }
140
141 /** Return an iterator to the beginning.
142 */
143 const_buffer*
144 2 begin() noexcept
145 {
146 2 return arr_;
147 }
148
149 /** Return an iterator to the beginning.
150 */
151 const_buffer const*
152 begin() const noexcept
153 {
154 return arr_;
155 }
156
157 /** Return an iterator to the end.
158 */
159 const_buffer*
160 3 end() noexcept
161 {
162 3 return arr_ + n_;
163 }
164
165 /** Return an iterator to the end.
166 */
167 const_buffer const*
168 end() const noexcept
169 {
170 return arr_ + n_;
171 }
172 };
173
174 //------------------------------------------------
175
176 /** A buffer sequence holding up to max_iovec_ mutable buffers.
177
178 This class stores a fixed-size array of mutable_buffer
179 descriptors, populated from an arbitrary buffer sequence.
180 It provides efficient storage for small buffer sequences
181 without dynamic allocation.
182
183 @par Usage
184
185 @code
186 void process(MutableBufferSequence auto const& buffers)
187 {
188 some_mutable_buffers bufs(buffers);
189 // use bufs.data(), bufs.size()
190 }
191 @endcode
192 */
193 class some_mutable_buffers
194 {
195 union {
196 int dummy_;
197 mutable_buffer arr_[detail::max_iovec_];
198 };
199 std::size_t n_ = 0;
200
201 public:
202 /** Default constructor.
203
204 Constructs an empty buffer sequence.
205 */
206 1 some_mutable_buffers() noexcept
207 1 : dummy_(0)
208 {
209 1 }
210
211 /** Copy constructor.
212 */
213 1 some_mutable_buffers(some_mutable_buffers const& other) noexcept
214 1 : n_(other.n_)
215 {
216
2/2
✓ Branch 0 taken 1 time.
✓ Branch 1 taken 1 time.
2 for(std::size_t i = 0; i < n_; ++i)
217 1 ::new(&arr_[i]) mutable_buffer(other.arr_[i]);
218 1 }
219
220 /** Construct from a buffer sequence.
221
222 Copies up to @ref detail::max_iovec_ buffer descriptors
223 from the source sequence into the internal array.
224
225 @param bs The buffer sequence to copy from.
226 */
227 template<MutableBufferSequence BS>
228 explicit
229 4 some_mutable_buffers(BS const& bs) noexcept
230 4 : n_(detail::fill_buffers(arr_, bs))
231 {
232 4 }
233
234 /** Destructor.
235 */
236 6 ~some_mutable_buffers()
237 {
238
2/2
✓ Branch 0 taken 7 times.
✓ Branch 1 taken 6 times.
13 while(n_--)
239 7 arr_[n_].~mutable_buffer();
240 6 }
241
242 /** Return a pointer to the buffer array.
243 */
244 mutable_buffer*
245 7 data() noexcept
246 {
247 7 return arr_;
248 }
249
250 /** Return a pointer to the buffer array.
251 */
252 mutable_buffer const*
253 data() const noexcept
254 {
255 return arr_;
256 }
257
258 /** Return the number of buffers.
259 */
260 std::size_t
261 4 size() const noexcept
262 {
263 4 return n_;
264 }
265
266 /** Return an iterator to the beginning.
267 */
268 mutable_buffer*
269 2 begin() noexcept
270 {
271 2 return arr_;
272 }
273
274 /** Return an iterator to the beginning.
275 */
276 mutable_buffer const*
277 begin() const noexcept
278 {
279 return arr_;
280 }
281
282 /** Return an iterator to the end.
283 */
284 mutable_buffer*
285 3 end() noexcept
286 {
287 3 return arr_ + n_;
288 }
289
290 /** Return an iterator to the end.
291 */
292 mutable_buffer const*
293 end() const noexcept
294 {
295 return arr_ + n_;
296 }
297 };
298
299 } // namespace capy
300 } // namespace boost
301
302 #endif
303