]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/boost/beast/core/impl/buffers_cat.ipp
update sources to v12.2.3
[ceph.git] / ceph / src / boost / boost / beast / core / impl / buffers_cat.ipp
1 //
2 // Copyright (c) 2016-2017 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/boostorg/beast
8 //
9
10 #ifndef BOOST_BEAST_IMPL_BUFFERS_CAT_IPP
11 #define BOOST_BEAST_IMPL_BUFFERS_CAT_IPP
12
13 #include <boost/beast/core/detail/type_traits.hpp>
14 #include <boost/asio/buffer.hpp>
15 #include <boost/throw_exception.hpp>
16 #include <array>
17 #include <cstdint>
18 #include <iterator>
19 #include <new>
20 #include <stdexcept>
21 #include <tuple>
22 #include <utility>
23
24 namespace boost {
25 namespace beast {
26
27 template<class... Bn>
28 class buffers_cat_view<Bn...>::const_iterator
29 {
30 std::size_t n_;
31 std::tuple<Bn...> const* bn_;
32 std::array<char, detail::max_sizeof<
33 typename detail::buffer_sequence_iterator<Bn>::type...>()> buf_;
34
35 friend class buffers_cat_view<Bn...>;
36
37 template<std::size_t I>
38 using C = std::integral_constant<std::size_t, I>;
39
40 template<std::size_t I>
41 using iter_t = typename detail::buffer_sequence_iterator<
42 typename std::tuple_element<I, std::tuple<Bn...>>::type>::type;
43
44 template<std::size_t I>
45 iter_t<I>&
46 iter()
47 {
48 // type-pun
49 return *reinterpret_cast<
50 iter_t<I>*>(static_cast<void*>(buf_.data()));
51 }
52
53 template<std::size_t I>
54 iter_t<I> const&
55 iter() const
56 {
57 // type-pun
58 return *reinterpret_cast<
59 iter_t<I> const*>(static_cast<
60 void const*>(buf_.data()));
61 }
62
63 public:
64 using value_type = typename
65 detail::common_buffers_type<Bn...>::type;
66 using pointer = value_type const*;
67 using reference = value_type;
68 using difference_type = std::ptrdiff_t;
69 using iterator_category =
70 std::bidirectional_iterator_tag;
71
72 ~const_iterator();
73 const_iterator();
74 const_iterator(const_iterator&& other);
75 const_iterator(const_iterator const& other);
76 const_iterator& operator=(const_iterator&& other);
77 const_iterator& operator=(const_iterator const& other);
78
79 bool
80 operator==(const_iterator const& other) const;
81
82 bool
83 operator!=(const_iterator const& other) const
84 {
85 return ! (*this == other);
86 }
87
88 reference
89 operator*() const;
90
91 pointer
92 operator->() const = delete;
93
94 const_iterator&
95 operator++();
96
97 const_iterator
98 operator++(int);
99
100 const_iterator&
101 operator--();
102
103 const_iterator
104 operator--(int);
105
106 private:
107 const_iterator(
108 std::tuple<Bn...> const& bn, bool at_end);
109
110 void
111 construct(C<sizeof...(Bn)> const&)
112 {
113 auto constexpr I = sizeof...(Bn);
114 n_ = I;
115 }
116
117 template<std::size_t I>
118 void
119 construct(C<I> const&)
120 {
121 if(boost::asio::buffer_size(
122 std::get<I>(*bn_)) != 0)
123 {
124 n_ = I;
125 new(&buf_[0]) iter_t<I>{
126 boost::asio::buffer_sequence_begin(
127 std::get<I>(*bn_))};
128 return;
129 }
130 construct(C<I+1>{});
131 }
132
133 void
134 rconstruct(C<0> const&)
135 {
136 auto constexpr I = 0;
137 if(boost::asio::buffer_size(
138 std::get<I>(*bn_)) != 0)
139 {
140 n_ = I;
141 new(&buf_[0]) iter_t<I>{
142 boost::asio::buffer_sequence_end(
143 std::get<I>(*bn_))};
144 return;
145 }
146 BOOST_THROW_EXCEPTION(std::logic_error{
147 "invalid iterator"});
148 }
149
150 template<std::size_t I>
151 void
152 rconstruct(C<I> const&)
153 {
154 if(boost::asio::buffer_size(
155 std::get<I>(*bn_)) != 0)
156 {
157 n_ = I;
158 new(&buf_[0]) iter_t<I>{
159 boost::asio::buffer_sequence_end(
160 std::get<I>(*bn_))};
161 return;
162 }
163 rconstruct(C<I-1>{});
164 }
165
166 void
167 destroy(C<sizeof...(Bn)> const&)
168 {
169 return;
170 }
171
172 template<std::size_t I>
173 void
174 destroy(C<I> const&)
175 {
176 if(n_ == I)
177 {
178 using Iter = iter_t<I>;
179 iter<I>().~Iter();
180 return;
181 }
182 destroy(C<I+1>{});
183 }
184
185 void
186 move(const_iterator&&,
187 C<sizeof...(Bn)> const&)
188 {
189 }
190
191 template<std::size_t I>
192 void
193 move(const_iterator&& other,
194 C<I> const&)
195 {
196 if(n_ == I)
197 {
198 new(&buf_[0]) iter_t<I>{
199 std::move(other.iter<I>())};
200 return;
201 }
202 move(std::move(other), C<I+1>{});
203 }
204
205 void
206 copy(const_iterator const&,
207 C<sizeof...(Bn)> const&)
208 {
209 }
210
211 template<std::size_t I>
212 void
213 copy(const_iterator const& other,
214 C<I> const&)
215 {
216 if(n_ == I)
217 {
218 new(&buf_[0]) iter_t<I>{
219 other.iter<I>()};
220 return;
221 }
222 copy(other, C<I+1>{});
223 }
224
225 bool
226 equal(const_iterator const&,
227 C<sizeof...(Bn)> const&) const
228 {
229 return true;
230 }
231
232 template<std::size_t I>
233 bool
234 equal(const_iterator const& other,
235 C<I> const&) const
236 {
237 if(n_ == I)
238 return iter<I>() == other.iter<I>();
239 return equal(other, C<I+1>{});
240 }
241
242 [[noreturn]]
243 reference
244 dereference(C<sizeof...(Bn)> const&) const
245 {
246 BOOST_THROW_EXCEPTION(std::logic_error{
247 "invalid iterator"});
248 }
249
250 template<std::size_t I>
251 reference
252 dereference(C<I> const&) const
253 {
254 if(n_ == I)
255 return *iter<I>();
256 return dereference(C<I+1>{});
257 }
258
259 [[noreturn]]
260 void
261 increment(C<sizeof...(Bn)> const&)
262 {
263 BOOST_THROW_EXCEPTION(std::logic_error{
264 "invalid iterator"});
265 }
266
267 template<std::size_t I>
268 void
269 increment(C<I> const&)
270 {
271 if(n_ == I)
272 {
273 if(++iter<I>() !=
274 boost::asio::buffer_sequence_end(
275 std::get<I>(*bn_)))
276 return;
277 using Iter = iter_t<I>;
278 iter<I>().~Iter();
279 return construct(C<I+1>{});
280 }
281 increment(C<I+1>{});
282 }
283
284 void
285 decrement(C<sizeof...(Bn)> const&)
286 {
287 auto constexpr I = sizeof...(Bn);
288 if(n_ == I)
289 rconstruct(C<I-1>{});
290 decrement(C<I-1>{});
291 }
292
293 template<std::size_t I>
294 void
295 decrement(C<I> const&)
296 {
297 if(n_ == I)
298 {
299 if(iter<I>() !=
300 boost::asio::buffer_sequence_begin(
301 std::get<I>(*bn_)))
302 {
303 --iter<I>();
304 return;
305 }
306 --n_;
307 using Iter = iter_t<I>;
308 iter<I>().~Iter();
309 rconstruct(C<I-1>{});
310 }
311 decrement(C<I-1>{});
312 }
313
314 void
315 decrement(C<0> const&)
316 {
317 auto constexpr I = 0;
318 if(iter<I>() !=
319 boost::asio::buffer_sequence_begin(
320 std::get<I>(*bn_)))
321 {
322 --iter<I>();
323 return;
324 }
325 BOOST_THROW_EXCEPTION(std::logic_error{
326 "invalid iterator"});
327 }
328 };
329
330 //------------------------------------------------------------------------------
331
332 template<class... Bn>
333 buffers_cat_view<Bn...>::
334 const_iterator::~const_iterator()
335 {
336 destroy(C<0>{});
337 }
338
339 template<class... Bn>
340 buffers_cat_view<Bn...>::
341 const_iterator::const_iterator()
342 : n_(sizeof...(Bn))
343 , bn_(nullptr)
344 {
345 }
346
347 template<class... Bn>
348 buffers_cat_view<Bn...>::
349 const_iterator::const_iterator(
350 std::tuple<Bn...> const& bn, bool at_end)
351 : bn_(&bn)
352 {
353 if(at_end)
354 n_ = sizeof...(Bn);
355 else
356 construct(C<0>{});
357 }
358
359 template<class... Bn>
360 buffers_cat_view<Bn...>::
361 const_iterator::const_iterator(const_iterator&& other)
362 : n_(other.n_)
363 , bn_(other.bn_)
364 {
365 move(std::move(other), C<0>{});
366 }
367
368 template<class... Bn>
369 buffers_cat_view<Bn...>::
370 const_iterator::const_iterator(const_iterator const& other)
371 : n_(other.n_)
372 , bn_(other.bn_)
373 {
374 copy(other, C<0>{});
375 }
376
377 template<class... Bn>
378 auto
379 buffers_cat_view<Bn...>::
380 const_iterator::operator=(const_iterator&& other) ->
381 const_iterator&
382 {
383 if(&other == this)
384 return *this;
385 destroy(C<0>{});
386 n_ = other.n_;
387 bn_ = other.bn_;
388 // VFALCO What about exceptions?
389 move(std::move(other), C<0>{});
390 return *this;
391 }
392
393 template<class... Bn>
394 auto
395 buffers_cat_view<Bn...>::
396 const_iterator::operator=(const_iterator const& other) ->
397 const_iterator&
398 {
399 if(&other == this)
400 return *this;
401 destroy(C<0>{});
402 n_ = other.n_;
403 bn_ = other.bn_;
404 // VFALCO What about exceptions?
405 copy(other, C<0>{});
406 return *this;
407 }
408
409 template<class... Bn>
410 bool
411 buffers_cat_view<Bn...>::
412 const_iterator::operator==(const_iterator const& other) const
413 {
414 if(bn_ != other.bn_)
415 return false;
416 if(n_ != other.n_)
417 return false;
418 return equal(other, C<0>{});
419 }
420
421 template<class... Bn>
422 auto
423 buffers_cat_view<Bn...>::
424 const_iterator::operator*() const ->
425 reference
426 {
427 return dereference(C<0>{});
428 }
429
430 template<class... Bn>
431 auto
432 buffers_cat_view<Bn...>::
433 const_iterator::operator++() ->
434 const_iterator&
435 {
436 increment(C<0>{});
437 return *this;
438 }
439
440 template<class... Bn>
441 auto
442 buffers_cat_view<Bn...>::
443 const_iterator::operator++(int) ->
444 const_iterator
445 {
446 auto temp = *this;
447 ++(*this);
448 return temp;
449 }
450
451 template<class... Bn>
452 auto
453 buffers_cat_view<Bn...>::
454 const_iterator::operator--() ->
455 const_iterator&
456 {
457 decrement(C<sizeof...(Bn)>{});
458 return *this;
459 }
460
461 template<class... Bn>
462 auto
463 buffers_cat_view<Bn...>::
464 const_iterator::operator--(int) ->
465 const_iterator
466 {
467 auto temp = *this;
468 --(*this);
469 return temp;
470 }
471
472 //------------------------------------------------------------------------------
473
474 template<class... Bn>
475 buffers_cat_view<Bn...>::
476 buffers_cat_view(Bn const&... bn)
477 : bn_(bn...)
478 {
479 }
480
481
482 template<class... Bn>
483 inline
484 auto
485 buffers_cat_view<Bn...>::begin() const ->
486 const_iterator
487 {
488 return const_iterator{bn_, false};
489 }
490
491 template<class... Bn>
492 inline
493 auto
494 buffers_cat_view<Bn...>::end() const ->
495 const_iterator
496 {
497 return const_iterator{bn_, true};
498 }
499
500 } // beast
501 } // boost
502
503 #endif