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
* 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
--------------------------------------------------------------------------------

View File

@ -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>

View File

@ -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>

View File

@ -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

View File

@ -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

View File

@ -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);