mirror of
https://github.com/boostorg/beast.git
synced 2025-07-29 20:37:31 +02:00
Fix consuming_buffers value_type (API Change):
This fixes a bug where instantiations of consuming_buffers with buffer sequence types whose value_type is not const_buffer or mutable_buffer can cause compilation errors. The function consumed_buffers is removed.
This commit is contained in:
@ -4,6 +4,7 @@
|
||||
* Improvements to code coverage
|
||||
* Use boost::lexical_cast instead of std::to_string
|
||||
* Fix prepare_buffers value_type
|
||||
* Fix consuming_buffers value_type
|
||||
|
||||
HTTP
|
||||
|
||||
@ -21,6 +22,7 @@ API Changes:
|
||||
|
||||
* Refactor message and message_headers declarations
|
||||
* prepared_buffers is private
|
||||
* consume_buffers is removed
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
|
@ -177,7 +177,6 @@
|
||||
<simplelist type="vert" columns="1">
|
||||
<member><link linkend="beast.ref.bind_handler">bind_handler</link></member>
|
||||
<member><link linkend="beast.ref.buffer_cat">buffer_cat</link></member>
|
||||
<member><link linkend="beast.ref.consumed_buffers">consumed_buffers</link></member>
|
||||
<member><link linkend="beast.ref.prepare_buffer">prepare_buffer</link></member>
|
||||
<member><link linkend="beast.ref.prepare_buffers">prepare_buffers</link></member>
|
||||
<member><link linkend="beast.ref.to_string">to_string</link></member>
|
||||
|
@ -37,20 +37,12 @@ namespace beast {
|
||||
consumable `ConstBufferSequence`. Violations of buffer const safety
|
||||
are not permitted, and will result in a compile error.
|
||||
*/
|
||||
template<class BufferSequence,
|
||||
class ValueType = typename BufferSequence::value_type>
|
||||
template<class BufferSequence>
|
||||
class consuming_buffers
|
||||
{
|
||||
using iter_type =
|
||||
typename BufferSequence::const_iterator;
|
||||
|
||||
static_assert(is_BufferSequence<BufferSequence, ValueType>::value,
|
||||
"BufferSequence requirements not met");
|
||||
|
||||
static_assert(std::is_constructible<ValueType,
|
||||
typename std::iterator_traits<iter_type>::value_type>::value,
|
||||
"ValueType requirements not met");
|
||||
|
||||
BufferSequence bs_;
|
||||
iter_type begin_;
|
||||
std::size_t skip_ = 0;
|
||||
@ -65,7 +57,12 @@ class consuming_buffers
|
||||
|
||||
public:
|
||||
/// The type for each element in the list of buffers.
|
||||
using value_type = ValueType;
|
||||
using value_type = typename std::conditional<
|
||||
std::is_convertible<typename
|
||||
std::iterator_traits<iter_type>::value_type,
|
||||
boost::asio::mutable_buffer>::value,
|
||||
boost::asio::mutable_buffer,
|
||||
boost::asio::const_buffer>::type;
|
||||
|
||||
#if GENERATING_DOCS
|
||||
/// A bidirectional iterator type that may be used to read elements.
|
||||
@ -100,7 +97,7 @@ public:
|
||||
const_iterator
|
||||
begin() const;
|
||||
|
||||
/// Get a bidirectional iterator for one past the last element.
|
||||
/// Get a bidirectional iterator to one past the last element.
|
||||
const_iterator
|
||||
end() const;
|
||||
|
||||
@ -114,25 +111,6 @@ public:
|
||||
consume(std::size_t n);
|
||||
};
|
||||
|
||||
/** Returns a new, consumed buffer sequence.
|
||||
|
||||
This function returns a new buffer sequence which when iterated,
|
||||
efficiently represents the portion of the original buffer sequence
|
||||
with `n` bytes removed from the beginning.
|
||||
|
||||
Copies will be made of the buffer sequence passed, but ownership
|
||||
of the underlying memory is not transferred.
|
||||
|
||||
@param buffers The buffer sequence to consume.
|
||||
|
||||
@param n The number of bytes to remove from the front. If this is
|
||||
larger than the size of the buffer sequence, an empty buffer sequence
|
||||
is returned.
|
||||
*/
|
||||
template<class BufferSequence>
|
||||
consuming_buffers<BufferSequence, typename BufferSequence::value_type>
|
||||
consumed_buffers(BufferSequence const& buffers, std::size_t n);
|
||||
|
||||
} // beast
|
||||
|
||||
#include <beast/core/impl/consuming_buffers.ipp>
|
||||
|
@ -18,10 +18,10 @@
|
||||
|
||||
namespace beast {
|
||||
|
||||
template<class BufferSequence, class ValueType>
|
||||
class consuming_buffers<BufferSequence, ValueType>::const_iterator
|
||||
template<class BufferSequence>
|
||||
class consuming_buffers<BufferSequence>::const_iterator
|
||||
{
|
||||
friend class consuming_buffers<BufferSequence, ValueType>;
|
||||
friend class consuming_buffers<BufferSequence>;
|
||||
|
||||
using iter_type =
|
||||
typename BufferSequence::const_iterator;
|
||||
@ -30,8 +30,12 @@ class consuming_buffers<BufferSequence, ValueType>::const_iterator
|
||||
consuming_buffers const* b_ = nullptr;
|
||||
|
||||
public:
|
||||
using value_type =
|
||||
typename std::iterator_traits<iter_type>::value_type;
|
||||
using value_type = typename std::conditional<
|
||||
std::is_convertible<typename
|
||||
std::iterator_traits<iter_type>::value_type,
|
||||
boost::asio::mutable_buffer>::value,
|
||||
boost::asio::mutable_buffer,
|
||||
boost::asio::const_buffer>::type;
|
||||
using pointer = value_type const*;
|
||||
using reference = value_type;
|
||||
using difference_type = std::ptrdiff_t;
|
||||
@ -59,8 +63,9 @@ public:
|
||||
reference
|
||||
operator*() const
|
||||
{
|
||||
return it_ == b_->begin_ ?
|
||||
*it_ + b_->skip_ : *it_;
|
||||
return it_ == b_->begin_
|
||||
? value_type{*it_} + b_->skip_
|
||||
: *it_;
|
||||
}
|
||||
|
||||
pointer
|
||||
@ -105,8 +110,8 @@ private:
|
||||
}
|
||||
};
|
||||
|
||||
template<class BufferSequence, class ValueType>
|
||||
consuming_buffers<BufferSequence, ValueType>::
|
||||
template<class BufferSequence>
|
||||
consuming_buffers<BufferSequence>::
|
||||
consuming_buffers(consuming_buffers&& other)
|
||||
: consuming_buffers(std::move(other),
|
||||
std::distance<iter_type>(
|
||||
@ -114,8 +119,8 @@ consuming_buffers(consuming_buffers&& other)
|
||||
{
|
||||
}
|
||||
|
||||
template<class BufferSequence, class ValueType>
|
||||
consuming_buffers<BufferSequence, ValueType>::
|
||||
template<class BufferSequence>
|
||||
consuming_buffers<BufferSequence>::
|
||||
consuming_buffers(consuming_buffers const& other)
|
||||
: consuming_buffers(other,
|
||||
std::distance<iter_type>(
|
||||
@ -123,9 +128,9 @@ consuming_buffers(consuming_buffers const& other)
|
||||
{
|
||||
}
|
||||
|
||||
template<class BufferSequence, class ValueType>
|
||||
template<class BufferSequence>
|
||||
auto
|
||||
consuming_buffers<BufferSequence, ValueType>::
|
||||
consuming_buffers<BufferSequence>::
|
||||
operator=(consuming_buffers&& other) ->
|
||||
consuming_buffers&
|
||||
{
|
||||
@ -137,9 +142,9 @@ operator=(consuming_buffers&& other) ->
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<class BufferSequence, class ValueType>
|
||||
template<class BufferSequence>
|
||||
auto
|
||||
consuming_buffers<BufferSequence, ValueType>::
|
||||
consuming_buffers<BufferSequence>::
|
||||
operator=(consuming_buffers const& other) ->
|
||||
consuming_buffers&
|
||||
{
|
||||
@ -151,35 +156,41 @@ operator=(consuming_buffers const& other) ->
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<class BufferSequence, class ValueType>
|
||||
consuming_buffers<BufferSequence, ValueType>::
|
||||
template<class BufferSequence>
|
||||
consuming_buffers<BufferSequence>::
|
||||
consuming_buffers(BufferSequence const& bs)
|
||||
: bs_(bs)
|
||||
, begin_(bs_.begin())
|
||||
{
|
||||
static_assert(is_BufferSequence<BufferSequence, ValueType>::value,
|
||||
"BufferSequence requirements not met");
|
||||
static_assert(
|
||||
is_BufferSequence<BufferSequence, value_type>::value,
|
||||
"BufferSequence requirements not met");
|
||||
}
|
||||
|
||||
template<class BufferSequence, class ValueType>
|
||||
template<class BufferSequence>
|
||||
inline
|
||||
auto
|
||||
consuming_buffers<BufferSequence, ValueType>::begin() const ->
|
||||
consuming_buffers<BufferSequence>::
|
||||
begin() const ->
|
||||
const_iterator
|
||||
{
|
||||
return const_iterator{*this, begin_};
|
||||
}
|
||||
|
||||
template<class BufferSequence, class ValueType>
|
||||
template<class BufferSequence>
|
||||
inline
|
||||
auto
|
||||
consuming_buffers<BufferSequence, ValueType>::end() const ->
|
||||
consuming_buffers<BufferSequence>::
|
||||
end() const ->
|
||||
const_iterator
|
||||
{
|
||||
return const_iterator{*this, bs_.end()};
|
||||
}
|
||||
|
||||
template<class BufferSequence, class ValueType>
|
||||
template<class BufferSequence>
|
||||
void
|
||||
consuming_buffers<BufferSequence, ValueType>::consume(std::size_t n)
|
||||
consuming_buffers<BufferSequence>::
|
||||
consume(std::size_t n)
|
||||
{
|
||||
using boost::asio::buffer_size;
|
||||
for(;n > 0 && begin_ != bs_.end(); ++begin_)
|
||||
@ -196,15 +207,6 @@ consuming_buffers<BufferSequence, ValueType>::consume(std::size_t n)
|
||||
}
|
||||
}
|
||||
|
||||
template<class BufferSequence>
|
||||
consuming_buffers<BufferSequence, typename BufferSequence::value_type>
|
||||
consumed_buffers(BufferSequence const& bs, std::size_t n)
|
||||
{
|
||||
consuming_buffers<BufferSequence> cb(bs);
|
||||
cb.consume(n);
|
||||
return cb;
|
||||
}
|
||||
|
||||
} // beast
|
||||
|
||||
#endif
|
||||
|
@ -19,6 +19,16 @@ namespace beast {
|
||||
class consuming_buffers_test : public beast::unit_test::suite
|
||||
{
|
||||
public:
|
||||
template<class BufferSequence>
|
||||
static
|
||||
consuming_buffers<BufferSequence>
|
||||
consumed_buffers(BufferSequence const& bs, std::size_t n)
|
||||
{
|
||||
consuming_buffers<BufferSequence> cb(bs);
|
||||
cb.consume(n);
|
||||
return cb;
|
||||
}
|
||||
|
||||
template<class Buffers1, class Buffers2>
|
||||
static
|
||||
bool
|
||||
|
@ -283,10 +283,10 @@ public:
|
||||
{
|
||||
static std::size_t constexpr size = 3;
|
||||
std::size_t n = s.size();
|
||||
auto cb = consumed_buffers(
|
||||
boost::asio::const_buffers_1(
|
||||
s.data(), n), 0);
|
||||
streambuf sb(size);
|
||||
consuming_buffers<
|
||||
boost::asio::const_buffers_1> cb{
|
||||
boost::asio::const_buffers_1(s.data(), n)};
|
||||
streambuf sb{size};
|
||||
while(n)
|
||||
{
|
||||
auto const amount = (std::min)(n, size);
|
||||
|
Reference in New Issue
Block a user