diff --git a/CHANGELOG.md b/CHANGELOG.md index 9855e021..8a4e9f6c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ Version 80: * Javadoc tidying * Add basic_dynamic_body.hpp +* Shrink buffer_prefix_view -------------------------------------------------------------------------------- diff --git a/include/beast/core/buffer_prefix.hpp b/include/beast/core/buffer_prefix.hpp index 54751e51..859a5c10 100644 --- a/include/beast/core/buffer_prefix.hpp +++ b/include/beast/core/buffer_prefix.hpp @@ -31,25 +31,24 @@ class buffer_prefix_view using buffers_type = typename std::decay::type; - using iter_type = typename buffers_type::const_iterator; + using iter_type = + typename buffers_type::const_iterator; BufferSequence bs_; - iter_type back_; - iter_type end_; std::size_t size_; + iter_type end_; template - buffer_prefix_view(Deduced&& other, - std::size_t nback, std::size_t nend) + buffer_prefix_view( + Deduced&& other, std::size_t dist) : bs_(std::forward(other).bs_) - , back_(std::next(bs_.begin(), nback)) - , end_(std::next(bs_.begin(), nend)) , size_(other.size_) + , end_(std::next(bs_.begin(), dist)) { } void - setup(std::size_t n); + setup(std::size_t size); public: /// The type for each element in the list of buffers. @@ -92,11 +91,13 @@ public: the sequence will be made, but ownership of the underlying memory is not transferred. */ - buffer_prefix_view(std::size_t n, BufferSequence const& buffers); + buffer_prefix_view( + std::size_t size, + BufferSequence const& buffers); /** Construct a buffer sequence prefix in-place. - @param n The maximum number of bytes in the prefix. + @param size The maximum number of bytes in the prefix. If this is larger than the size of passed, buffers, the resulting sequence will represent the entire input sequence. @@ -104,8 +105,10 @@ public: @param args Arguments forwarded to the contained buffers constructor. */ template - buffer_prefix_view(std::size_t n, - boost::in_place_init_t, Args&&... args); + buffer_prefix_view( + std::size_t size, + boost::in_place_init_t, + Args&&... args); /// Get a bidirectional iterator to the first element. const_iterator @@ -122,23 +125,23 @@ public: passed buffer, but with a size that is equal to or less than the size of the original buffer. - @param n The size of the returned buffer. + @param size The size of the returned buffer. @param buffer The buffer to shorten. The underlying memory is not modified. - @return A new buffer that points to the first `n` bytes - of the original buffer. + @return A new buffer that points to the first `size` + bytes of the original buffer. */ inline boost::asio::const_buffer -buffer_prefix(std::size_t n, +buffer_prefix(std::size_t size, boost::asio::const_buffer buffer) { using boost::asio::buffer_cast; using boost::asio::buffer_size; return { buffer_cast(buffer), - (std::min)(n, buffer_size(buffer)) }; + (std::min)(size, buffer_size(buffer)) }; } /** Returns a prefix of a mutable buffer. @@ -147,23 +150,23 @@ buffer_prefix(std::size_t n, passed buffer, but with a size that is equal to or less than the size of the original buffer. - @param n The size of the returned buffer. + @param size The size of the returned buffer. @param buffer The buffer to shorten. The underlying memory is not modified. - @return A new buffer that points to the first `n` bytes + @return A new buffer that points to the first `size` bytes of the original buffer. */ inline boost::asio::mutable_buffer -buffer_prefix(std::size_t n, +buffer_prefix(std::size_t size, boost::asio::mutable_buffer buffer) { using boost::asio::buffer_cast; using boost::asio::buffer_size; - return { buffer_cast(buffer), - (std::min)(n, buffer_size(buffer)) }; + return {buffer_cast(buffer), + (std::min)(size, buffer_size(buffer))}; } /** Returns a prefix of a buffer sequence. @@ -172,7 +175,7 @@ buffer_prefix(std::size_t n, presents a shorter subset of the original list of buffers starting with the first byte of the original sequence. - @param n The maximum number of bytes in the wrapped + @param size The maximum number of bytes in the wrapped sequence. If this is larger than the size of passed, buffers, the resulting sequence will represent the entire input sequence. @@ -188,17 +191,19 @@ buffer_prefix_view #else inline typename std::enable_if< - ! std::is_same::value && - ! std::is_same::value, - buffer_prefix_view>::type + ! std::is_same::value && + ! std::is_same::value, + buffer_prefix_view>::type #endif -buffer_prefix(std::size_t n, BufferSequence const& buffers) +buffer_prefix(std::size_t size, BufferSequence const& buffers) { static_assert( is_const_buffer_sequence::value || is_mutable_buffer_sequence::value, "BufferSequence requirements not met"); - return buffer_prefix_view(n, buffers); + return buffer_prefix_view(size, buffers); } } // beast diff --git a/include/beast/core/impl/buffer_prefix.ipp b/include/beast/core/impl/buffer_prefix.ipp index b3aa5578..ef6f5347 100644 --- a/include/beast/core/impl/buffer_prefix.ipp +++ b/include/beast/core/impl/buffer_prefix.ipp @@ -21,24 +21,24 @@ namespace detail { inline boost::asio::const_buffer -buffer_prefix(std::size_t n, +buffer_prefix(std::size_t size, boost::asio::const_buffer buffer) { using boost::asio::buffer_cast; using boost::asio::buffer_size; - return { buffer_cast(buffer), - (std::min)(n, buffer_size(buffer)) }; + return {buffer_cast(buffer), + (std::min)(size, buffer_size(buffer))}; } inline boost::asio::mutable_buffer -buffer_prefix(std::size_t n, +buffer_prefix(std::size_t size, boost::asio::mutable_buffer buffer) { using boost::asio::buffer_cast; using boost::asio::buffer_size; - return { buffer_cast(buffer), - (std::min)(n, buffer_size(buffer)) }; + return {buffer_cast(buffer), + (std::min)(size, buffer_size(buffer))}; } } // detail @@ -49,6 +49,7 @@ class buffer_prefix_view::const_iterator friend class buffer_prefix_view; buffer_prefix_view const* b_ = nullptr; + std::size_t remain_; iter_type it_; public: @@ -65,10 +66,10 @@ public: std::bidirectional_iterator_tag; const_iterator() = default; - const_iterator(const_iterator&& other); - const_iterator(const_iterator const& other); - const_iterator& operator=(const_iterator&& other); - const_iterator& operator=(const_iterator const& other); + const_iterator(const_iterator&& other) = default; + const_iterator(const_iterator const& other) = default; + const_iterator& operator=(const_iterator&& other) = default; + const_iterator& operator=(const_iterator const& other) = default; bool operator==(const_iterator const& other) const @@ -85,9 +86,7 @@ public: reference operator*() const { - if(it_ == b_->back_) - return detail::buffer_prefix(b_->size_, *it_); - return *it_; + return detail::buffer_prefix(remain_, *it_); } pointer @@ -96,7 +95,7 @@ public: const_iterator& operator++() { - ++it_; + remain_ -= boost::asio::buffer_size(*it_++); return *this; } @@ -104,14 +103,14 @@ public: operator++(int) { auto temp = *this; - ++(*this); + remain_ -= boost::asio::buffer_size(*it_++); return temp; } const_iterator& operator--() { - --it_; + remain_ += boost::asio::buffer_size(*--it_); return *this; } @@ -119,15 +118,24 @@ public: operator--(int) { auto temp = *this; - --(*this); + remain_ += boost::asio::buffer_size(*--it_); return temp; } private: const_iterator(buffer_prefix_view const& b, - bool at_end) + std::true_type) : b_(&b) - , it_(at_end ? b.end_ : b.bs_.begin()) + , remain_(0) + , it_(b_->end_) + { + } + + const_iterator(buffer_prefix_view const& b, + std::false_type) + : b_(&b) + , remain_(b_->size_) + , it_(b_->bs_.begin()) { } }; @@ -135,74 +143,31 @@ private: template void buffer_prefix_view:: -setup(std::size_t n) +setup(std::size_t size) { - for(end_ = bs_.begin(); end_ != bs_.end(); ++end_) + size_ = 0; + end_ = bs_.begin(); + auto const last = bs_.end(); + while(end_ != last) { auto const len = - boost::asio::buffer_size(*end_); - if(n <= len) + boost::asio::buffer_size(*end_++); + if(len >= size) { - size_ = n; - back_ = end_++; - return; + size_ += size; + break; } - n -= len; + size -= len; + size_ += len; } - size_ = 0; - back_ = end_; -} - -template -buffer_prefix_view:: -const_iterator:: -const_iterator(const_iterator&& other) - : b_(other.b_) - , it_(std::move(other.it_)) -{ -} - -template -buffer_prefix_view:: -const_iterator:: -const_iterator(const_iterator const& other) - : b_(other.b_) - , it_(other.it_) -{ -} - -template -auto -buffer_prefix_view:: -const_iterator:: -operator=(const_iterator&& other) -> - const_iterator& -{ - b_ = other.b_; - it_ = std::move(other.it_); - return *this; -} - -template -auto -buffer_prefix_view:: -const_iterator:: -operator=(const_iterator const& other) -> - const_iterator& -{ - if(&other == this) - return *this; - b_ = other.b_; - it_ = other.it_; - return *this; } template buffer_prefix_view:: buffer_prefix_view(buffer_prefix_view&& other) : buffer_prefix_view(std::move(other), - std::distance(other.bs_.begin(), other.back_), - std::distance(other.bs_.begin(), other.end_)) + std::distance( + other.bs_.begin(), other.end_)) { } @@ -210,8 +175,8 @@ template buffer_prefix_view:: buffer_prefix_view(buffer_prefix_view const& other) : buffer_prefix_view(other, - std::distance(other.bs_.begin(), other.back_), - std::distance(other.bs_.begin(), other.end_)) + std::distance( + other.bs_.begin(), other.end_)) { } @@ -221,14 +186,11 @@ buffer_prefix_view:: operator=(buffer_prefix_view&& other) -> buffer_prefix_view& { - auto const nback = std::distance( - other.bs_.begin(), other.back_); - auto const nend = std::distance( + auto const dist = std::distance( other.bs_.begin(), other.end_); bs_ = std::move(other.bs_); - back_ = std::next(bs_.begin(), nback); - end_ = std::next(bs_.begin(), nend); size_ = other.size_; + end_ = std::next(bs_.begin(), dist); return *this; } @@ -238,33 +200,31 @@ buffer_prefix_view:: operator=(buffer_prefix_view const& other) -> buffer_prefix_view& { - auto const nback = std::distance( - other.bs_.begin(), other.back_); - auto const nend = std::distance( + auto const dist = std::distance( other.bs_.begin(), other.end_); bs_ = other.bs_; - back_ = std::next(bs_.begin(), nback); - end_ = std::next(bs_.begin(), nend); size_ = other.size_; + end_ = std::next(bs_.begin(), dist); return *this; } template buffer_prefix_view:: -buffer_prefix_view(std::size_t n, BufferSequence const& bs) +buffer_prefix_view(std::size_t size, + BufferSequence const& bs) : bs_(bs) { - setup(n); + setup(size); } template template buffer_prefix_view:: -buffer_prefix_view(std::size_t n, +buffer_prefix_view(std::size_t size, boost::in_place_init_t, Args&&... args) : bs_(std::forward(args)...) { - setup(n); + setup(size); } template @@ -273,7 +233,7 @@ auto buffer_prefix_view::begin() const -> const_iterator { - return const_iterator{*this, false}; + return const_iterator{*this, std::false_type{}}; } template @@ -282,7 +242,7 @@ auto buffer_prefix_view::end() const -> const_iterator { - return const_iterator{*this, true}; + return const_iterator{*this, std::true_type{}}; } } // beast diff --git a/test/core/buffer_prefix.cpp b/test/core/buffer_prefix.cpp index 4da8687b..9ae2ceb2 100644 --- a/test/core/buffer_prefix.cpp +++ b/test/core/buffer_prefix.cpp @@ -172,15 +172,6 @@ public: BEAST_EXPECT(bsize2(pb) == 2); BEAST_EXPECT(bsize3(pb) == 2); BEAST_EXPECT(bsize4(pb) == 2); - std::size_t n = 0; - for(auto it = pb.end(); it != pb.begin(); --it) - { - decltype(pb)::const_iterator it2(std::move(it)); - BEAST_EXPECT(buffer_size(*it2) == 1); - it = std::move(it2); - ++n; - } - BEAST_EXPECT(n == 2); } void run() override