Add buffers_range_ref (replaces reference_wrapper parameter)

This commit is contained in:
Vinnie Falco
2018-12-19 19:15:04 -08:00
parent cbd5e76e92
commit c4f4087888
14 changed files with 139 additions and 44 deletions

View File

@@ -22,6 +22,7 @@ Version 200
* HTTP tidying
* Adjust static_asio lib options in Jamfile
* Add type_traits tests
* Add buffers_range_ref (replaces reference_wrapper parameter)
API Changes:

View File

@@ -57,6 +57,7 @@ transferred.
]]
[[
[link beast.ref.boost__beast__buffers_range `buffers_range`]
[link beast.ref.boost__beast__buffers_range_ref `buffers_range_ref`]
][
This function returns an iterable range representing the passed
buffer sequence. The values obtained when iterating the range
@@ -64,6 +65,14 @@ transferred.
sequence is mutable, in which case the value obtained when iterating
will be a mutable buffer. It is intended as a notational convenience
when writing a ['range-for] statement over a buffer sequence.
The function
[link beast.ref.boost__beast__buffers_range_ref `buffers_range`]
maintains a copy of the buffer sequence, while
[link beast.ref.boost__beast__buffers_range_ref `buffers_range_ref`]
maintains a reference (in this case, the caller must ensure that
the lifetime of the referenced buffer sequence extends until the
range object is destroyed).
]]
[[
[link beast.ref.boost__beast__buffers_suffix `buffers_suffix`]

View File

@@ -219,6 +219,7 @@
<member><link linkend="beast.ref.boost__beast__buffers_front">buffers_front</link></member>
<member><link linkend="beast.ref.boost__beast__buffers_prefix">buffers_prefix</link></member>
<member><link linkend="beast.ref.boost__beast__buffers_range">buffers_range</link></member>
<member><link linkend="beast.ref.boost__beast__buffers_range_ref">buffers_range_ref</link></member>
<member><link linkend="beast.ref.boost__beast__buffers_to_string">buffers_to_string</link></member>
<member><link linkend="beast.ref.boost__beast__generic_category">generic_category</link></member>
<member><link linkend="beast.ref.boost__beast__iequals">iequals</link></member>

View File

@@ -11,9 +11,8 @@
#define BOOST_BEAST_BUFFERS_RANGE_HPP
#include <boost/beast/core/detail/config.hpp>
#include <boost/beast/core/buffer_traits.hpp>
#include <boost/beast/core/detail/buffers_range_adaptor.hpp>
#include <boost/asio/buffer.hpp>
#include <functional>
namespace boost {
namespace beast {
@@ -22,65 +21,104 @@ namespace beast {
This function returns an iterable range representing the
passed buffer sequence. The values obtained when iterating
the range will always be `const_buffer`, unless the underlying
buffer sequence is a @em MutableBufferSequence, in which case
the value obtained when iterating will be a `mutable_buffer`.
the range will be `net::const_buffer`, unless the underlying
buffer sequence is a <em>MutableBufferSequence</em>, in which case
the value obtained when iterating will be a `net::mutable_buffer`.
@par Example
The following function returns the total number of bytes in
the specified buffer sequence:
the specified buffer sequence. A copy of the buffer sequence
is maintained for the lifetime of the range object:
@code
template<class ConstBufferSequence>
std::size_t buffer_sequence_size(ConstBufferSequence const& buffers)
template <class BufferSequence>
std::size_t buffer_sequence_size (BufferSequence const& buffers)
{
std::size_t size = 0;
for(auto const buffer : buffers_range(std::ref(buffers)))
for (auto const buffer : buffers_range (buffers))
size += buffer.size();
return size;
}
@endcode
@param buffers The buffer sequence to adapt into a range. The
range returned from this function will contain a copy of the
passed buffer sequence. If `buffers` is a `std::reference_wrapper`,
the range returned from this function will contain a reference to the
passed buffer sequence. In this case, the caller is responsible
for ensuring that the lifetime of the buffer sequence is valid for
the lifetime of the returned range.
range object returned from this function will contain a copy
of the passed buffer sequence.
@return An object of unspecified type, meeting the requirements of
<em>ConstBufferSequence</em>, and also @em MutableBufferSequence if `buffers`
is a mutable buffer sequence.
@return An object of unspecified type which meets the requirements
of <em>ConstBufferSequence</em>. If `buffers` is a mutable buffer
sequence, the returned object will also meet the requirements of
<em>MutableBufferSequence</em>.
@see @ref buffers_range_ref
*/
/** @{ */
template<class ConstBufferSequence>
template<class BufferSequence>
#if BOOST_BEAST_DOXYGEN
__implementation_defined__
#else
detail::buffers_range_adaptor<ConstBufferSequence>
detail::buffers_range_adaptor<BufferSequence>
#endif
buffers_range(ConstBufferSequence const& buffers)
buffers_range(BufferSequence const& buffers)
{
static_assert(
net::is_const_buffer_sequence<ConstBufferSequence>::value,
"ConstBufferSequence requirements not met");
return detail::buffers_range_adaptor<ConstBufferSequence>(buffers);
is_const_buffer_sequence<BufferSequence>::value,
"BufferSequence requirements not met");
return detail::buffers_range_adaptor<
BufferSequence>(buffers);
}
template<class ConstBufferSequence>
/** Returns an iterable range representing a buffer sequence.
This function returns an iterable range representing the
passed buffer sequence. The values obtained when iterating
the range will be `net::const_buffer`, unless the underlying
buffer sequence is a <em>MutableBufferSequence</em>, in which case
the value obtained when iterating will be a `net::mutable_buffer`.
@par Example
The following function returns the total number of bytes in
the specified buffer sequence. A reference to the original
buffers is maintained for the lifetime of the range object:
@code
template <class BufferSequence>
std::size_t buffer_sequence_size_ref (BufferSequence const& buffers)
{
std::size_t size = 0;
for (auto const buffer : buffers_range_ref (buffers))
size += buffer.size();
return size;
}
@endcode
@param buffers The buffer sequence to adapt into a range. The
range returned from this function will maintain a reference to
these buffers. The application is responsible for ensuring that
the lifetime of the referenced buffers extends until the range
object is destroyed.
@return An object of unspecified type which meets the requirements
of <em>ConstBufferSequence</em>. If `buffers` is a mutable buffer
sequence, the returned object will also meet the requirements of
<em>MutableBufferSequence</em>.
@see @ref buffers_range
*/
template<class BufferSequence>
#if BOOST_BEAST_DOXYGEN
__implementation_defined__
#else
detail::buffers_range_adaptor<ConstBufferSequence const&>
detail::buffers_range_adaptor<BufferSequence const&>
#endif
buffers_range(std::reference_wrapper<ConstBufferSequence> buffers)
buffers_range_ref(BufferSequence const& buffers)
{
static_assert(
net::is_const_buffer_sequence<ConstBufferSequence>::value,
"ConstBufferSequence requirements not met");
return detail::buffers_range_adaptor<ConstBufferSequence const&>(buffers.get());
is_const_buffer_sequence<BufferSequence>::value,
"BufferSequence requirements not met");
return detail::buffers_range_adaptor<
BufferSequence const&>(buffers);
}
/** @} */

View File

@@ -50,7 +50,7 @@ buffers_to_string(ConstBufferSequence const& buffers)
std::string result;
using net::buffer_size;
result.reserve(buffer_size(buffers));
for(auto const buffer : beast::buffers_range(std::ref(buffers)))
for(auto const buffer : beast::buffers_range_ref(buffers))
result.append(static_cast<char const*>(
buffer.data()), buffer.size());
return result;

View File

@@ -192,7 +192,7 @@ struct basic_file_body<file_win32>
error_code& ec)
{
std::size_t nwritten = 0;
for(auto buffer : beast::buffers_range(std::ref(buffers)))
for(auto buffer : beast::buffers_range_ref(buffers))
{
nwritten += body_.file_.write(
buffer.data(), buffer.size(), ec);

View File

@@ -936,7 +936,7 @@ public:
if(os_.fail())
return;
std::size_t bytes_transferred = 0;
for(auto b : beast::buffers_range(std::ref(buffers)))
for(auto b : beast::buffers_range_ref(buffers))
{
os_.write(static_cast<char const*>(
b.data()), b.size());

View File

@@ -132,7 +132,7 @@ public:
}
ec.assign(0, ec.category());
CharT* dest = &body_[size];
for(auto b : beast::buffers_range(std::ref(buffers)))
for(auto b : beast::buffers_range_ref(buffers))
{
Traits::copy(dest, static_cast<
CharT const*>(b.data()), b.size());

View File

@@ -71,12 +71,16 @@ mask_inplace(net::mutable_buffer& b, prepared_key& key)
// Apply mask in place
//
template<class MutableBuffers, class KeyType>
template<
class MutableBufferSequence,
class KeyType>
void
mask_inplace(MutableBuffers const& bs, KeyType& key)
mask_inplace(
MutableBufferSequence const& buffers,
KeyType& key)
{
for(net::mutable_buffer b :
beast::buffers_range(std::ref(bs)))
beast::buffers_range_ref(buffers))
mask_inplace(b, key);
}

View File

@@ -84,11 +84,12 @@ template<class _>
template<class ConstBufferSequence>
bool
utf8_checker_t<_>::
write(ConstBufferSequence const& bs)
write(ConstBufferSequence const& buffers)
{
static_assert(net::is_const_buffer_sequence<ConstBufferSequence>::value,
static_assert(
net::is_const_buffer_sequence<ConstBufferSequence>::value,
"ConstBufferSequence requirements not met");
for(auto b : beast::buffers_range(std::ref(bs)))
for(auto b : beast::buffers_range_ref(buffers))
if(! write(static_cast<
std::uint8_t const*>(b.data()),
b.size()))

View File

@@ -60,7 +60,7 @@ deflate(
zs.next_in = nullptr;
zs.avail_out = out.size();
zs.next_out = out.data();
for(auto in : beast::buffers_range(std::ref(cb)))
for(auto in : beast::buffers_range_ref(cb))
{
zs.avail_in = in.size();
if(zs.avail_in == 0)

View File

@@ -20,11 +20,51 @@ namespace beast {
class buffers_range_test : public beast::unit_test::suite
{
public:
BOOST_STATIC_ASSERT(
is_const_buffer_sequence<
decltype(beast::buffers_range(
std::declval<net::const_buffer>()))>::value);
BOOST_STATIC_ASSERT(
is_const_buffer_sequence<
decltype(beast::buffers_range(
std::declval<net::mutable_buffer>()))>::value);
BOOST_STATIC_ASSERT(
! net::is_mutable_buffer_sequence<
decltype(beast::buffers_range(
std::declval<net::const_buffer>()))>::value);
BOOST_STATIC_ASSERT(
net::is_mutable_buffer_sequence<
decltype(beast::buffers_range(
std::declval<net::mutable_buffer>()))>::value);
template <class BufferSequence>
std::size_t buffer_sequence_size (BufferSequence const& buffers)
{
std::size_t size = 0;
for (auto const buffer : buffers_range (buffers))
size += buffer.size();
return size;
}
template <class BufferSequence>
std::size_t buffer_sequence_size_ref (BufferSequence const& buffers)
{
std::size_t size = 0;
for (auto const buffer : buffers_range_ref (buffers))
size += buffer.size();
return size;
}
void
testJavadocs()
{
BEAST_EXPECT(&buffers_range_test::buffer_sequence_size<net::const_buffer>);
BEAST_EXPECT(&buffers_range_test::buffer_sequence_size_ref<net::const_buffer>);
}
void
testBufferSequence()
{
@@ -44,6 +84,7 @@ public:
void
run() override
{
testJavadocs();
testBufferSequence();
}
};

View File

@@ -68,7 +68,7 @@ public:
fill(MutableBufferSequence const& buffers)
{
std::size_t n = 0;
for(auto b : beast::buffers_range(std::ref(buffers)))
for(auto b : beast::buffers_range_ref(buffers))
{
std::fill(
static_cast<char*>(b.data()),

View File

@@ -269,7 +269,7 @@ nodejs_basic_parser<Derived>::write(
ConstBufferSequence>::value,
"ConstBufferSequence requirements not met");
std::size_t bytes_used = 0;
for(auto buffer : beast::buffers_range(std::ref(buffers)))
for(auto buffer : beast::buffers_range_ref(buffers))
{
auto const n = write(
static_cast<void const*>(buffer.data()),