Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-07-05 08:27:55

0001 //
0002 // Copyright (c) 2016-2019 Vinnie Falco (vinnie dot falco at gmail dot com)
0003 //
0004 // Distributed under the Boost Software License, Version 1.0. (See accompanying
0005 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0006 //
0007 // Official repository: https://github.com/boostorg/beast
0008 //
0009 
0010 #ifndef BOOST_BEAST_IMPL_BUFFERS_CAT_HPP
0011 #define BOOST_BEAST_IMPL_BUFFERS_CAT_HPP
0012 
0013 #include <boost/beast/core/detail/tuple.hpp>
0014 #include <boost/beast/core/detail/variant.hpp>
0015 #include <boost/asio/buffer.hpp>
0016 #include <cstdint>
0017 #include <iterator>
0018 #include <new>
0019 #include <stdexcept>
0020 #include <utility>
0021 
0022 namespace boost {
0023 namespace beast {
0024 
0025 template<class Buffer>
0026 class buffers_cat_view<Buffer>
0027 {
0028     Buffer buffer_;
0029 public:
0030     using value_type = buffers_type<Buffer>;
0031 
0032     using const_iterator = buffers_iterator_type<Buffer>;
0033 
0034     explicit
0035     buffers_cat_view(Buffer const& buffer)
0036         : buffer_(buffer)
0037     {
0038     }
0039 
0040     const_iterator
0041     begin() const
0042     {
0043         return net::buffer_sequence_begin(buffer_);
0044     }
0045 
0046     const_iterator
0047     end() const
0048     {
0049         return net::buffer_sequence_end(buffer_);
0050     }
0051 };
0052 
0053 #if defined(_MSC_VER) && ! defined(__clang__)
0054 # define BOOST_BEAST_UNREACHABLE() __assume(false)
0055 #else
0056 # define BOOST_BEAST_UNREACHABLE() __builtin_unreachable()
0057 #endif
0058 
0059 #ifdef BOOST_BEAST_TESTS
0060 
0061 #define BOOST_BEAST_LOGIC_ERROR(s) \
0062     { \
0063         BOOST_THROW_EXCEPTION(std::logic_error((s))); \
0064         BOOST_BEAST_UNREACHABLE(); \
0065     }
0066 
0067 #define BOOST_BEAST_LOGIC_ERROR_RETURN(s, v) \
0068     { \
0069         BOOST_THROW_EXCEPTION(std::logic_error((s))); \
0070         return v; \
0071     }
0072 
0073 #else
0074 
0075 #define BOOST_BEAST_LOGIC_ERROR(s) \
0076     { \
0077         BOOST_ASSERT_MSG(false, s); \
0078         BOOST_BEAST_UNREACHABLE(); \
0079     }
0080 
0081 #define BOOST_BEAST_LOGIC_ERROR_RETURN(s, v) \
0082     { \
0083         BOOST_ASSERT_MSG(false, s); \
0084         return v; \
0085     }
0086 
0087 #endif
0088 
0089 namespace detail {
0090 
0091 struct buffers_cat_view_iterator_base
0092 {
0093     struct past_end
0094     {
0095         char unused = 0; // make g++8 happy
0096 
0097         net::mutable_buffer
0098         operator*() const
0099         {
0100             BOOST_BEAST_LOGIC_ERROR_RETURN(
0101                     "Dereferencing a one-past-the-end iterator", {});
0102         }
0103 
0104         operator bool() const noexcept
0105         {
0106             return true;
0107         }
0108     };
0109 };
0110 
0111 } // detail
0112 
0113 template<class... Bn>
0114 class buffers_cat_view<Bn...>::const_iterator
0115     : private detail::buffers_cat_view_iterator_base
0116 {
0117     // VFALCO The logic to skip empty sequences fails
0118     //        if there is just one buffer in the list.
0119     static_assert(sizeof...(Bn) >= 2,
0120         "A minimum of two sequences are required");
0121 
0122     detail::tuple<Bn...> const* bn_ = nullptr;
0123     detail::variant<
0124         buffers_iterator_type<Bn>..., past_end> it_{};
0125 
0126     friend class buffers_cat_view<Bn...>;
0127 
0128     template<std::size_t I>
0129     using C = std::integral_constant<std::size_t, I>;
0130 
0131 public:
0132     using value_type = typename
0133         buffers_cat_view<Bn...>::value_type;
0134     using pointer = value_type const*;
0135     using reference = value_type;
0136     using difference_type = std::ptrdiff_t;
0137     using iterator_category =
0138         std::bidirectional_iterator_tag;
0139 
0140     const_iterator() = default;
0141     const_iterator(const_iterator const& other) = default;
0142     const_iterator& operator=(
0143         const_iterator const& other) = default;
0144 
0145     bool
0146     operator==(const_iterator const& other) const;
0147 
0148     bool
0149     operator!=(const_iterator const& other) const
0150     {
0151         return ! (*this == other);
0152     }
0153 
0154     reference
0155     operator*() const;
0156 
0157     pointer
0158     operator->() const = delete;
0159 
0160     const_iterator&
0161     operator++();
0162 
0163     const_iterator
0164     operator++(int);
0165 
0166     const_iterator&
0167     operator--();
0168 
0169     const_iterator
0170     operator--(int);
0171 
0172 private:
0173     const_iterator(
0174         detail::tuple<Bn...> const& bn,
0175         std::true_type);
0176 
0177     const_iterator(
0178         detail::tuple<Bn...> const& bn,
0179         std::false_type);
0180 
0181     struct dereference
0182     {
0183         const_iterator const& self;
0184 
0185         reference
0186         operator()(mp11::mp_size_t<0>)
0187         {
0188             BOOST_BEAST_LOGIC_ERROR_RETURN(
0189                 "Dereferencing a default-constructed iterator", {});
0190         }
0191 
0192         template<class I>
0193         reference operator()(I)
0194         {
0195             return *self.it_.template get<I::value>();
0196         }
0197     };
0198 
0199     struct increment
0200     {
0201         const_iterator& self;
0202 
0203         void
0204         operator()(mp11::mp_size_t<0>)
0205         {
0206             BOOST_BEAST_LOGIC_ERROR(
0207                 "Incrementing a default-constructed iterator");
0208         }
0209 
0210         template<std::size_t I>
0211         void
0212         operator()(mp11::mp_size_t<I>)
0213         {
0214             ++self.it_.template get<I>();
0215             next(mp11::mp_size_t<I>{});
0216         }
0217 
0218         template<std::size_t I>
0219         void
0220         next(mp11::mp_size_t<I>)
0221         {
0222             auto& it = self.it_.template get<I>();
0223             for(;;)
0224             {
0225                 if (it == net::buffer_sequence_end(
0226                         detail::get<I-1>(*self.bn_)))
0227                     break;
0228                 if(net::const_buffer(*it).size() > 0)
0229                     return;
0230                 ++it;
0231             }
0232             self.it_.template emplace<I+1>(
0233                 net::buffer_sequence_begin(
0234                     detail::get<I>(*self.bn_)));
0235             next(mp11::mp_size_t<I+1>{});
0236         }
0237 
0238         void
0239         operator()(mp11::mp_size_t<sizeof...(Bn)>)
0240         {
0241             auto constexpr I = sizeof...(Bn);
0242             ++self.it_.template get<I>();
0243             next(mp11::mp_size_t<I>{});
0244         }
0245 
0246         void
0247         next(mp11::mp_size_t<sizeof...(Bn)>)
0248         {
0249             auto constexpr I = sizeof...(Bn);
0250             auto& it = self.it_.template get<I>();
0251             for(;;)
0252             {
0253                 if (it == net::buffer_sequence_end(
0254                         detail::get<I-1>(*self.bn_)))
0255                     break;
0256                 if(net::const_buffer(*it).size() > 0)
0257                     return;
0258                 ++it;
0259             }
0260             // end
0261             self.it_.template emplace<I+1>();
0262         }
0263 
0264         void
0265         operator()(mp11::mp_size_t<sizeof...(Bn)+1>)
0266         {
0267             BOOST_BEAST_LOGIC_ERROR(
0268                 "Incrementing a one-past-the-end iterator");
0269         }
0270     };
0271 
0272     struct decrement
0273     {
0274         const_iterator& self;
0275 
0276         void
0277         operator()(mp11::mp_size_t<0>)
0278         {
0279             BOOST_BEAST_LOGIC_ERROR(
0280                 "Decrementing a default-constructed iterator");
0281         }
0282 
0283         void
0284         operator()(mp11::mp_size_t<1>)
0285         {
0286             auto constexpr I = 1;
0287 
0288             auto& it = self.it_.template get<I>();
0289             for(;;)
0290             {
0291                 if(it == net::buffer_sequence_begin(
0292                     detail::get<I-1>(*self.bn_)))
0293                 {
0294                     BOOST_BEAST_LOGIC_ERROR(
0295                         "Decrementing an iterator to the beginning");
0296                 }
0297                 --it;
0298                 if(net::const_buffer(*it).size() > 0)
0299                     return;
0300             }
0301         }
0302 
0303         template<std::size_t I>
0304         void
0305         operator()(mp11::mp_size_t<I>)
0306         {
0307             auto& it = self.it_.template get<I>();
0308             for(;;)
0309             {
0310                 if(it == net::buffer_sequence_begin(
0311                         detail::get<I-1>(*self.bn_)))
0312                     break;
0313                 --it;
0314                 if(net::const_buffer(*it).size() > 0)
0315                     return;
0316             }
0317             self.it_.template emplace<I-1>(
0318                 net::buffer_sequence_end(
0319                     detail::get<I-2>(*self.bn_)));
0320             (*this)(mp11::mp_size_t<I-1>{});
0321         }
0322 
0323         void
0324         operator()(mp11::mp_size_t<sizeof...(Bn)+1>)
0325         {
0326             auto constexpr I = sizeof...(Bn)+1;
0327             self.it_.template emplace<I-1>(
0328                 net::buffer_sequence_end(
0329                     detail::get<I-2>(*self.bn_)));
0330             (*this)(mp11::mp_size_t<I-1>{});
0331         }
0332     };
0333 };
0334 
0335 //------------------------------------------------------------------------------
0336 
0337 template<class... Bn>
0338 buffers_cat_view<Bn...>::
0339 const_iterator::
0340 const_iterator(
0341     detail::tuple<Bn...> const& bn,
0342     std::true_type)
0343     : bn_(&bn)
0344 {
0345     // one past the end
0346     it_.template emplace<sizeof...(Bn)+1>();
0347 }
0348 
0349 template<class... Bn>
0350 buffers_cat_view<Bn...>::
0351 const_iterator::
0352 const_iterator(
0353     detail::tuple<Bn...> const& bn,
0354     std::false_type)
0355     : bn_(&bn)
0356 {
0357     it_.template emplace<1>(
0358         net::buffer_sequence_begin(
0359             detail::get<0>(*bn_)));
0360     increment{*this}.next(
0361         mp11::mp_size_t<1>{});
0362 }
0363 
0364 template<class... Bn>
0365 bool
0366 buffers_cat_view<Bn...>::
0367 const_iterator::
0368 operator==(const_iterator const& other) const
0369 {
0370     return bn_ == other.bn_ && it_ == other.it_;
0371 }
0372 
0373 template<class... Bn>
0374 auto
0375 buffers_cat_view<Bn...>::
0376 const_iterator::
0377 operator*() const ->
0378     reference
0379 {
0380     return mp11::mp_with_index<
0381         sizeof...(Bn) + 2>(
0382             it_.index(),
0383             dereference{*this});
0384 }
0385 
0386 template<class... Bn>
0387 auto
0388 buffers_cat_view<Bn...>::
0389 const_iterator::
0390 operator++() ->
0391     const_iterator&
0392 {
0393     mp11::mp_with_index<
0394         sizeof...(Bn) + 2>(
0395             it_.index(),
0396             increment{*this});
0397     return *this;
0398 }
0399 
0400 template<class... Bn>
0401 auto
0402 buffers_cat_view<Bn...>::
0403 const_iterator::
0404 operator++(int) ->
0405     const_iterator
0406 {
0407     auto temp = *this;
0408     ++(*this);
0409     return temp;
0410 }
0411 
0412 template<class... Bn>
0413 auto
0414 buffers_cat_view<Bn...>::
0415 const_iterator::
0416 operator--() ->
0417     const_iterator&
0418 {
0419     mp11::mp_with_index<
0420         sizeof...(Bn) + 2>(
0421             it_.index(),
0422             decrement{*this});
0423     return *this;
0424 }
0425 
0426 template<class... Bn>
0427 auto
0428 buffers_cat_view<Bn...>::
0429 const_iterator::
0430 operator--(int) ->
0431     const_iterator
0432 {
0433     auto temp = *this;
0434     --(*this);
0435     return temp;
0436 }
0437 
0438 //------------------------------------------------------------------------------
0439 
0440 template<class... Bn>
0441 buffers_cat_view<Bn...>::
0442 buffers_cat_view(Bn const&... bn)
0443     : bn_(bn...)
0444 {
0445 }
0446 
0447 
0448 template<class... Bn>
0449 auto
0450 buffers_cat_view<Bn...>::begin() const ->
0451     const_iterator
0452 {
0453     return const_iterator{bn_, std::false_type{}};
0454 }
0455 
0456 template<class... Bn>
0457 auto
0458 buffers_cat_view<Bn...>::end() const->
0459     const_iterator
0460 {
0461     return const_iterator{bn_, std::true_type{}};
0462 }
0463 
0464 } // beast
0465 } // boost
0466 
0467 #endif