diff --git a/CHANGELOG.md b/CHANGELOG.md
index 8aad90f5..d74e6bfc 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -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:
diff --git a/doc/qbk/03_core/3_buffers.qbk b/doc/qbk/03_core/3_buffers.qbk
index cf61e471..aa954b8e 100644
--- a/doc/qbk/03_core/3_buffers.qbk
+++ b/doc/qbk/03_core/3_buffers.qbk
@@ -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`]
diff --git a/doc/qbk/quickref.xml b/doc/qbk/quickref.xml
index 220d2bba..83e6105d 100644
--- a/doc/qbk/quickref.xml
+++ b/doc/qbk/quickref.xml
@@ -219,6 +219,7 @@
buffers_frontbuffers_prefixbuffers_range
+ buffers_range_refbuffers_to_stringgeneric_categoryiequals
diff --git a/include/boost/beast/core/buffers_range.hpp b/include/boost/beast/core/buffers_range.hpp
index 1d0c882e..cdc40768 100644
--- a/include/boost/beast/core/buffers_range.hpp
+++ b/include/boost/beast/core/buffers_range.hpp
@@ -11,9 +11,8 @@
#define BOOST_BEAST_BUFFERS_RANGE_HPP
#include
+#include
#include
-#include
-#include
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 MutableBufferSequence, 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
- std::size_t buffer_sequence_size(ConstBufferSequence const& buffers)
+ template
+ 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
- ConstBufferSequence, and also @em MutableBufferSequence if `buffers`
- is a mutable buffer sequence.
+ @return An object of unspecified type which meets the requirements
+ of ConstBufferSequence. If `buffers` is a mutable buffer
+ sequence, the returned object will also meet the requirements of
+ MutableBufferSequence.
+
+ @see @ref buffers_range_ref
*/
-/** @{ */
-template
+template
#if BOOST_BEAST_DOXYGEN
__implementation_defined__
#else
-detail::buffers_range_adaptor
+detail::buffers_range_adaptor
#endif
-buffers_range(ConstBufferSequence const& buffers)
+buffers_range(BufferSequence const& buffers)
{
static_assert(
- net::is_const_buffer_sequence::value,
- "ConstBufferSequence requirements not met");
- return detail::buffers_range_adaptor(buffers);
+ is_const_buffer_sequence::value,
+ "BufferSequence requirements not met");
+ return detail::buffers_range_adaptor<
+ BufferSequence>(buffers);
}
-template
+/** 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 MutableBufferSequence, 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
+ 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 ConstBufferSequence. If `buffers` is a mutable buffer
+ sequence, the returned object will also meet the requirements of
+ MutableBufferSequence.
+
+ @see @ref buffers_range
+*/
+template
#if BOOST_BEAST_DOXYGEN
__implementation_defined__
#else
-detail::buffers_range_adaptor
+detail::buffers_range_adaptor
#endif
-buffers_range(std::reference_wrapper buffers)
+buffers_range_ref(BufferSequence const& buffers)
{
static_assert(
- net::is_const_buffer_sequence::value,
- "ConstBufferSequence requirements not met");
- return detail::buffers_range_adaptor(buffers.get());
+ is_const_buffer_sequence::value,
+ "BufferSequence requirements not met");
+ return detail::buffers_range_adaptor<
+ BufferSequence const&>(buffers);
}
/** @} */
diff --git a/include/boost/beast/core/buffers_to_string.hpp b/include/boost/beast/core/buffers_to_string.hpp
index 8aed006c..a36ced58 100644
--- a/include/boost/beast/core/buffers_to_string.hpp
+++ b/include/boost/beast/core/buffers_to_string.hpp
@@ -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(
buffer.data()), buffer.size());
return result;
diff --git a/include/boost/beast/http/impl/file_body_win32.ipp b/include/boost/beast/http/impl/file_body_win32.ipp
index 279e01a8..2d96ee9e 100644
--- a/include/boost/beast/http/impl/file_body_win32.ipp
+++ b/include/boost/beast/http/impl/file_body_win32.ipp
@@ -192,7 +192,7 @@ struct basic_file_body
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);
diff --git a/include/boost/beast/http/impl/write.ipp b/include/boost/beast/http/impl/write.ipp
index 180a029d..a08be699 100644
--- a/include/boost/beast/http/impl/write.ipp
+++ b/include/boost/beast/http/impl/write.ipp
@@ -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(
b.data()), b.size());
diff --git a/include/boost/beast/http/string_body.hpp b/include/boost/beast/http/string_body.hpp
index bc324b6f..95b69622 100644
--- a/include/boost/beast/http/string_body.hpp
+++ b/include/boost/beast/http/string_body.hpp
@@ -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());
diff --git a/include/boost/beast/websocket/detail/mask.hpp b/include/boost/beast/websocket/detail/mask.hpp
index cf3ecab1..bbb544e7 100644
--- a/include/boost/beast/websocket/detail/mask.hpp
+++ b/include/boost/beast/websocket/detail/mask.hpp
@@ -71,12 +71,16 @@ mask_inplace(net::mutable_buffer& b, prepared_key& key)
// Apply mask in place
//
-template
+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);
}
diff --git a/include/boost/beast/websocket/detail/utf8_checker.hpp b/include/boost/beast/websocket/detail/utf8_checker.hpp
index 7b09b337..ae37441e 100644
--- a/include/boost/beast/websocket/detail/utf8_checker.hpp
+++ b/include/boost/beast/websocket/detail/utf8_checker.hpp
@@ -84,11 +84,12 @@ template
template
bool
utf8_checker_t<_>::
-write(ConstBufferSequence const& bs)
+write(ConstBufferSequence const& buffers)
{
- static_assert(net::is_const_buffer_sequence::value,
+ static_assert(
+ net::is_const_buffer_sequence::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()))
diff --git a/include/boost/beast/websocket/impl/write.ipp b/include/boost/beast/websocket/impl/write.ipp
index 12f10bbd..08dce136 100644
--- a/include/boost/beast/websocket/impl/write.ipp
+++ b/include/boost/beast/websocket/impl/write.ipp
@@ -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)
diff --git a/test/beast/core/buffers_range.cpp b/test/beast/core/buffers_range.cpp
index d0e62ac8..d441492c 100644
--- a/test/beast/core/buffers_range.cpp
+++ b/test/beast/core/buffers_range.cpp
@@ -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()))>::value);
+
+ BOOST_STATIC_ASSERT(
+ is_const_buffer_sequence<
+ decltype(beast::buffers_range(
+ std::declval()))>::value);
+
+ BOOST_STATIC_ASSERT(
+ ! net::is_mutable_buffer_sequence<
+ decltype(beast::buffers_range(
+ std::declval()))>::value);
+
BOOST_STATIC_ASSERT(
net::is_mutable_buffer_sequence<
decltype(beast::buffers_range(
std::declval()))>::value);
+ template
+ 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
+ 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);
+ BEAST_EXPECT(&buffers_range_test::buffer_sequence_size_ref);
+ }
+
void
testBufferSequence()
{
@@ -44,6 +84,7 @@ public:
void
run() override
{
+ testJavadocs();
testBufferSequence();
}
};
diff --git a/test/bench/buffers/bench_buffers.cpp b/test/bench/buffers/bench_buffers.cpp
index 1548923e..bedf6b0b 100644
--- a/test/bench/buffers/bench_buffers.cpp
+++ b/test/bench/buffers/bench_buffers.cpp
@@ -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(b.data()),
diff --git a/test/bench/parser/nodejs_parser.hpp b/test/bench/parser/nodejs_parser.hpp
index 818734bf..951a926b 100644
--- a/test/bench/parser/nodejs_parser.hpp
+++ b/test/bench/parser/nodejs_parser.hpp
@@ -269,7 +269,7 @@ nodejs_basic_parser::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(buffer.data()),