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