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:
Vinnie Falco
2016-11-08 18:01:07 -05:00
parent 8f535ba74f
commit 6afa6afc98
6 changed files with 60 additions and 69 deletions

View File

@ -4,6 +4,7 @@
* Improvements to code coverage * Improvements to code coverage
* Use boost::lexical_cast instead of std::to_string * Use boost::lexical_cast instead of std::to_string
* Fix prepare_buffers value_type * Fix prepare_buffers value_type
* Fix consuming_buffers value_type
HTTP HTTP
@ -21,6 +22,7 @@ API Changes:
* Refactor message and message_headers declarations * Refactor message and message_headers declarations
* prepared_buffers is private * prepared_buffers is private
* consume_buffers is removed
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------

View File

@ -177,7 +177,6 @@
<simplelist type="vert" columns="1"> <simplelist type="vert" columns="1">
<member><link linkend="beast.ref.bind_handler">bind_handler</link></member> <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.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_buffer">prepare_buffer</link></member>
<member><link linkend="beast.ref.prepare_buffers">prepare_buffers</link></member> <member><link linkend="beast.ref.prepare_buffers">prepare_buffers</link></member>
<member><link linkend="beast.ref.to_string">to_string</link></member> <member><link linkend="beast.ref.to_string">to_string</link></member>

View File

@ -37,20 +37,12 @@ namespace beast {
consumable `ConstBufferSequence`. Violations of buffer const safety consumable `ConstBufferSequence`. Violations of buffer const safety
are not permitted, and will result in a compile error. are not permitted, and will result in a compile error.
*/ */
template<class BufferSequence, template<class BufferSequence>
class ValueType = typename BufferSequence::value_type>
class consuming_buffers class consuming_buffers
{ {
using iter_type = using iter_type =
typename BufferSequence::const_iterator; 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_; BufferSequence bs_;
iter_type begin_; iter_type begin_;
std::size_t skip_ = 0; std::size_t skip_ = 0;
@ -65,7 +57,12 @@ class consuming_buffers
public: public:
/// The type for each element in the list of buffers. /// 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 #if GENERATING_DOCS
/// A bidirectional iterator type that may be used to read elements. /// A bidirectional iterator type that may be used to read elements.
@ -100,7 +97,7 @@ public:
const_iterator const_iterator
begin() const; begin() const;
/// Get a bidirectional iterator for one past the last element. /// Get a bidirectional iterator to one past the last element.
const_iterator const_iterator
end() const; end() const;
@ -114,25 +111,6 @@ public:
consume(std::size_t n); 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 } // beast
#include <beast/core/impl/consuming_buffers.ipp> #include <beast/core/impl/consuming_buffers.ipp>

View File

@ -18,10 +18,10 @@
namespace beast { namespace beast {
template<class BufferSequence, class ValueType> template<class BufferSequence>
class consuming_buffers<BufferSequence, ValueType>::const_iterator class consuming_buffers<BufferSequence>::const_iterator
{ {
friend class consuming_buffers<BufferSequence, ValueType>; friend class consuming_buffers<BufferSequence>;
using iter_type = using iter_type =
typename BufferSequence::const_iterator; typename BufferSequence::const_iterator;
@ -30,8 +30,12 @@ class consuming_buffers<BufferSequence, ValueType>::const_iterator
consuming_buffers const* b_ = nullptr; consuming_buffers const* b_ = nullptr;
public: public:
using value_type = using value_type = typename std::conditional<
typename std::iterator_traits<iter_type>::value_type; 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 pointer = value_type const*;
using reference = value_type; using reference = value_type;
using difference_type = std::ptrdiff_t; using difference_type = std::ptrdiff_t;
@ -59,8 +63,9 @@ public:
reference reference
operator*() const operator*() const
{ {
return it_ == b_->begin_ ? return it_ == b_->begin_
*it_ + b_->skip_ : *it_; ? value_type{*it_} + b_->skip_
: *it_;
} }
pointer pointer
@ -105,8 +110,8 @@ private:
} }
}; };
template<class BufferSequence, class ValueType> template<class BufferSequence>
consuming_buffers<BufferSequence, ValueType>:: consuming_buffers<BufferSequence>::
consuming_buffers(consuming_buffers&& other) consuming_buffers(consuming_buffers&& other)
: consuming_buffers(std::move(other), : consuming_buffers(std::move(other),
std::distance<iter_type>( std::distance<iter_type>(
@ -114,8 +119,8 @@ consuming_buffers(consuming_buffers&& other)
{ {
} }
template<class BufferSequence, class ValueType> template<class BufferSequence>
consuming_buffers<BufferSequence, ValueType>:: consuming_buffers<BufferSequence>::
consuming_buffers(consuming_buffers const& other) consuming_buffers(consuming_buffers const& other)
: consuming_buffers(other, : consuming_buffers(other,
std::distance<iter_type>( std::distance<iter_type>(
@ -123,9 +128,9 @@ consuming_buffers(consuming_buffers const& other)
{ {
} }
template<class BufferSequence, class ValueType> template<class BufferSequence>
auto auto
consuming_buffers<BufferSequence, ValueType>:: consuming_buffers<BufferSequence>::
operator=(consuming_buffers&& other) -> operator=(consuming_buffers&& other) ->
consuming_buffers& consuming_buffers&
{ {
@ -137,9 +142,9 @@ operator=(consuming_buffers&& other) ->
return *this; return *this;
} }
template<class BufferSequence, class ValueType> template<class BufferSequence>
auto auto
consuming_buffers<BufferSequence, ValueType>:: consuming_buffers<BufferSequence>::
operator=(consuming_buffers const& other) -> operator=(consuming_buffers const& other) ->
consuming_buffers& consuming_buffers&
{ {
@ -151,35 +156,41 @@ operator=(consuming_buffers const& other) ->
return *this; return *this;
} }
template<class BufferSequence, class ValueType> template<class BufferSequence>
consuming_buffers<BufferSequence, ValueType>:: consuming_buffers<BufferSequence>::
consuming_buffers(BufferSequence const& bs) consuming_buffers(BufferSequence const& bs)
: bs_(bs) : bs_(bs)
, begin_(bs_.begin()) , begin_(bs_.begin())
{ {
static_assert(is_BufferSequence<BufferSequence, ValueType>::value, static_assert(
"BufferSequence requirements not met"); is_BufferSequence<BufferSequence, value_type>::value,
"BufferSequence requirements not met");
} }
template<class BufferSequence, class ValueType> template<class BufferSequence>
inline
auto auto
consuming_buffers<BufferSequence, ValueType>::begin() const -> consuming_buffers<BufferSequence>::
begin() const ->
const_iterator const_iterator
{ {
return const_iterator{*this, begin_}; return const_iterator{*this, begin_};
} }
template<class BufferSequence, class ValueType> template<class BufferSequence>
inline
auto auto
consuming_buffers<BufferSequence, ValueType>::end() const -> consuming_buffers<BufferSequence>::
end() const ->
const_iterator const_iterator
{ {
return const_iterator{*this, bs_.end()}; return const_iterator{*this, bs_.end()};
} }
template<class BufferSequence, class ValueType> template<class BufferSequence>
void void
consuming_buffers<BufferSequence, ValueType>::consume(std::size_t n) consuming_buffers<BufferSequence>::
consume(std::size_t n)
{ {
using boost::asio::buffer_size; using boost::asio::buffer_size;
for(;n > 0 && begin_ != bs_.end(); ++begin_) 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 } // beast
#endif #endif

View File

@ -19,6 +19,16 @@ namespace beast {
class consuming_buffers_test : public beast::unit_test::suite class consuming_buffers_test : public beast::unit_test::suite
{ {
public: 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> template<class Buffers1, class Buffers2>
static static
bool bool

View File

@ -283,10 +283,10 @@ public:
{ {
static std::size_t constexpr size = 3; static std::size_t constexpr size = 3;
std::size_t n = s.size(); std::size_t n = s.size();
auto cb = consumed_buffers( consuming_buffers<
boost::asio::const_buffers_1( boost::asio::const_buffers_1> cb{
s.data(), n), 0); boost::asio::const_buffers_1(s.data(), n)};
streambuf sb(size); streambuf sb{size};
while(n) while(n)
{ {
auto const amount = (std::min)(n, size); auto const amount = (std::min)(n, size);