Fix prepare_buffers value_type:

This fixes a bug where calling prepare_buffers on a buffer
sequence whose value_type is not const_buffer or mutable_buffer
causes compilation errors.

The documentation is also tidied up.
This commit is contained in:
Vinnie Falco
2016-11-08 17:23:31 -05:00
parent aa8e7432c2
commit 08d8a2ae35
3 changed files with 67 additions and 38 deletions

View File

@@ -3,6 +3,7 @@
* Boost library min/max guidance * Boost library min/max guidance
* 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
HTTP HTTP

View File

@@ -50,8 +50,12 @@ class prepared_buffers<BufferSequence>::const_iterator
typename BufferSequence::const_iterator it_; typename BufferSequence::const_iterator it_;
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;

View File

@@ -13,15 +13,24 @@
#include <cstdint> #include <cstdint>
#include <iterator> #include <iterator>
#include <stdexcept> #include <stdexcept>
#include <type_traits>
#include <utility> #include <utility>
namespace beast { namespace beast {
/** Get a trimmed const buffer. /** Return a shortened buffer.
The new buffer starts at the beginning of the passed The returned buffer points to the same memory as the
buffer. Ownership of the underlying memory is not passed buffer, but with a size that is equal to or less
transferred. than the size of the original buffer.
@param n The size of the returned buffer.
@param buffer The buffer to shorten. Ownership of the
underlying memory is not transferred.
@return A new buffer that points to the first `n` bytes
of the original buffer.
*/ */
inline inline
boost::asio::const_buffer boost::asio::const_buffer
@@ -34,11 +43,19 @@ prepare_buffer(std::size_t n,
(std::min)(n, buffer_size(buffer)) }; (std::min)(n, buffer_size(buffer)) };
} }
/** Get a trimmed mutable buffer. /** Return a shortened buffer.
The new buffer starts at the beginning of the passed The returned buffer points to the same memory as the
buffer. Ownership of the underlying memory is not passed buffer, but with a size that is equal to or less
transferred. than the size of the original buffer.
@param n The size of the returned buffer.
@param buffer The buffer to shorten. Ownership of the
underlying memory is not transferred.
@return A new buffer that points to the first `n` bytes
of the original buffer.
*/ */
inline inline
boost::asio::mutable_buffer boost::asio::mutable_buffer
@@ -51,13 +68,13 @@ prepare_buffer(std::size_t n,
(std::min)(n, buffer_size(buffer)) }; (std::min)(n, buffer_size(buffer)) };
} }
/** Wrapper to produce a trimmed buffer sequence. /** A buffer sequence adapter that shortens the sequence size.
This wraps a buffer sequence to efficiently present a shorter The class adapts a buffer sequence to efficiently represent
subset of the original list of buffers starting with the first a shorter subset of the original list of buffers starting
byte of the original sequence. with the first byte of the original sequence.
@tparam BufferSequence The buffer sequence to wrap. @tparam BufferSequence The buffer sequence to adapt.
*/ */
template<class BufferSequence> template<class BufferSequence>
class prepared_buffers class prepared_buffers
@@ -80,10 +97,17 @@ class prepared_buffers
{ {
} }
void
setup(std::size_t n);
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 = 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;
#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.
@@ -106,14 +130,16 @@ public:
/// Copy assignment. /// Copy assignment.
prepared_buffers& operator=(prepared_buffers const&); prepared_buffers& operator=(prepared_buffers const&);
/** Construct a wrapped buffer sequence. /** Construct a shortened buffer sequence.
@param n The maximum number of bytes in the wrapped sequence. @param n The maximum number of bytes in the wrapped
If this is larger than the size of buffers, the wrapped sequence. If this is larger than the size of passed,
sequence will represent the entire input sequence. buffers, the resulting sequence will represent the
entire input sequence.
@param buffers The buffer sequence to wrap. A copy of the sequence @param buffers The buffer sequence to adapt. A copy of
will be made, but ownership of the underlying memory is not transferred. the sequence will be made, but ownership of the underlying
memory is not transferred.
*/ */
prepared_buffers(std::size_t n, BufferSequence const& buffers); prepared_buffers(std::size_t n, BufferSequence const& buffers);
@@ -121,30 +147,28 @@ 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;
private:
void
setup(std::size_t n);
}; };
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
/** Return a trimmed, wrapped buffer sequence. /** Return a shortened buffer sequence.
This function returns a new buffer sequence which wraps the provided This function returns a new buffer sequence which adapts the
buffer sequence and efficiently presents a shorter subset of the passed buffer sequence and efficiently presents a shorter subset
original list of buffers starting with the first byte of the original of the original list of buffers starting with the first byte of
sequence. the original sequence.
@param n The maximum number of bytes in the wrapped sequence. If this @param n The maximum number of bytes in the wrapped
is larger than the size of buffers, the wrapped sequence will represent sequence. If this is larger than the size of passed,
the entire input sequence. buffers, the resulting sequence will represent the
entire input sequence.
@param buffers The buffer sequence to wrap. A copy of the sequence @param buffers The buffer sequence to adapt. A copy of
will be made, but ownership of the underlying memory is not transferred. the sequence will be made, but ownership of the underlying
memory is not transferred.
*/ */
template<class BufferSequence> template<class BufferSequence>
prepared_buffers<BufferSequence> prepared_buffers<BufferSequence>