Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-09-17 08:24:08

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