mirror of
https://github.com/boostorg/beast.git
synced 2025-08-02 14:24:31 +02:00
Tidy up buffers_prefix and tests
This commit is contained in:
@@ -27,35 +27,27 @@ namespace beast {
|
|||||||
a shorter subset of the original list of buffers starting
|
a shorter subset of the original list of buffers starting
|
||||||
with the first byte of the original sequence.
|
with the first byte of the original sequence.
|
||||||
|
|
||||||
@tparam BufferSequence The buffer sequence to adapt.
|
@tparam ConstBufferSequence The buffer sequence to adapt.
|
||||||
*/
|
*/
|
||||||
template<class BufferSequence>
|
template<class ConstBufferSequence>
|
||||||
class buffers_prefix_view
|
class buffers_prefix_view
|
||||||
{
|
{
|
||||||
using buffers_type = typename
|
|
||||||
std::decay<BufferSequence>::type;
|
|
||||||
|
|
||||||
using iter_type = typename
|
using iter_type = typename
|
||||||
detail::buffer_sequence_iterator<buffers_type>::type;
|
detail::buffer_sequence_iterator<
|
||||||
|
ConstBufferSequence>::type;
|
||||||
|
|
||||||
BufferSequence bs_;
|
ConstBufferSequence bs_;
|
||||||
std::size_t size_;
|
std::size_t size_;
|
||||||
std::size_t remain_;
|
std::size_t remain_;
|
||||||
iter_type end_;
|
iter_type end_;
|
||||||
|
|
||||||
template<class Deduced>
|
|
||||||
buffers_prefix_view(
|
|
||||||
Deduced&& other, std::size_t dist)
|
|
||||||
: bs_(std::forward<Deduced>(other).bs_)
|
|
||||||
, size_(other.size_)
|
|
||||||
, remain_(other.remain_)
|
|
||||||
, end_(std::next(bs_.begin(), dist))
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
setup(std::size_t size);
|
setup(std::size_t size);
|
||||||
|
|
||||||
|
buffers_prefix_view(
|
||||||
|
buffers_prefix_view const& other,
|
||||||
|
std::size_t dist);
|
||||||
|
|
||||||
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 = typename std::conditional<
|
using value_type = typename std::conditional<
|
||||||
@@ -74,22 +66,16 @@ public:
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/// Move Constructor
|
|
||||||
buffers_prefix_view(buffers_prefix_view&&);
|
|
||||||
|
|
||||||
/// Copy Constructor
|
/// Copy Constructor
|
||||||
buffers_prefix_view(buffers_prefix_view const&);
|
buffers_prefix_view(buffers_prefix_view const&);
|
||||||
|
|
||||||
/// Move Assignment
|
|
||||||
buffers_prefix_view& operator=(buffers_prefix_view&&);
|
|
||||||
|
|
||||||
/// Copy Assignment
|
/// Copy Assignment
|
||||||
buffers_prefix_view& operator=(buffers_prefix_view const&);
|
buffers_prefix_view& operator=(buffers_prefix_view const&);
|
||||||
|
|
||||||
/** Construct a buffer sequence prefix.
|
/** Construct a buffer sequence prefix.
|
||||||
|
|
||||||
@param size 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,
|
If this is larger than the size of passed buffers,
|
||||||
the resulting sequence will represent the entire
|
the resulting sequence will represent the entire
|
||||||
input sequence.
|
input sequence.
|
||||||
|
|
||||||
@@ -100,16 +86,16 @@ public:
|
|||||||
*/
|
*/
|
||||||
buffers_prefix_view(
|
buffers_prefix_view(
|
||||||
std::size_t size,
|
std::size_t size,
|
||||||
BufferSequence const& buffers);
|
ConstBufferSequence const& buffers);
|
||||||
|
|
||||||
/** Construct a buffer sequence prefix in-place.
|
/** Construct a buffer sequence prefix in-place.
|
||||||
|
|
||||||
@param size 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,
|
If this is larger than the size of passed buffers,
|
||||||
the resulting sequence will represent the entire
|
the resulting sequence will represent the entire
|
||||||
input sequence.
|
input sequence.
|
||||||
|
|
||||||
@param args Arguments forwarded to the contained buffers constructor.
|
@param args Arguments forwarded to the contained buffer's constructor.
|
||||||
*/
|
*/
|
||||||
template<class... Args>
|
template<class... Args>
|
||||||
buffers_prefix_view(
|
buffers_prefix_view(
|
||||||
@@ -124,64 +110,29 @@ public:
|
|||||||
/// Returns an iterator to one past the last buffer in the sequence
|
/// Returns an iterator to one past the last buffer in the sequence
|
||||||
const_iterator
|
const_iterator
|
||||||
end() const;
|
end() const;
|
||||||
|
|
||||||
|
#if ! BOOST_BEAST_DOXYGEN
|
||||||
|
template<class Buffers>
|
||||||
|
friend
|
||||||
|
std::size_t
|
||||||
|
buffer_size(buffers_prefix_view<Buffers> const& buffers);
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#ifndef BOOST_BEAST_DOXYGEN
|
||||||
|
BOOST_BEAST_DECL
|
||||||
|
std::size_t
|
||||||
|
buffer_size(buffers_prefix_view<
|
||||||
|
net::const_buffer> const& buffers);
|
||||||
|
|
||||||
|
BOOST_BEAST_DECL
|
||||||
|
std::size_t
|
||||||
|
buffer_size(buffers_prefix_view<
|
||||||
|
net::mutable_buffer> const& buffers);
|
||||||
|
#endif
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
/** Returns a prefix of a constant buffer.
|
|
||||||
|
|
||||||
The returned buffer points to the same memory as the passed
|
|
||||||
buffer, but with a size that is equal to or smaller.
|
|
||||||
|
|
||||||
@param size The maximum size of the returned buffer in bytes. If
|
|
||||||
this is greater than or equal to the size of the passed buffer,
|
|
||||||
the result will have the same size as the original buffer.
|
|
||||||
|
|
||||||
@param buffer The buffer to return a prefix for. The
|
|
||||||
underlying memory is not modified, and ownership of the
|
|
||||||
memory is not transferred.
|
|
||||||
|
|
||||||
@return A constant buffer that represents the prefix of
|
|
||||||
the original buffer.
|
|
||||||
|
|
||||||
@par Exception Safety
|
|
||||||
|
|
||||||
No-throw guarantee.
|
|
||||||
*/
|
|
||||||
inline
|
|
||||||
net::const_buffer
|
|
||||||
buffers_prefix(std::size_t size,
|
|
||||||
net::const_buffer buffer) noexcept
|
|
||||||
{
|
|
||||||
return {buffer.data(), std::min<
|
|
||||||
std::size_t>(size, buffer.size())};
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Returns a prefix of a mutable buffer.
|
|
||||||
|
|
||||||
The returned buffer points to the same memory as the passed
|
|
||||||
buffer, but with a size that is equal to or smaller.
|
|
||||||
|
|
||||||
@param size The maximum size of the returned buffer in bytes. If
|
|
||||||
this is greater than or equal to the size of the passed buffer,
|
|
||||||
the result will have the same size as the original buffer.
|
|
||||||
|
|
||||||
@param buffer The buffer to return a prefix for. The
|
|
||||||
underlying memory is not modified, and ownership of the
|
|
||||||
memory is not transferred.
|
|
||||||
|
|
||||||
@return A mutable buffer that represents the prefix of
|
|
||||||
the original buffer.
|
|
||||||
*/
|
|
||||||
inline
|
|
||||||
net::mutable_buffer
|
|
||||||
buffers_prefix(std::size_t size,
|
|
||||||
net::mutable_buffer buffer) noexcept
|
|
||||||
{
|
|
||||||
return {buffer.data(), std::min<
|
|
||||||
std::size_t>(size, buffer.size())};
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Returns a prefix of a constant or mutable buffer sequence.
|
/** Returns a prefix of a constant or mutable buffer sequence.
|
||||||
|
|
||||||
The returned buffer sequence points to the same memory as the
|
The returned buffer sequence points to the same memory as the
|
||||||
@@ -202,30 +153,16 @@ buffers_prefix(std::size_t size,
|
|||||||
|
|
||||||
@return A constant buffer sequence that represents the prefix
|
@return A constant buffer sequence that represents the prefix
|
||||||
of the original buffer sequence. If the original buffer sequence
|
of the original buffer sequence. If the original buffer sequence
|
||||||
also meets the requirements of <em>MutableBufferSequence</em>,
|
also meets the requirements of <em>MutableConstBufferSequence</em>,
|
||||||
then the returned value will also be a mutable buffer sequence.
|
then the returned value will also be a mutable buffer sequence.
|
||||||
|
|
||||||
@note This function does not participate in overload resolution
|
|
||||||
if `buffers` is convertible to either `net::const_buffer` or
|
|
||||||
`net::mutable_buffer`.
|
|
||||||
*/
|
*/
|
||||||
template<class ConstBufferSequence>
|
template<class ConstBufferSequence>
|
||||||
#if BOOST_BEAST_DOXYGEN
|
|
||||||
buffers_prefix_view<ConstBufferSequence>
|
buffers_prefix_view<ConstBufferSequence>
|
||||||
#else
|
buffers_prefix(
|
||||||
inline
|
std::size_t size, ConstBufferSequence const& buffers)
|
||||||
typename std::enable_if<
|
|
||||||
! std::is_convertible<ConstBufferSequence,
|
|
||||||
net::const_buffer>::value &&
|
|
||||||
! std::is_convertible<ConstBufferSequence,
|
|
||||||
net::mutable_buffer>::value,
|
|
||||||
buffers_prefix_view<ConstBufferSequence>>::type
|
|
||||||
#endif
|
|
||||||
buffers_prefix(std::size_t size, ConstBufferSequence const& buffers)
|
|
||||||
{
|
{
|
||||||
static_assert(
|
static_assert(
|
||||||
net::is_const_buffer_sequence<ConstBufferSequence>::value ||
|
net::is_const_buffer_sequence<ConstBufferSequence>::value,
|
||||||
net::is_mutable_buffer_sequence<ConstBufferSequence>::value,
|
|
||||||
"ConstBufferSequence requirements not met");
|
"ConstBufferSequence requirements not met");
|
||||||
return buffers_prefix_view<ConstBufferSequence>(size, buffers);
|
return buffers_prefix_view<ConstBufferSequence>(size, buffers);
|
||||||
}
|
}
|
||||||
@@ -240,12 +177,12 @@ buffers_prefix(std::size_t size, ConstBufferSequence const& buffers)
|
|||||||
mutable, the returned buffer sequence will also be mutable.
|
mutable, the returned buffer sequence will also be mutable.
|
||||||
Otherwise, the returned buffer sequence will be constant.
|
Otherwise, the returned buffer sequence will be constant.
|
||||||
*/
|
*/
|
||||||
template<class BufferSequence>
|
template<class ConstBufferSequence>
|
||||||
typename std::conditional<
|
typename std::conditional<
|
||||||
net::is_mutable_buffer_sequence<BufferSequence>::value,
|
net::is_mutable_buffer_sequence<ConstBufferSequence>::value,
|
||||||
net::mutable_buffer,
|
net::mutable_buffer,
|
||||||
net::const_buffer>::type
|
net::const_buffer>::type
|
||||||
buffers_front(BufferSequence const& buffers)
|
buffers_front(ConstBufferSequence const& buffers)
|
||||||
{
|
{
|
||||||
auto const first =
|
auto const first =
|
||||||
net::buffer_sequence_begin(buffers);
|
net::buffer_sequence_begin(buffers);
|
||||||
|
@@ -7,8 +7,8 @@
|
|||||||
// Official repository: https://github.com/boostorg/beast
|
// Official repository: https://github.com/boostorg/beast
|
||||||
//
|
//
|
||||||
|
|
||||||
#ifndef BOOST_BEAST_IMPL_BUFFERS_PREFIX_IPP
|
#ifndef BOOST_BEAST_IMPL_BUFFERS_PREFIX_HPP
|
||||||
#define BOOST_BEAST_IMPL_BUFFERS_PREFIX_IPP
|
#define BOOST_BEAST_IMPL_BUFFERS_PREFIX_HPP
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
@@ -20,32 +20,10 @@
|
|||||||
namespace boost {
|
namespace boost {
|
||||||
namespace beast {
|
namespace beast {
|
||||||
|
|
||||||
namespace detail {
|
template<class Buffers>
|
||||||
|
class buffers_prefix_view<Buffers>::const_iterator
|
||||||
inline
|
|
||||||
net::const_buffer
|
|
||||||
buffers_prefix(std::size_t size,
|
|
||||||
net::const_buffer buffer)
|
|
||||||
{
|
{
|
||||||
return {buffer.data(),
|
friend class buffers_prefix_view<Buffers>;
|
||||||
(std::min)(size, buffer.size())};
|
|
||||||
}
|
|
||||||
|
|
||||||
inline
|
|
||||||
net::mutable_buffer
|
|
||||||
buffers_prefix(std::size_t size,
|
|
||||||
net::mutable_buffer buffer)
|
|
||||||
{
|
|
||||||
return {buffer.data(),
|
|
||||||
(std::min)(size, buffer.size())};
|
|
||||||
}
|
|
||||||
|
|
||||||
} // detail
|
|
||||||
|
|
||||||
template<class BufferSequence>
|
|
||||||
class buffers_prefix_view<BufferSequence>::const_iterator
|
|
||||||
{
|
|
||||||
friend class buffers_prefix_view<BufferSequence>;
|
|
||||||
|
|
||||||
buffers_prefix_view const* b_ = nullptr;
|
buffers_prefix_view const* b_ = nullptr;
|
||||||
std::size_t remain_;
|
std::size_t remain_;
|
||||||
@@ -65,9 +43,7 @@ public:
|
|||||||
std::bidirectional_iterator_tag;
|
std::bidirectional_iterator_tag;
|
||||||
|
|
||||||
const_iterator() = default;
|
const_iterator() = default;
|
||||||
const_iterator(const_iterator&& other) = default;
|
|
||||||
const_iterator(const_iterator const& other) = default;
|
const_iterator(const_iterator const& other) = default;
|
||||||
const_iterator& operator=(const_iterator&& other) = default;
|
|
||||||
const_iterator& operator=(const_iterator const& other) = default;
|
const_iterator& operator=(const_iterator const& other) = default;
|
||||||
|
|
||||||
bool
|
bool
|
||||||
@@ -98,7 +74,7 @@ public:
|
|||||||
reference
|
reference
|
||||||
operator*() const
|
operator*() const
|
||||||
{
|
{
|
||||||
return detail::buffers_prefix(remain_, *it_);
|
return beast::buffers_prefix(remain_, *it_);
|
||||||
}
|
}
|
||||||
|
|
||||||
pointer
|
pointer
|
||||||
@@ -154,9 +130,9 @@ private:
|
|||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
template<class BufferSequence>
|
template<class Buffers>
|
||||||
void
|
void
|
||||||
buffers_prefix_view<BufferSequence>::
|
buffers_prefix_view<Buffers>::
|
||||||
setup(std::size_t size)
|
setup(std::size_t size)
|
||||||
{
|
{
|
||||||
size_ = 0;
|
size_ = 0;
|
||||||
@@ -166,10 +142,14 @@ setup(std::size_t size)
|
|||||||
while(end_ != last)
|
while(end_ != last)
|
||||||
{
|
{
|
||||||
auto const len =
|
auto const len =
|
||||||
net::buffer_size(*end_++);
|
net::const_buffer(*end_++).size();
|
||||||
if(len >= size)
|
if(len >= size)
|
||||||
{
|
{
|
||||||
size_ += size;
|
size_ += size;
|
||||||
|
|
||||||
|
// by design, this subtraction can wrap
|
||||||
|
BOOST_STATIC_ASSERT(std::is_unsigned<
|
||||||
|
decltype(remain_)>::value);
|
||||||
remain_ = size - len;
|
remain_ = size - len;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -178,18 +158,20 @@ setup(std::size_t size)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class BufferSequence>
|
template<class Buffers>
|
||||||
buffers_prefix_view<BufferSequence>::
|
buffers_prefix_view<Buffers>::
|
||||||
buffers_prefix_view(buffers_prefix_view&& other)
|
buffers_prefix_view(
|
||||||
: buffers_prefix_view(std::move(other),
|
buffers_prefix_view const& other,
|
||||||
std::distance<iter_type>(
|
std::size_t dist)
|
||||||
net::buffer_sequence_begin(other.bs_),
|
: bs_(other.bs_)
|
||||||
other.end_))
|
, size_(other.size_)
|
||||||
|
, remain_(other.remain_)
|
||||||
|
, end_(std::next(bs_.begin(), dist))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class BufferSequence>
|
template<class Buffers>
|
||||||
buffers_prefix_view<BufferSequence>::
|
buffers_prefix_view<Buffers>::
|
||||||
buffers_prefix_view(buffers_prefix_view const& other)
|
buffers_prefix_view(buffers_prefix_view const& other)
|
||||||
: buffers_prefix_view(other,
|
: buffers_prefix_view(other,
|
||||||
std::distance<iter_type>(
|
std::distance<iter_type>(
|
||||||
@@ -198,27 +180,9 @@ buffers_prefix_view(buffers_prefix_view const& other)
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class BufferSequence>
|
template<class Buffers>
|
||||||
auto
|
auto
|
||||||
buffers_prefix_view<BufferSequence>::
|
buffers_prefix_view<Buffers>::
|
||||||
operator=(buffers_prefix_view&& other) ->
|
|
||||||
buffers_prefix_view&
|
|
||||||
{
|
|
||||||
auto const dist = std::distance<iter_type>(
|
|
||||||
net::buffer_sequence_begin(other.bs_),
|
|
||||||
other.end_);
|
|
||||||
bs_ = std::move(other.bs_);
|
|
||||||
size_ = other.size_;
|
|
||||||
remain_ = other.remain_;
|
|
||||||
end_ = std::next(
|
|
||||||
net::buffer_sequence_begin(bs_),
|
|
||||||
dist);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class BufferSequence>
|
|
||||||
auto
|
|
||||||
buffers_prefix_view<BufferSequence>::
|
|
||||||
operator=(buffers_prefix_view const& other) ->
|
operator=(buffers_prefix_view const& other) ->
|
||||||
buffers_prefix_view&
|
buffers_prefix_view&
|
||||||
{
|
{
|
||||||
@@ -234,43 +198,138 @@ operator=(buffers_prefix_view const& other) ->
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class BufferSequence>
|
template<class Buffers>
|
||||||
buffers_prefix_view<BufferSequence>::
|
buffers_prefix_view<Buffers>::
|
||||||
buffers_prefix_view(std::size_t size,
|
buffers_prefix_view(
|
||||||
BufferSequence const& bs)
|
std::size_t size,
|
||||||
|
Buffers const& bs)
|
||||||
: bs_(bs)
|
: bs_(bs)
|
||||||
{
|
{
|
||||||
setup(size);
|
setup(size);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class BufferSequence>
|
template<class Buffers>
|
||||||
template<class... Args>
|
template<class... Args>
|
||||||
buffers_prefix_view<BufferSequence>::
|
buffers_prefix_view<Buffers>::
|
||||||
buffers_prefix_view(std::size_t size,
|
buffers_prefix_view(
|
||||||
boost::in_place_init_t, Args&&... args)
|
std::size_t size,
|
||||||
|
boost::in_place_init_t,
|
||||||
|
Args&&... args)
|
||||||
: bs_(std::forward<Args>(args)...)
|
: bs_(std::forward<Args>(args)...)
|
||||||
{
|
{
|
||||||
setup(size);
|
setup(size);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class BufferSequence>
|
template<class Buffers>
|
||||||
inline
|
|
||||||
auto
|
auto
|
||||||
buffers_prefix_view<BufferSequence>::begin() const ->
|
buffers_prefix_view<Buffers>::begin() const ->
|
||||||
const_iterator
|
const_iterator
|
||||||
{
|
{
|
||||||
return const_iterator{*this, std::false_type{}};
|
return const_iterator{*this, std::false_type{}};
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class BufferSequence>
|
template<class Buffers>
|
||||||
inline
|
|
||||||
auto
|
auto
|
||||||
buffers_prefix_view<BufferSequence>::end() const ->
|
buffers_prefix_view<Buffers>::end() const ->
|
||||||
const_iterator
|
const_iterator
|
||||||
{
|
{
|
||||||
return const_iterator{*this, std::true_type{}};
|
return const_iterator{*this, std::true_type{}};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<class Buffers>
|
||||||
|
std::size_t
|
||||||
|
buffer_size(buffers_prefix_view<
|
||||||
|
Buffers> const& buffers)
|
||||||
|
{
|
||||||
|
return buffers.size_;
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
template<>
|
||||||
|
class buffers_prefix_view<net::const_buffer>
|
||||||
|
: public net::const_buffer
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
using net::const_buffer::const_buffer;
|
||||||
|
buffers_prefix_view(buffers_prefix_view const&) = default;
|
||||||
|
buffers_prefix_view& operator=(buffers_prefix_view const&) = default;
|
||||||
|
|
||||||
|
buffers_prefix_view(
|
||||||
|
std::size_t size,
|
||||||
|
net::const_buffer buffer)
|
||||||
|
: net::const_buffer(
|
||||||
|
buffer.data(),
|
||||||
|
std::min<std::size_t>(size, buffer.size())
|
||||||
|
#if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING)
|
||||||
|
, buffer.get_debug_check()
|
||||||
|
#endif
|
||||||
|
)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class... Args>
|
||||||
|
buffers_prefix_view(
|
||||||
|
std::size_t size,
|
||||||
|
boost::in_place_init_t,
|
||||||
|
Args&&... args)
|
||||||
|
: buffers_prefix_view(size,
|
||||||
|
net::const_buffer(
|
||||||
|
std::forward<Args>(args)...))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
std::size_t
|
||||||
|
buffer_size(buffers_prefix_view<
|
||||||
|
net::const_buffer> const& buffers)
|
||||||
|
{
|
||||||
|
return buffers.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
template<>
|
||||||
|
class buffers_prefix_view<net::mutable_buffer>
|
||||||
|
: public net::mutable_buffer
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
using net::mutable_buffer::mutable_buffer;
|
||||||
|
buffers_prefix_view(buffers_prefix_view const&) = default;
|
||||||
|
buffers_prefix_view& operator=(buffers_prefix_view const&) = default;
|
||||||
|
|
||||||
|
buffers_prefix_view(
|
||||||
|
std::size_t size,
|
||||||
|
net::mutable_buffer buffer)
|
||||||
|
: net::mutable_buffer(
|
||||||
|
buffer.data(),
|
||||||
|
std::min<std::size_t>(size, buffer.size())
|
||||||
|
#if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING)
|
||||||
|
, buffer.get_debug_check()
|
||||||
|
#endif
|
||||||
|
)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class... Args>
|
||||||
|
buffers_prefix_view(
|
||||||
|
std::size_t size,
|
||||||
|
boost::in_place_init_t,
|
||||||
|
Args&&... args)
|
||||||
|
: buffers_prefix_view(size,
|
||||||
|
net::mutable_buffer(
|
||||||
|
std::forward<Args>(args)...))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
std::size_t
|
||||||
|
buffer_size(buffers_prefix_view<
|
||||||
|
net::mutable_buffer> const& buffers)
|
||||||
|
{
|
||||||
|
return buffers.size();
|
||||||
|
}
|
||||||
|
|
||||||
} // beast
|
} // beast
|
||||||
} // boost
|
} // boost
|
||||||
|
|
||||||
|
@@ -20,21 +20,6 @@
|
|||||||
namespace boost {
|
namespace boost {
|
||||||
namespace beast {
|
namespace beast {
|
||||||
|
|
||||||
BOOST_STATIC_ASSERT(
|
|
||||||
std::is_same<net::const_buffer, decltype(
|
|
||||||
buffers_prefix(0,
|
|
||||||
std::declval<net::const_buffer>()))>::value);
|
|
||||||
|
|
||||||
BOOST_STATIC_ASSERT(
|
|
||||||
net::is_const_buffer_sequence<decltype(
|
|
||||||
buffers_prefix(0,
|
|
||||||
std::declval<net::const_buffer>()))>::value);
|
|
||||||
|
|
||||||
BOOST_STATIC_ASSERT(
|
|
||||||
std::is_same<net::mutable_buffer, decltype(
|
|
||||||
buffers_prefix(0,
|
|
||||||
std::declval<net::mutable_buffer>()))>::value);
|
|
||||||
|
|
||||||
class buffers_prefix_test : public beast::unit_test::suite
|
class buffers_prefix_test : public beast::unit_test::suite
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -43,10 +28,9 @@ public:
|
|||||||
std::size_t
|
std::size_t
|
||||||
bsize1(ConstBufferSequence const& bs)
|
bsize1(ConstBufferSequence const& bs)
|
||||||
{
|
{
|
||||||
using net::buffer_size;
|
|
||||||
std::size_t n = 0;
|
std::size_t n = 0;
|
||||||
for(auto it = bs.begin(); it != bs.end(); ++it)
|
for(auto it = bs.begin(); it != bs.end(); ++it)
|
||||||
n += buffer_size(*it);
|
n += net::buffer_size(*it);
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -55,10 +39,9 @@ public:
|
|||||||
std::size_t
|
std::size_t
|
||||||
bsize2(ConstBufferSequence const& bs)
|
bsize2(ConstBufferSequence const& bs)
|
||||||
{
|
{
|
||||||
using net::buffer_size;
|
|
||||||
std::size_t n = 0;
|
std::size_t n = 0;
|
||||||
for(auto it = bs.begin(); it != bs.end(); it++)
|
for(auto it = bs.begin(); it != bs.end(); it++)
|
||||||
n += buffer_size(*it);
|
n += net::buffer_size(*it);
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -67,10 +50,9 @@ public:
|
|||||||
std::size_t
|
std::size_t
|
||||||
bsize3(ConstBufferSequence const& bs)
|
bsize3(ConstBufferSequence const& bs)
|
||||||
{
|
{
|
||||||
using net::buffer_size;
|
|
||||||
std::size_t n = 0;
|
std::size_t n = 0;
|
||||||
for(auto it = bs.end(); it != bs.begin();)
|
for(auto it = bs.end(); it != bs.begin();)
|
||||||
n += buffer_size(*--it);
|
n += net::buffer_size(*--it);
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -79,12 +61,11 @@ public:
|
|||||||
std::size_t
|
std::size_t
|
||||||
bsize4(ConstBufferSequence const& bs)
|
bsize4(ConstBufferSequence const& bs)
|
||||||
{
|
{
|
||||||
using net::buffer_size;
|
|
||||||
std::size_t n = 0;
|
std::size_t n = 0;
|
||||||
for(auto it = bs.end(); it != bs.begin();)
|
for(auto it = bs.end(); it != bs.begin();)
|
||||||
{
|
{
|
||||||
it--;
|
it--;
|
||||||
n += buffer_size(*it);
|
n += net::buffer_size(*it);
|
||||||
}
|
}
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
@@ -121,26 +102,27 @@ public:
|
|||||||
|
|
||||||
void testEmptyBuffers()
|
void testEmptyBuffers()
|
||||||
{
|
{
|
||||||
using net::buffer_copy;
|
|
||||||
using net::buffer_size;
|
using net::buffer_size;
|
||||||
using net::mutable_buffer;
|
|
||||||
auto pb0 = buffers_prefix(0, mutable_buffer{});
|
|
||||||
BEAST_EXPECT(buffer_size(pb0) == 0);
|
|
||||||
auto pb1 = buffers_prefix(1, mutable_buffer{});
|
|
||||||
BEAST_EXPECT(buffer_size(pb1) == 0);
|
|
||||||
BEAST_EXPECT(buffer_copy(pb0, pb1) == 0);
|
|
||||||
|
|
||||||
|
auto pb0 = buffers_prefix(0, net::mutable_buffer{});
|
||||||
|
BEAST_EXPECT(buffer_size(pb0) == 0);
|
||||||
|
auto pb1 = buffers_prefix(1, net::mutable_buffer{});
|
||||||
|
BEAST_EXPECT(buffer_size(pb1) == 0);
|
||||||
|
BEAST_EXPECT(net::buffer_copy(pb0, pb1) == 0);
|
||||||
|
|
||||||
|
#if 0
|
||||||
using pb_type = decltype(pb0);
|
using pb_type = decltype(pb0);
|
||||||
buffers_suffix<pb_type> cb(pb0);
|
buffers_suffix<pb_type> cb(pb0);
|
||||||
BEAST_EXPECT(buffer_size(cb) == 0);
|
BEAST_EXPECT(buffer_size(cb) == 0);
|
||||||
BEAST_EXPECT(buffer_copy(cb, pb1) == 0);
|
BEAST_EXPECT(net::buffer_copy(cb, pb1) == 0);
|
||||||
cb.consume(1);
|
cb.consume(1);
|
||||||
BEAST_EXPECT(buffer_size(cb) == 0);
|
BEAST_EXPECT(buffer_size(cb) == 0);
|
||||||
BEAST_EXPECT(buffer_copy(cb, pb1) == 0);
|
BEAST_EXPECT(net::buffer_copy(cb, pb1) == 0);
|
||||||
|
|
||||||
auto pbc = buffers_prefix(2, cb);
|
auto pbc = buffers_prefix(2, cb);
|
||||||
BEAST_EXPECT(buffer_size(pbc) == 0);
|
BEAST_EXPECT(buffer_size(pbc) == 0);
|
||||||
BEAST_EXPECT(buffer_copy(pbc, cb) == 0);
|
BEAST_EXPECT(net::buffer_copy(pbc, cb) == 0);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void testIterator()
|
void testIterator()
|
||||||
@@ -157,6 +139,73 @@ public:
|
|||||||
BEAST_EXPECT(bsize2(pb) == 2);
|
BEAST_EXPECT(bsize2(pb) == 2);
|
||||||
BEAST_EXPECT(bsize3(pb) == 2);
|
BEAST_EXPECT(bsize3(pb) == 2);
|
||||||
BEAST_EXPECT(bsize4(pb) == 2);
|
BEAST_EXPECT(bsize4(pb) == 2);
|
||||||
|
|
||||||
|
// default ctor is one past the end
|
||||||
|
decltype(pb)::const_iterator it;
|
||||||
|
BEAST_EXPECT(pb.end() == it);
|
||||||
|
BEAST_EXPECT(it == pb.end());
|
||||||
|
decltype(pb)::const_iterator it2;
|
||||||
|
BEAST_EXPECT(it == it2);
|
||||||
|
BEAST_EXPECT(it2 == it);
|
||||||
|
it = pb.end();
|
||||||
|
it2 = pb.end();
|
||||||
|
BEAST_EXPECT(it == it2);
|
||||||
|
BEAST_EXPECT(it2 == it);
|
||||||
|
decltype(pb)::const_iterator it3(it2);
|
||||||
|
BEAST_EXPECT(it3 == it2);
|
||||||
|
it = pb.begin();
|
||||||
|
BEAST_EXPECT(it != it3);
|
||||||
|
it = it3;
|
||||||
|
BEAST_EXPECT(it == it3);
|
||||||
|
}
|
||||||
|
|
||||||
|
void testInPlaceInit()
|
||||||
|
{
|
||||||
|
{
|
||||||
|
class test_buffers
|
||||||
|
{
|
||||||
|
net::const_buffer cb_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
using const_iterator =
|
||||||
|
net::const_buffer const*;
|
||||||
|
|
||||||
|
explicit
|
||||||
|
test_buffers(std::true_type)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
const_iterator
|
||||||
|
begin() const
|
||||||
|
{
|
||||||
|
return &cb_;
|
||||||
|
}
|
||||||
|
|
||||||
|
const_iterator
|
||||||
|
end() const
|
||||||
|
{
|
||||||
|
return begin() + 1;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
buffers_prefix_view<test_buffers> v(
|
||||||
|
2, boost::in_place_init, std::true_type{});
|
||||||
|
BEAST_EXPECT(buffer_size(v) == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
char c[2];
|
||||||
|
c[0] = 0;
|
||||||
|
c[1] = 0;
|
||||||
|
buffers_prefix_view<net::const_buffer> v(
|
||||||
|
2, boost::in_place_init, c, sizeof(c));
|
||||||
|
BEAST_EXPECT(buffer_size(v) == 2);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
char c[2];
|
||||||
|
buffers_prefix_view<net::mutable_buffer> v(
|
||||||
|
2, boost::in_place_init, c, sizeof(c));
|
||||||
|
BEAST_EXPECT(buffer_size(v) == 2);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void run() override
|
void run() override
|
||||||
@@ -165,6 +214,7 @@ public:
|
|||||||
testMatrix<net::mutable_buffer>();
|
testMatrix<net::mutable_buffer>();
|
||||||
testEmptyBuffers();
|
testEmptyBuffers();
|
||||||
testIterator();
|
testIterator();
|
||||||
|
testInPlaceInit();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user