Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:29:26

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 # define BOOST_BEAST_UNREACHABLE_RETURN(v) return v
0056 #else
0057 # define BOOST_BEAST_UNREACHABLE() __builtin_unreachable()
0058 # define BOOST_BEAST_UNREACHABLE_RETURN(v) \
0059     do { __builtin_unreachable(); return v; } while(false)
0060 #endif
0061 
0062 #ifdef BOOST_BEAST_TESTS
0063 
0064 #define BOOST_BEAST_LOGIC_ERROR(s) \
0065     { \
0066         BOOST_THROW_EXCEPTION(std::logic_error((s))); \
0067         BOOST_BEAST_UNREACHABLE(); \
0068     }
0069 
0070 #else
0071 
0072 #define BOOST_BEAST_LOGIC_ERROR(s) \
0073     { \
0074         BOOST_ASSERT_MSG(false, s); \
0075         BOOST_BEAST_UNREACHABLE(); \
0076     }
0077 
0078 #endif
0079 
0080 namespace detail {
0081 
0082 struct buffers_cat_view_iterator_base
0083 {
0084     struct past_end
0085     {
0086         char unused = 0; // make g++8 happy
0087 
0088         BOOST_NORETURN net::mutable_buffer
0089         operator*() const
0090         {
0091             BOOST_BEAST_LOGIC_ERROR(
0092                     "Dereferencing a one-past-the-end iterator");
0093         }
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         BOOST_NORETURN reference
0177         operator()(mp11::mp_size_t<0>)
0178         {
0179             BOOST_BEAST_LOGIC_ERROR(
0180                 "Dereferencing a default-constructed iterator");
0181         }
0182 
0183         template<class I>
0184         reference operator()(I)
0185         {
0186             return *self.it_.template get<I::value>();
0187         }
0188     };
0189 
0190     struct increment
0191     {
0192         const_iterator& self;
0193 
0194         void
0195         operator()(mp11::mp_size_t<0>)
0196         {
0197             BOOST_BEAST_LOGIC_ERROR(
0198                 "Incrementing a default-constructed iterator");
0199         }
0200 
0201         template<std::size_t I>
0202         void
0203         operator()(mp11::mp_size_t<I>)
0204         {
0205             ++self.it_.template get<I>();
0206             next(mp11::mp_size_t<I>{});
0207         }
0208 
0209         template<std::size_t I>
0210         void
0211         next(mp11::mp_size_t<I>)
0212         {
0213             auto& it = self.it_.template get<I>();
0214             for(;;)
0215             {
0216                 if (it == net::buffer_sequence_end(
0217                         detail::get<I-1>(*self.bn_)))
0218                     break;
0219                 if(net::const_buffer(*it).size() > 0)
0220                     return;
0221                 ++it;
0222             }
0223             self.it_.template emplace<I+1>(
0224                 net::buffer_sequence_begin(
0225                     detail::get<I>(*self.bn_)));
0226             next(mp11::mp_size_t<I+1>{});
0227         }
0228 
0229         void
0230         operator()(mp11::mp_size_t<sizeof...(Bn)>)
0231         {
0232             auto constexpr I = sizeof...(Bn);
0233             ++self.it_.template get<I>();
0234             next(mp11::mp_size_t<I>{});
0235         }
0236 
0237         void
0238         next(mp11::mp_size_t<sizeof...(Bn)>)
0239         {
0240             auto constexpr I = sizeof...(Bn);
0241             auto& it = self.it_.template get<I>();
0242             for(;;)
0243             {
0244                 if (it == net::buffer_sequence_end(
0245                         detail::get<I-1>(*self.bn_)))
0246                     break;
0247                 if(net::const_buffer(*it).size() > 0)
0248                     return;
0249                 ++it;
0250             }
0251             // end
0252             self.it_.template emplace<I+1>();
0253         }
0254 
0255         void
0256         operator()(mp11::mp_size_t<sizeof...(Bn)+1>)
0257         {
0258             BOOST_BEAST_LOGIC_ERROR(
0259                 "Incrementing a one-past-the-end iterator");
0260         }
0261     };
0262 
0263     struct decrement
0264     {
0265         const_iterator& self;
0266 
0267         void
0268         operator()(mp11::mp_size_t<0>)
0269         {
0270             BOOST_BEAST_LOGIC_ERROR(
0271                 "Decrementing a default-constructed iterator");
0272         }
0273 
0274         void
0275         operator()(mp11::mp_size_t<1>)
0276         {
0277             auto constexpr I = 1;
0278 
0279             auto& it = self.it_.template get<I>();
0280             for(;;)
0281             {
0282                 if(it == net::buffer_sequence_begin(
0283                     detail::get<I-1>(*self.bn_)))
0284                 {
0285                     BOOST_BEAST_LOGIC_ERROR(
0286                         "Decrementing an iterator to the beginning");
0287                 }
0288                 --it;
0289                 if(net::const_buffer(*it).size() > 0)
0290                     return;
0291             }
0292         }
0293 
0294         template<std::size_t I>
0295         void
0296         operator()(mp11::mp_size_t<I>)
0297         {
0298             auto& it = self.it_.template get<I>();
0299             for(;;)
0300             {
0301                 if(it == net::buffer_sequence_begin(
0302                         detail::get<I-1>(*self.bn_)))
0303                     break;
0304                 --it;
0305                 if(net::const_buffer(*it).size() > 0)
0306                     return;
0307             }
0308             self.it_.template emplace<I-1>(
0309                 net::buffer_sequence_end(
0310                     detail::get<I-2>(*self.bn_)));
0311             (*this)(mp11::mp_size_t<I-1>{});
0312         }
0313 
0314         void
0315         operator()(mp11::mp_size_t<sizeof...(Bn)+1>)
0316         {
0317             auto constexpr I = sizeof...(Bn)+1;
0318             self.it_.template emplace<I-1>(
0319                 net::buffer_sequence_end(
0320                     detail::get<I-2>(*self.bn_)));
0321             (*this)(mp11::mp_size_t<I-1>{});
0322         }
0323     };
0324 };
0325 
0326 //------------------------------------------------------------------------------
0327 
0328 template<class... Bn>
0329 buffers_cat_view<Bn...>::
0330 const_iterator::
0331 const_iterator(
0332     detail::tuple<Bn...> const& bn,
0333     std::true_type)
0334     : bn_(&bn)
0335 {
0336     // one past the end
0337     it_.template emplace<sizeof...(Bn)+1>();
0338 }
0339 
0340 template<class... Bn>
0341 buffers_cat_view<Bn...>::
0342 const_iterator::
0343 const_iterator(
0344     detail::tuple<Bn...> const& bn,
0345     std::false_type)
0346     : bn_(&bn)
0347 {
0348     it_.template emplace<1>(
0349         net::buffer_sequence_begin(
0350             detail::get<0>(*bn_)));
0351     increment{*this}.next(
0352         mp11::mp_size_t<1>{});
0353 }
0354 
0355 template<class... Bn>
0356 bool
0357 buffers_cat_view<Bn...>::
0358 const_iterator::
0359 operator==(const_iterator const& other) const
0360 {
0361     return bn_ == other.bn_ && it_ == other.it_;
0362 }
0363 
0364 template<class... Bn>
0365 auto
0366 buffers_cat_view<Bn...>::
0367 const_iterator::
0368 operator*() const ->
0369     reference
0370 {
0371     return mp11::mp_with_index<
0372         sizeof...(Bn) + 2>(
0373             it_.index(),
0374             dereference{*this});
0375 }
0376 
0377 template<class... Bn>
0378 auto
0379 buffers_cat_view<Bn...>::
0380 const_iterator::
0381 operator++() ->
0382     const_iterator&
0383 {
0384     mp11::mp_with_index<
0385         sizeof...(Bn) + 2>(
0386             it_.index(),
0387             increment{*this});
0388     return *this;
0389 }
0390 
0391 template<class... Bn>
0392 auto
0393 buffers_cat_view<Bn...>::
0394 const_iterator::
0395 operator++(int) ->
0396     const_iterator
0397 {
0398     auto temp = *this;
0399     ++(*this);
0400     return temp;
0401 }
0402 
0403 template<class... Bn>
0404 auto
0405 buffers_cat_view<Bn...>::
0406 const_iterator::
0407 operator--() ->
0408     const_iterator&
0409 {
0410     mp11::mp_with_index<
0411         sizeof...(Bn) + 2>(
0412             it_.index(),
0413             decrement{*this});
0414     return *this;
0415 }
0416 
0417 template<class... Bn>
0418 auto
0419 buffers_cat_view<Bn...>::
0420 const_iterator::
0421 operator--(int) ->
0422     const_iterator
0423 {
0424     auto temp = *this;
0425     --(*this);
0426     return temp;
0427 }
0428 
0429 //------------------------------------------------------------------------------
0430 
0431 template<class... Bn>
0432 buffers_cat_view<Bn...>::
0433 buffers_cat_view(Bn const&... bn)
0434     : bn_(bn...)
0435 {
0436 }
0437 
0438 
0439 template<class... Bn>
0440 auto
0441 buffers_cat_view<Bn...>::begin() const ->
0442     const_iterator
0443 {
0444     return const_iterator{bn_, std::false_type{}};
0445 }
0446 
0447 template<class... Bn>
0448 auto
0449 buffers_cat_view<Bn...>::end() const->
0450     const_iterator
0451 {
0452     return const_iterator{bn_, std::true_type{}};
0453 }
0454 
0455 } // beast
0456 } // boost
0457 
0458 #endif