File indexing completed on 2025-01-18 09:29:26
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #ifndef BOOST_BEAST_IMPL_BUFFERS_SUFFIX_HPP
0011 #define BOOST_BEAST_IMPL_BUFFERS_SUFFIX_HPP
0012
0013 #include <boost/beast/core/buffer_traits.hpp>
0014 #include <boost/beast/core/buffer_traits.hpp>
0015 #include <boost/type_traits.hpp>
0016 #include <algorithm>
0017 #include <cstdint>
0018 #include <iterator>
0019 #include <type_traits>
0020 #include <utility>
0021
0022 namespace boost {
0023 namespace beast {
0024
0025 template<class Buffers>
0026 class buffers_suffix<Buffers>::const_iterator
0027 {
0028 friend class buffers_suffix<Buffers>;
0029
0030 using iter_type = buffers_iterator_type<Buffers>;
0031
0032 iter_type it_{};
0033 buffers_suffix const* b_ = nullptr;
0034
0035 public:
0036 #if BOOST_WORKAROUND(BOOST_MSVC, < 1910)
0037 using value_type = typename std::conditional<
0038 boost::is_convertible<typename
0039 std::iterator_traits<iter_type>::value_type,
0040 net::mutable_buffer>::value,
0041 net::mutable_buffer,
0042 net::const_buffer>::type;
0043 #else
0044 using value_type = buffers_type<Buffers>;
0045 #endif
0046 using pointer = value_type const*;
0047 using reference = value_type;
0048 using difference_type = std::ptrdiff_t;
0049 using iterator_category =
0050 std::bidirectional_iterator_tag;
0051
0052 const_iterator() = default;
0053 const_iterator(
0054 const_iterator const& other) = default;
0055 const_iterator& operator=(
0056 const_iterator const& other) = default;
0057
0058 bool
0059 operator==(const_iterator const& other) const
0060 {
0061 return b_ == other.b_ && it_ == other.it_;
0062 }
0063
0064 bool
0065 operator!=(const_iterator const& other) const
0066 {
0067 return !(*this == other);
0068 }
0069
0070 reference
0071 operator*() const
0072 {
0073 if(it_ == b_->begin_)
0074 return value_type(*it_) + b_->skip_;
0075 return value_type(*it_);
0076 }
0077
0078 pointer
0079 operator->() const = delete;
0080
0081 const_iterator&
0082 operator++()
0083 {
0084 ++it_;
0085 return *this;
0086 }
0087
0088 const_iterator
0089 operator++(int)
0090 {
0091 auto temp = *this;
0092 ++(*this);
0093 return temp;
0094 }
0095
0096 const_iterator&
0097 operator--()
0098 {
0099 --it_;
0100 return *this;
0101 }
0102
0103 const_iterator
0104 operator--(int)
0105 {
0106 auto temp = *this;
0107 --(*this);
0108 return temp;
0109 }
0110
0111 private:
0112 const_iterator(
0113 buffers_suffix const& b,
0114 iter_type it)
0115 : it_(it)
0116 , b_(&b)
0117 {
0118 }
0119 };
0120
0121
0122
0123 template<class Buffers>
0124 buffers_suffix<Buffers>::
0125 buffers_suffix()
0126 : begin_(net::buffer_sequence_begin(bs_))
0127 {
0128 }
0129
0130 template<class Buffers>
0131 buffers_suffix<Buffers>::
0132 buffers_suffix(buffers_suffix const& other)
0133 : buffers_suffix(other,
0134 std::distance<iter_type>(
0135 net::buffer_sequence_begin(
0136 other.bs_), other.begin_))
0137 {
0138 }
0139
0140 template<class Buffers>
0141 buffers_suffix<Buffers>::
0142 buffers_suffix(Buffers const& bs)
0143 : bs_(bs)
0144 , begin_(net::buffer_sequence_begin(bs_))
0145 {
0146 static_assert(
0147 net::is_const_buffer_sequence<Buffers>::value ||
0148 net::is_mutable_buffer_sequence<Buffers>::value,
0149 "BufferSequence type requirements not met");
0150 }
0151
0152 template<class Buffers>
0153 template<class... Args>
0154 buffers_suffix<Buffers>::
0155 buffers_suffix(boost::in_place_init_t, Args&&... args)
0156 : bs_(std::forward<Args>(args)...)
0157 , begin_(net::buffer_sequence_begin(bs_))
0158 {
0159 static_assert(sizeof...(Args) > 0,
0160 "Missing constructor arguments");
0161 static_assert(
0162 std::is_constructible<Buffers, Args...>::value,
0163 "Buffers not constructible from arguments");
0164 }
0165
0166 template<class Buffers>
0167 auto
0168 buffers_suffix<Buffers>::
0169 operator=(buffers_suffix const& other) ->
0170 buffers_suffix&
0171 {
0172 auto const dist = std::distance<iter_type>(
0173 net::buffer_sequence_begin(other.bs_),
0174 other.begin_);
0175 bs_ = other.bs_;
0176 begin_ = std::next(
0177 net::buffer_sequence_begin(bs_), dist);
0178 skip_ = other.skip_;
0179 return *this;
0180 }
0181
0182 template<class Buffers>
0183 auto
0184 buffers_suffix<Buffers>::
0185 begin() const ->
0186 const_iterator
0187 {
0188 return const_iterator{*this, begin_};
0189 }
0190
0191 template<class Buffers>
0192 auto
0193 buffers_suffix<Buffers>::
0194 end() const ->
0195 const_iterator
0196 {
0197 return const_iterator{*this,
0198 net::buffer_sequence_end(bs_)};
0199 }
0200
0201 template<class Buffers>
0202 void
0203 buffers_suffix<Buffers>::
0204 consume(std::size_t amount)
0205 {
0206 auto const end =
0207 net::buffer_sequence_end(bs_);
0208 for(;amount > 0 && begin_ != end; ++begin_)
0209 {
0210 auto const len =
0211 buffer_bytes(*begin_) - skip_;
0212 if(amount < len)
0213 {
0214 skip_ += amount;
0215 break;
0216 }
0217 amount -= len;
0218 skip_ = 0;
0219 }
0220 }
0221
0222 }
0223 }
0224
0225 #endif