diff --git a/CHANGELOG.md b/CHANGELOG.md
index 576bf78e..33ccd970 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -7,6 +7,7 @@ Version 200
* Refactor buffers_range
* Fix and refactor buffers_cat
* Refactor buffers_prefix
+* Add const and mutable buffer sequence traits
API Changes:
diff --git a/doc/qbk/03_core/3_buffers.qbk b/doc/qbk/03_core/3_buffers.qbk
index 53ad78c0..10237d59 100644
--- a/doc/qbk/03_core/3_buffers.qbk
+++ b/doc/qbk/03_core/3_buffers.qbk
@@ -160,4 +160,34 @@ output streams.
]]
]
+These type traits are provided to facilitate writing compile-time
+metafunctions which operate on buffers:
+
+[table Buffer Algorithms and Types
+[[Name][Description]]
+[[
+ [link beast.ref.boost__beast__buffers_type `buffers_type`]
+][
+ This metafunction is used to determine the underlying buffer type for
+ a list of buffer sequence. The equivalent type of the alias will vary
+ depending on the template type argument.
+]]
+[[
+ [link beast.ref.boost__beast__is_const_buffer_sequence `is_const_buffer_sequence`]
+][
+ This metafunction is used to determine if all of the specified types
+ meet the requirements of __ConstBufferSequence__. This type alias
+ will be `std::true_type` if each specified type meets the requirements,
+ otherwise, this type alias will be `std::false_type`.
+]]
+[[
+ [link beast.ref.boost__beast__is_mutable_buffer_sequence `is_mutable_buffer_sequence`]
+][
+ This metafunction is used to determine if all of the specified types
+ meet the requirements of __MutableBufferSequence__. This type alias
+ will be `std::true_type` if each specified type meets the requirements,
+ otherwise, this type alias will be `std::false_type`.
+]]
+]
+
[endsect]
diff --git a/doc/qbk/quickref.xml b/doc/qbk/quickref.xml
index 44b3c5b2..297c7e40 100644
--- a/doc/qbk/quickref.xml
+++ b/doc/qbk/quickref.xml
@@ -242,7 +242,9 @@
is_async_write_streamis_async_streamis_completion_handler
+ is_const_buffer_sequenceis_file
+ is_mutable_buffer_sequenceis_sync_read_streamis_sync_streamis_sync_write_stream
diff --git a/include/boost/beast/core/buffer_traits.hpp b/include/boost/beast/core/buffer_traits.hpp
index 0141e333..74ed663a 100644
--- a/include/boost/beast/core/buffer_traits.hpp
+++ b/include/boost/beast/core/buffer_traits.hpp
@@ -12,24 +12,62 @@
#include
#include
+#include
#include
namespace boost {
namespace beast {
-/** Type alias used to obtain the underlying buffer type of a buffer sequence.
+/** Determine if a list of types satisfy the ConstBufferSequence requirements.
+
+ This metafunction is used to determine if all of the specified types
+ meet the requirements for const buffer sequences. This type alias
+ will be `std::true_type` if each specified type meets the requirements,
+ otherwise, this type alias will be `std::false_type`.
+
+ @tparam TN A list of zero or more types to check. If this list is
+ empty, the resulting type alias will be `std::true_type`.
+*/
+#if BOOST_BEAST_DOXYGEN
+template
+struct is_const_buffer_sequence : __see_below__ {};
+//using is_const_buffer_sequence = __see_below__;
+#else
+template
+using is_const_buffer_sequence = mp11::mp_all<
+ net::is_const_buffer_sequence...>;
+#endif
+
+/** Determine if a list of types satisfy the MutableBufferSequence requirements.
+
+ This metafunction is used to determine if all of the specified types
+ meet the requirements for mutable buffer sequences. This type alias
+ will be `std::true_type` if each specified type meets the requirements,
+ otherwise, this type alias will be `std::false_type`.
+
+ @tparam TN A list of zero or more types to check. If this list is
+ empty, the resulting type alias will be `std::true_type`.
+*/
+#if BOOST_BEAST_DOXYGEN
+template
+struct is_mutable_buffer_sequence : __see_below__ {};
+//using is_mutable_buffer_sequence = __see_below__;
+#else
+template
+using is_mutable_buffer_sequence = mp11::mp_all<
+ net::is_mutable_buffer_sequence...>;
+#endif
+
+/** Type alias for the underlying buffer type of a list of buffer sequence types.
This metafunction is used to determine the underlying buffer type for
- a given buffer sequence. The equivalent type of the alias will vary
+ a list of buffer sequence. The equivalent type of the alias will vary
depending on the template type argument:
- @li If the template argument is a MutableBufferSequence,
- the resulting type alias will be `net::mutable_buffer`, else
+ @li If every type in the list is a MutableBufferSequence,
+ the resulting type alias will be `net::mutable_buffer`, otherwise
- @li If the template argument is a ConstBufferSequence,
- the resulting type alias will be `net::const_buffer`, otherwise
-
- @li The resulting type alias will be `void`.
+ @li The resulting type alias will be `net::const_buffer`.
@par Example
The following code returns the first buffer in a buffer sequence,
@@ -50,21 +88,19 @@ namespace beast {
}
@endcode
- @param T The buffer sequence type to use.
+ @tparam TN A list of zero or more types to check. If this list is
+ empty, the resulting type alias will be `net::mutable_buffer`.
*/
-template
+template
#if BOOST_BEAST_DOXYGEN
struct buffers_type : __see_below__ {};
//using buffers_type = __see_below__;
#else
using buffers_type = typename
std::conditional<
- net::is_mutable_buffer_sequence::value,
+ is_mutable_buffer_sequence::value,
net::mutable_buffer,
- typename std::conditional<
- net::is_const_buffer_sequence::value,
- net::const_buffer,
- void>::type>::type;
+ net::const_buffer>::type;
#endif
} // beast
diff --git a/test/beast/core/buffer_traits.cpp b/test/beast/core/buffer_traits.cpp
index 846c7bbe..d27bff9f 100644
--- a/test/beast/core/buffer_traits.cpp
+++ b/test/beast/core/buffer_traits.cpp
@@ -10,30 +10,139 @@
// Test that header file is self-contained.
#include
+#include
#include
namespace boost {
namespace beast {
-BOOST_STATIC_ASSERT(
- std::is_same>::value);
+class buffer_traits_test : public beast::unit_test::suite
+{
+public:
+ // is_const_buffer_sequence
-BOOST_STATIC_ASSERT(
- std::is_same>::value);
+ BOOST_STATIC_ASSERT(is_const_buffer_sequence<
+ >::value);
-BOOST_STATIC_ASSERT(
- std::is_same>>::value);
+ BOOST_STATIC_ASSERT(is_const_buffer_sequence<
+ net::const_buffer
+ >::value);
-BOOST_STATIC_ASSERT(
- std::is_same>>::value);
+ BOOST_STATIC_ASSERT(is_const_buffer_sequence<
+ net::const_buffer, net::const_buffer
+ >::value);
-BOOST_STATIC_ASSERT(
- std::is_same>>::value);
+ BOOST_STATIC_ASSERT(is_const_buffer_sequence<
+ net::const_buffer, net::mutable_buffer
+ >::value);
+
+ BOOST_STATIC_ASSERT(is_const_buffer_sequence<
+ net::mutable_buffer, net::mutable_buffer
+ >::value);
+
+ // is_mutable_buffer_sequence
+
+ BOOST_STATIC_ASSERT(is_mutable_buffer_sequence<
+ >::value);
+
+ BOOST_STATIC_ASSERT(is_mutable_buffer_sequence<
+ net::mutable_buffer
+ >::value);
+
+ BOOST_STATIC_ASSERT(is_mutable_buffer_sequence<
+ net::mutable_buffer, net::mutable_buffer
+ >::value);
+
+ BOOST_STATIC_ASSERT(! is_mutable_buffer_sequence<
+ net::const_buffer, net::const_buffer
+ >::value);
+
+ BOOST_STATIC_ASSERT(! is_mutable_buffer_sequence<
+ net::const_buffer, net::mutable_buffer
+ >::value);
+
+ // buffers_type
+
+ BOOST_STATIC_ASSERT(
+ std::is_same>::value);
+
+ BOOST_STATIC_ASSERT(
+ std::is_same>::value);
+
+ BOOST_STATIC_ASSERT(
+ std::is_same>::value);
+
+ BOOST_STATIC_ASSERT(
+ std::is_same>::value);
+
+ BOOST_STATIC_ASSERT(
+ std::is_same>::value);
+
+ BOOST_STATIC_ASSERT(
+ std::is_same>::value);
+
+ BOOST_STATIC_ASSERT(
+ std::is_same
+ >>::value);
+
+ BOOST_STATIC_ASSERT(
+ std::is_same
+ >>::value);
+
+ BOOST_STATIC_ASSERT(
+ std::is_same
+ >>::value);
+
+ // javadoc: buffers_type
+ template
+ buffers_type
+ buffers_front (BufferSequence const& buffers)
+ {
+ static_assert(
+ net::is_const_buffer_sequence::value,
+ "BufferSequence requirements not met");
+ auto const first = net::buffer_sequence_begin (buffers);
+ if (first == net::buffer_sequence_end (buffers))
+ return {};
+ return *first;
+ }
+
+ void
+ testJavadocs()
+ {
+ // buffers_front
+ {
+ net::const_buffer cb;
+ buffers_front(cb);
+
+ net::mutable_buffer mb;
+ buffers_front(mb);
+ }
+
+ pass();
+ }
+
+ void run() override
+ {
+ testJavadocs();
+ }
+};
+
+BEAST_DEFINE_TESTSUITE(beast,core,buffer_traits);
} // beast
} // boost