Line data 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 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 : 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 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 : 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 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
|