Add const and mutable buffer sequence traits:

* Add variadic is_const_buffer_sequence
* Add variadic is_mutable_buffer_sequence
* buffers_type is now variadic
This commit is contained in:
Vinnie Falco
2018-12-15 10:59:00 -08:00
parent 4cfe860b93
commit 1998bad89d
5 changed files with 208 additions and 30 deletions

View File

@ -7,6 +7,7 @@ Version 200
* Refactor buffers_range * Refactor buffers_range
* Fix and refactor buffers_cat * Fix and refactor buffers_cat
* Refactor buffers_prefix * Refactor buffers_prefix
* Add const and mutable buffer sequence traits
API Changes: API Changes:

View File

@ -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] [endsect]

View File

@ -242,7 +242,9 @@
<member><link linkend="beast.ref.boost__beast__is_async_write_stream">is_async_write_stream</link></member> <member><link linkend="beast.ref.boost__beast__is_async_write_stream">is_async_write_stream</link></member>
<member><link linkend="beast.ref.boost__beast__is_async_stream">is_async_stream</link></member> <member><link linkend="beast.ref.boost__beast__is_async_stream">is_async_stream</link></member>
<member><link linkend="beast.ref.boost__beast__is_completion_handler">is_completion_handler</link></member> <member><link linkend="beast.ref.boost__beast__is_completion_handler">is_completion_handler</link></member>
<member><link linkend="beast.ref.boost__beast__is_const_buffer_sequence">is_const_buffer_sequence</link></member>
<member><link linkend="beast.ref.boost__beast__is_file">is_file</link></member> <member><link linkend="beast.ref.boost__beast__is_file">is_file</link></member>
<member><link linkend="beast.ref.boost__beast__is_mutable_buffer_sequence">is_mutable_buffer_sequence</link></member>
<member><link linkend="beast.ref.boost__beast__is_sync_read_stream">is_sync_read_stream</link></member> <member><link linkend="beast.ref.boost__beast__is_sync_read_stream">is_sync_read_stream</link></member>
<member><link linkend="beast.ref.boost__beast__is_sync_stream">is_sync_stream</link></member> <member><link linkend="beast.ref.boost__beast__is_sync_stream">is_sync_stream</link></member>
<member><link linkend="beast.ref.boost__beast__is_sync_write_stream">is_sync_write_stream</link></member> <member><link linkend="beast.ref.boost__beast__is_sync_write_stream">is_sync_write_stream</link></member>

View File

@ -12,24 +12,62 @@
#include <boost/beast/core/detail/config.hpp> #include <boost/beast/core/detail/config.hpp>
#include <boost/asio/buffer.hpp> #include <boost/asio/buffer.hpp>
#include <boost/mp11/function.hpp>
#include <type_traits> #include <type_traits>
namespace boost { namespace boost {
namespace beast { namespace beast {
/** Type alias used to obtain the underlying buffer type of a buffer sequence. /** Determine if a list of types satisfy the <em>ConstBufferSequence</em> 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<class... TN>
struct is_const_buffer_sequence : __see_below__ {};
//using is_const_buffer_sequence = __see_below__;
#else
template<class... TN>
using is_const_buffer_sequence = mp11::mp_all<
net::is_const_buffer_sequence<TN>...>;
#endif
/** Determine if a list of types satisfy the <em>MutableBufferSequence</em> 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<class... TN>
struct is_mutable_buffer_sequence : __see_below__ {};
//using is_mutable_buffer_sequence = __see_below__;
#else
template<class... TN>
using is_mutable_buffer_sequence = mp11::mp_all<
net::is_mutable_buffer_sequence<TN>...>;
#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 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: depending on the template type argument:
@li If the template argument is a <em>MutableBufferSequence</em>, @li If every type in the list is a <em>MutableBufferSequence</em>,
the resulting type alias will be `net::mutable_buffer`, else the resulting type alias will be `net::mutable_buffer`, otherwise
@li If the template argument is a <em>ConstBufferSequence</em>, @li The resulting type alias will be `net::const_buffer`.
the resulting type alias will be `net::const_buffer`, otherwise
@li The resulting type alias will be `void`.
@par Example @par Example
The following code returns the first buffer in a buffer sequence, The following code returns the first buffer in a buffer sequence,
@ -50,21 +88,19 @@ namespace beast {
} }
@endcode @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<class T> template<class... TN>
#if BOOST_BEAST_DOXYGEN #if BOOST_BEAST_DOXYGEN
struct buffers_type : __see_below__ {}; struct buffers_type : __see_below__ {};
//using buffers_type = __see_below__; //using buffers_type = __see_below__;
#else #else
using buffers_type = typename using buffers_type = typename
std::conditional< std::conditional<
net::is_mutable_buffer_sequence<T>::value, is_mutable_buffer_sequence<TN...>::value,
net::mutable_buffer, net::mutable_buffer,
typename std::conditional< net::const_buffer>::type;
net::is_const_buffer_sequence<T>::value,
net::const_buffer,
void>::type>::type;
#endif #endif
} // beast } // beast

View File

@ -10,30 +10,139 @@
// Test that header file is self-contained. // Test that header file is self-contained.
#include <boost/beast/core/buffer_traits.hpp> #include <boost/beast/core/buffer_traits.hpp>
#include <boost/beast/_experimental/unit_test/suite.hpp>
#include <array> #include <array>
namespace boost { namespace boost {
namespace beast { namespace beast {
BOOST_STATIC_ASSERT( class buffer_traits_test : public beast::unit_test::suite
std::is_same<net::const_buffer, {
buffers_type<net::const_buffer>>::value); public:
// is_const_buffer_sequence
BOOST_STATIC_ASSERT( BOOST_STATIC_ASSERT(is_const_buffer_sequence<
std::is_same<net::mutable_buffer, >::value);
buffers_type<net::mutable_buffer>>::value);
BOOST_STATIC_ASSERT( BOOST_STATIC_ASSERT(is_const_buffer_sequence<
std::is_same<net::const_buffer, net::const_buffer
buffers_type<std::array<net::const_buffer, 3>>>::value); >::value);
BOOST_STATIC_ASSERT( BOOST_STATIC_ASSERT(is_const_buffer_sequence<
std::is_same<net::mutable_buffer, net::const_buffer, net::const_buffer
buffers_type<std::array<net::mutable_buffer, 3>>>::value); >::value);
BOOST_STATIC_ASSERT( BOOST_STATIC_ASSERT(is_const_buffer_sequence<
std::is_same<void, net::const_buffer, net::mutable_buffer
buffers_type<std::array<int, 3>>>::value); >::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<net::const_buffer, buffers_type<
net::const_buffer
>>::value);
BOOST_STATIC_ASSERT(
std::is_same<net::const_buffer, buffers_type<
net::const_buffer, net::const_buffer
>>::value);
BOOST_STATIC_ASSERT(
std::is_same<net::const_buffer, buffers_type<
net::const_buffer, net::mutable_buffer
>>::value);
BOOST_STATIC_ASSERT(
std::is_same<net::mutable_buffer, buffers_type<
>>::value);
BOOST_STATIC_ASSERT(
std::is_same<net::mutable_buffer, buffers_type<
net::mutable_buffer
>>::value);
BOOST_STATIC_ASSERT(
std::is_same<net::mutable_buffer, buffers_type<
net::mutable_buffer, net::mutable_buffer
>>::value);
BOOST_STATIC_ASSERT(
std::is_same<net::const_buffer, buffers_type<
std::array<net::const_buffer, 3>
>>::value);
BOOST_STATIC_ASSERT(
std::is_same<net::mutable_buffer, buffers_type<
std::array<net::mutable_buffer, 3>
>>::value);
BOOST_STATIC_ASSERT(
std::is_same<net::const_buffer, buffers_type<
std::array<int, 3>
>>::value);
// javadoc: buffers_type
template <class BufferSequence>
buffers_type <BufferSequence>
buffers_front (BufferSequence const& buffers)
{
static_assert(
net::is_const_buffer_sequence<BufferSequence>::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 } // beast
} // boost } // boost