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_PREFIX_HPP
0011 #define BOOST_BEAST_IMPL_BUFFERS_PREFIX_HPP
0012 
0013 #include <boost/beast/core/buffer_traits.hpp>
0014 #include <boost/config/workaround.hpp>
0015 #include <algorithm>
0016 #include <cstdint>
0017 #include <iterator>
0018 #include <stdexcept>
0019 #include <type_traits>
0020 #include <utility>
0021 
0022 namespace boost {
0023 namespace beast {
0024 
0025 template<class Buffers>
0026 class buffers_prefix_view<Buffers>::const_iterator
0027 {
0028     friend class buffers_prefix_view<Buffers>;
0029 
0030     buffers_prefix_view const* b_ = nullptr;
0031     std::size_t remain_ = 0;
0032     iter_type it_{};
0033 
0034 public:
0035 #if BOOST_WORKAROUND(BOOST_MSVC, < 1910)
0036     using value_type = typename std::conditional<
0037         boost::is_convertible<typename
0038             std::iterator_traits<iter_type>::value_type,
0039                 net::mutable_buffer>::value,
0040                     net::mutable_buffer,
0041                         net::const_buffer>::type;
0042 #else
0043     using value_type = buffers_type<Buffers>;
0044 #endif
0045 
0046     BOOST_STATIC_ASSERT(std::is_same<
0047         typename const_iterator::value_type,
0048         typename buffers_prefix_view::value_type>::value);
0049 
0050     using pointer = value_type const*;
0051     using reference = value_type;
0052     using difference_type = std::ptrdiff_t;
0053     using iterator_category =
0054         std::bidirectional_iterator_tag;
0055 
0056     const_iterator() = default;
0057     const_iterator(
0058         const_iterator const& other) = default;
0059     const_iterator& operator=(
0060         const_iterator const& other) = default;
0061 
0062     bool
0063     operator==(const_iterator const& other) const
0064     {
0065         return b_ == other.b_ && it_ == other.it_;
0066     }
0067 
0068     bool
0069     operator!=(const_iterator const& other) const
0070     {
0071         return !(*this == other);
0072     }
0073 
0074     reference
0075     operator*() const
0076     {
0077         value_type v(*it_);
0078         if(remain_ < v.size())
0079             return {v.data(), remain_};
0080         return v;
0081     }
0082 
0083     pointer
0084     operator->() const = delete;
0085 
0086     const_iterator&
0087     operator++()
0088     {
0089         value_type const v = *it_++;
0090         remain_ -= v.size();
0091         return *this;
0092     }
0093 
0094     const_iterator
0095     operator++(int)
0096     {
0097         auto temp = *this;
0098         value_type const v = *it_++;
0099         remain_ -= v.size();
0100         return temp;
0101     }
0102 
0103     const_iterator&
0104     operator--()
0105     {
0106         value_type const v = *--it_;
0107         remain_ += v.size();
0108         return *this;
0109     }
0110 
0111     const_iterator
0112     operator--(int)
0113     {
0114         auto temp = *this;
0115         value_type const v = *--it_;
0116         remain_ += v.size();
0117         return temp;
0118     }
0119 
0120 private:
0121     const_iterator(
0122         buffers_prefix_view const& b,
0123         std::true_type)
0124         : b_(&b)
0125         , remain_(b.remain_)
0126         , it_(b_->end_)
0127     {
0128     }
0129 
0130     const_iterator(
0131         buffers_prefix_view const& b,
0132         std::false_type)
0133         : b_(&b)
0134         , remain_(b_->size_)
0135         , it_(net::buffer_sequence_begin(b_->bs_))
0136     {
0137     }
0138 };
0139 
0140 //------------------------------------------------------------------------------
0141 
0142 template<class Buffers>
0143 void
0144 buffers_prefix_view<Buffers>::
0145 setup(std::size_t size)
0146 {
0147     size_ = 0;
0148     remain_ = 0;
0149     end_ = net::buffer_sequence_begin(bs_);
0150     auto const last = bs_.end();
0151     while(end_ != last)
0152     {
0153         auto const len = buffer_bytes(*end_++);
0154         if(len >= size)
0155         {
0156             size_ += size;
0157 
0158             // by design, this subtraction can wrap
0159             BOOST_STATIC_ASSERT(std::is_unsigned<
0160                 decltype(remain_)>::value);
0161             remain_ = size - len;
0162             break;
0163         }
0164         size -= len;
0165         size_ += len;
0166     }
0167 }
0168 
0169 template<class Buffers>
0170 buffers_prefix_view<Buffers>::
0171 buffers_prefix_view(
0172     buffers_prefix_view const& other,
0173     std::size_t dist)
0174     : bs_(other.bs_)
0175     , size_(other.size_)
0176     , remain_(other.remain_)
0177     , end_(std::next(bs_.begin(), dist))
0178 {
0179 }
0180 
0181 template<class Buffers>
0182 buffers_prefix_view<Buffers>::
0183 buffers_prefix_view(buffers_prefix_view const& other)
0184     : buffers_prefix_view(other,
0185         std::distance<iter_type>(
0186             net::buffer_sequence_begin(other.bs_),
0187                 other.end_))
0188 {
0189 }
0190 
0191 template<class Buffers>
0192 auto
0193 buffers_prefix_view<Buffers>::
0194 operator=(buffers_prefix_view const& other) ->
0195     buffers_prefix_view&
0196 {
0197     auto const dist = std::distance<iter_type>(
0198         net::buffer_sequence_begin(other.bs_),
0199         other.end_);
0200     bs_ = other.bs_;
0201     size_ = other.size_;
0202     remain_ = other.remain_;
0203     end_ = std::next(
0204         net::buffer_sequence_begin(bs_),
0205             dist);
0206     return *this;
0207 }
0208 
0209 template<class Buffers>
0210 buffers_prefix_view<Buffers>::
0211 buffers_prefix_view(
0212     std::size_t size,
0213     Buffers const& bs)
0214     : bs_(bs)
0215 {
0216     setup(size);
0217 }
0218 
0219 template<class Buffers>
0220 template<class... Args>
0221 buffers_prefix_view<Buffers>::
0222 buffers_prefix_view(
0223     std::size_t size,
0224     boost::in_place_init_t,
0225     Args&&... args)
0226     : bs_(std::forward<Args>(args)...)
0227 {
0228     setup(size);
0229 }
0230 
0231 template<class Buffers>
0232 auto
0233 buffers_prefix_view<Buffers>::
0234 begin() const ->
0235     const_iterator
0236 {
0237     return const_iterator{
0238         *this, std::false_type{}};
0239 }
0240 
0241 template<class Buffers>
0242 auto
0243 buffers_prefix_view<Buffers>::
0244 end() const ->
0245     const_iterator
0246 {
0247     return const_iterator{
0248         *this, std::true_type{}};
0249 }
0250 
0251 //------------------------------------------------------------------------------
0252 
0253 template<>
0254 class buffers_prefix_view<net::const_buffer>
0255     : public net::const_buffer
0256 {
0257 public:
0258     using net::const_buffer::const_buffer;
0259     buffers_prefix_view(buffers_prefix_view const&) = default;
0260     buffers_prefix_view& operator=(buffers_prefix_view const&) = default;
0261 
0262     buffers_prefix_view(
0263         std::size_t size,
0264         net::const_buffer buffer)
0265         : net::const_buffer(
0266             buffer.data(),
0267             std::min<std::size_t>(size, buffer.size())
0268         #if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING)
0269             , buffer.get_debug_check()
0270         #endif
0271             )
0272     {
0273     }
0274 
0275     template<class... Args>
0276     buffers_prefix_view(
0277         std::size_t size,
0278         boost::in_place_init_t,
0279         Args&&... args)
0280         : buffers_prefix_view(size,
0281             net::const_buffer(
0282                 std::forward<Args>(args)...))
0283     {
0284     }
0285 };
0286 
0287 //------------------------------------------------------------------------------
0288 
0289 template<>
0290 class buffers_prefix_view<net::mutable_buffer>
0291     : public net::mutable_buffer
0292 {
0293 public:
0294     using net::mutable_buffer::mutable_buffer;
0295     buffers_prefix_view(buffers_prefix_view const&) = default;
0296     buffers_prefix_view& operator=(buffers_prefix_view const&) = default;
0297 
0298     buffers_prefix_view(
0299         std::size_t size,
0300         net::mutable_buffer buffer)
0301         : net::mutable_buffer(
0302             buffer.data(),
0303             std::min<std::size_t>(size, buffer.size())
0304         #if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING)
0305             , buffer.get_debug_check()
0306         #endif
0307             )
0308     {
0309     }
0310 
0311     template<class... Args>
0312     buffers_prefix_view(
0313         std::size_t size,
0314         boost::in_place_init_t,
0315         Args&&... args)
0316         : buffers_prefix_view(size,
0317             net::mutable_buffer(
0318                 std::forward<Args>(args)...))
0319     {
0320     }
0321 };
0322 
0323 } // beast
0324 } // boost
0325 
0326 #endif