From 1998bad89d2bd8c0020fb2f4c124b861af9b1d17 Mon Sep 17 00:00:00 2001 From: Vinnie Falco Date: Sat, 15 Dec 2018 10:59:00 -0800 Subject: [PATCH] Add const and mutable buffer sequence traits: * Add variadic is_const_buffer_sequence * Add variadic is_mutable_buffer_sequence * buffers_type is now variadic --- CHANGELOG.md | 1 + doc/qbk/03_core/3_buffers.qbk | 30 +++++ doc/qbk/quickref.xml | 2 + include/boost/beast/core/buffer_traits.hpp | 66 +++++++--- test/beast/core/buffer_traits.cpp | 139 ++++++++++++++++++--- 5 files changed, 208 insertions(+), 30 deletions(-) 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_stream is_async_stream is_completion_handler + is_const_buffer_sequence is_file + is_mutable_buffer_sequence is_sync_read_stream is_sync_stream is_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