diff --git a/CHANGELOG.md b/CHANGELOG.md index 182d7a50..2bd3fdd4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,14 @@ Version 210: * Add stream_traits.hpp * Add executor_type trait +API Changes: + +* Stream traits are now in stream_traits.hpp + +Actions Required: + +* Include the file stream_traits.hpp as needed + -------------------------------------------------------------------------------- Version 209: diff --git a/doc/qbk/release_notes.qbk b/doc/qbk/release_notes.qbk index 865797d7..e9723f1e 100644 --- a/doc/qbk/release_notes.qbk +++ b/doc/qbk/release_notes.qbk @@ -32,21 +32,31 @@ New websocket-chat-multi example [/* `BASIC_TIMEOUT_STREAM` TODO] -* ([issue 1305]) Better `flat_buffer`, `flat_static_buffer`, `multi_buffer`, and `static_buffer`: +* ([issue 1305]) Better + `flat_buffer`, + `flat_static_buffer`, + `multi_buffer`, and + `static_buffer`: * Revise all reference documentation * Move construction does not always invalidate buffers * non-const `data()` returns a mutable buffer sequence * Add `cdata()` to also return constant readable bytes * Eligible member functions are declared `noexcept` -* ([issue 1345]) Better `flat_buffer`, `multi_buffer` +* ([issue 1345]) Better + `flat_buffer`, + `multi_buffer` * Add `clear`, `reserve()`, `max_size()`, `shrink_to_fit()` * Respect Allocator `max_size()` * Specify exception safety -* ([issue 1384]) New functions `bind_back_handler`, `bind_front_handler` +* ([issue 1384]) New functions + `bind_back_handler`, + `bind_front_handler` -* Better `static_buffer`, `flat_static_buffer` +* Better + `static_buffer`, + `flat_static_buffer` * Add `clear()` * More members are `noexcept` * Specify exception safety @@ -56,23 +66,32 @@ New websocket-chat-multi example * New file * New variadic `is_const_buffer_sequence` * New variadic `is_mutable_buffer_sequence` - * New `buffers_iterator_type` trait - * New `buffers_type` trait + * New trait `buffers_iterator_type` + * New trait `buffers_type` -* New classes `async_op_base` and `stable_async_op_base` +* New classes + `async_op_base`, + `stable_async_op_base` * Handle boilerplate for writing composed operations - * New `allocate_stable` is preferred over `handler_ptr` + * New + `allocate_stable` + is preferred over `handler_ptr` -* New `buffer_size` replacement for `net::buffer_size` +* New + `buffer_size` + replacement for `net::buffer_size` * New: * `saved_handler` * `buffers_range_ref` * `dynamic_buffer_ref` * `executor_type` - * `get_lowest_layer` and `lowest_layer_type` - * `close_socket` and `beast_close_socket` - * `error` and `condition` + * `get_lowest_layer`, + `lowest_layer_type` + * `close_socket`, + `beast_close_socket` + * `error`, + `condition` [*API Changes] @@ -80,38 +99,64 @@ New websocket-chat-multi example from the stream. Previously, they returned the number of bytes consumed by the parser. ['Actions Required]: - * Callers depending on the return value of `http::read` or - `http::async_read` overloads should adjust the usage of + * Callers depending on the return value of + `http::read` or + `http::async_read` + overloads should adjust the usage of the returned value as needed. -* `flat_static_buffer::reset()` is deprecated. - ['Actions Required]: - * call `clear()` instead. +* Metafunctions + `has_get_executor`, + `is_sync_stream`, + `is_sync_read_stream`, + `is_sync_write_stream`, + `is_async_stream`, + `is_async_read_stream`, and + `is_async_write_stream` + are now located in stream_traits.hpp. + ['Actions Required]: Include stream_traits.hpp as needed. -* `buffers_adapter` is now called `buffers_adaptor`. +* `flat_static_buffer::reset()` + is deprecated. ['Actions Required]: - * Replace `buffers_adapter` with `buffers_adaptor`, or define - `BOOST_BEAST_ALLOW_DEPRECATED`. + * call + `clear()` instead. -* `buffers` is now called `make_printable`. +* `buffers_adapter` is now spelled + `buffers_adaptor`. ['Actions Required]: - * Replace `buffers` with `make_printable`, and include - "make_printable.hpp" instead of "ostream.hpp". + * Replace `buffers_adapter` with + `buffers_adaptor`, + or define `BOOST_BEAST_ALLOW_DEPRECATED`. + +* `buffers` is now spelled + `make_printable`. + ['Actions Required]: + * Replace `buffers` with + `make_printable`, + and include "make_printable.hpp" instead of "ostream.hpp". * `file_mode::append_new` is removed, as it makes no sense. ['Actions Required]: - - Replace `file_mode::append_new` with either `file_mode::append` - or `file_mode::append_existing` as needed. + - Replace `file_mode::append_new` with either + `file_mode::append` or + `file_mode::append_existing` + as needed. -* `buffers_range_ref` is preferred to `std::reference_wrapper`. +* `buffers_range_ref` + is preferred to `std::reference_wrapper`. ['Actions Required]: - - Call `buffers_range_ref` with the buffer, instead of calling - `buffers_range` with a reference wrapper constructed from - the buffer. + - Call + `buffers_range_ref` + with the buffer, instead of calling + `buffers_range` + with a reference wrapper constructed from the buffer. * Nested `lowest_layer` and `lowest_layer_type` are removed. - ['Actions Required]: Use the free function `get_lowest_layer` and the - type trait `lowest_layer_type` instead. + ['Actions Required]: Use the free function + `get_lowest_layer` and the + type trait + `lowest_layer_type` instead. [*Examples] @@ -119,9 +164,10 @@ New websocket-chat-multi example * ([issue 1347]) Improve echo-op -* ([issue 1401]) Examples use `flat_buffer` +* ([issue 1401]) Examples use + `flat_buffer` -* New websocket-chat-multi example +* New example [[source_file example/websocket/server/chat-multi]] * `async_echo` works with move-only handlers @@ -129,33 +175,42 @@ New websocket-chat-multi example * ([issue 1223]) HTTP read counts bytes correctly when an error occurs -* ([issue 1247]) Update `ssl_stream` for Asio changes +* ([issue 1247]) Update `ssl_stream` + for Asio changes -* ([issue 1279]) Enable explicit instantiations of `websocket::stream` +* ([issue 1279]) Enable explicit instantiations of + `websocket::stream` * ([issue 1290]) Don't use deprecated Asio interfaces -* ([issue 1306]) `http::message` is not-a `boost::empty_value` +* ([issue 1306]) `http::message` + is not-a `boost::empty_value` -* ([issue 1306]) `test::stream` has fewer dependencies +* ([issue 1306]) `test::stream` + has fewer dependencies * ([issue 1365]) Handler wrappers decay parameters sooner -* ([issue 1408]) `session_alloc` is thread-safe +* ([issue 1408]) `session_alloc` + is thread-safe * ([issue 1414]) Boost.System is header-only -* ([issue 1418]) `test::stream` maintains a handler work guard +* ([issue 1418]) `test::stream` + maintains a handler work guard -* `buffers_cat` correctly skips empty buffers when iterated +* `buffers_cat` + correctly skips empty buffers when iterated -* `ostream` does not overflow or exceed the dynamic buffer's maximum size +* `ostream` + does not overflow or exceed the dynamic buffer's maximum size * A handler work guard is maintained on paused websocket operations * All behavior of default-constructed iterators is conforming -* `file_mode::append_existing` works correctly +* `file_mode::append_existing` + works correctly [/-----------------------------------------------------------------------------] diff --git a/include/boost/beast/core/buffer_size.hpp b/include/boost/beast/core/buffer_size.hpp index 36d1f1e4..ffaa6910 100644 --- a/include/boost/beast/core/buffer_size.hpp +++ b/include/boost/beast/core/buffer_size.hpp @@ -14,7 +14,7 @@ #include #include #include -#include +#include #include namespace boost { diff --git a/include/boost/beast/core/detail/impl/read.hpp b/include/boost/beast/core/detail/impl/read.hpp index 89b6ed10..e6b0bb56 100644 --- a/include/boost/beast/core/detail/impl/read.hpp +++ b/include/boost/beast/core/detail/impl/read.hpp @@ -13,7 +13,6 @@ #include #include #include -#include #include #include #include diff --git a/include/boost/beast/core/detail/read.hpp b/include/boost/beast/core/detail/read.hpp index fe092e65..2f425030 100644 --- a/include/boost/beast/core/detail/read.hpp +++ b/include/boost/beast/core/detail/read.hpp @@ -12,7 +12,7 @@ #include #include -#include +#include #include #include diff --git a/include/boost/beast/core/detail/stream_traits.hpp b/include/boost/beast/core/detail/stream_traits.hpp index 90e1fcf4..c825b2c8 100644 --- a/include/boost/beast/core/detail/stream_traits.hpp +++ b/include/boost/beast/core/detail/stream_traits.hpp @@ -10,6 +10,8 @@ #ifndef BOOST_BEAST_DETAIL_STREAM_TRAITS_HPP #define BOOST_BEAST_DETAIL_STREAM_TRAITS_HPP +#include +#include #include #include @@ -25,13 +27,11 @@ namespace detail { // template -std::false_type has_next_layer_impl(void*) {} +std::false_type has_next_layer_impl(void*); template auto has_next_layer_impl(decltype(nullptr)) -> - decltype(std::declval().next_layer(), std::true_type{}) -{ -} + decltype(std::declval().next_layer(), std::true_type{}); template using has_next_layer = decltype(has_next_layer_impl(nullptr)); @@ -73,6 +73,37 @@ get_lowest_layer_impl( //------------------------------------------------------------------------------ +// Types that meet the requirements, +// for use with std::declval only. +template +struct BufferSequence +{ + using value_type = BufferType; + using const_iterator = BufferType const*; + ~BufferSequence(); + BufferSequence(BufferSequence const&) = default; + const_iterator begin() const noexcept; + const_iterator end() const noexcept; +}; +using ConstBufferSequence = + BufferSequence; +using MutableBufferSequence = + BufferSequence; + +// + +// Types that meet the requirements, +// for use with std::declval only. +struct StreamHandler +{ + StreamHandler(StreamHandler const&) = default; + void operator()(error_code ec, std::size_t); +}; +using ReadHandler = StreamHandler; +using WriteHandler = StreamHandler; + +//------------------------------------------------------------------------------ + } // detail } // beast } // boost diff --git a/include/boost/beast/core/detail/type_traits.hpp b/include/boost/beast/core/detail/type_traits.hpp index a6d8f305..fbe4cf0d 100644 --- a/include/boost/beast/core/detail/type_traits.hpp +++ b/include/boost/beast/core/detail/type_traits.hpp @@ -13,7 +13,7 @@ #include #include #include -#include +#include #include #include #include @@ -161,39 +161,6 @@ struct is_contiguous_container -struct BufferSequence -{ - using value_type = BufferType; - using const_iterator = BufferType const*; - ~BufferSequence(); - BufferSequence(BufferSequence const&) = default; - const_iterator begin() const noexcept; - const_iterator end() const noexcept; -}; -using ConstBufferSequence = - BufferSequence; -using MutableBufferSequence = - BufferSequence; - -// - -// Types that meet the requirements, -// for use with std::declval only. -struct StreamHandler -{ - StreamHandler(StreamHandler const&) = default; - void operator()(error_code ec, std::size_t); -}; -using ReadHandler = StreamHandler; -using WriteHandler = StreamHandler; - /* If this static assert goes off, it means that the completion handler you provided to an asynchronous initiating function did not have the right signature. Check the parameter types for your diff --git a/include/boost/beast/core/stream_traits.hpp b/include/boost/beast/core/stream_traits.hpp index b6b3e801..ad169818 100644 --- a/include/boost/beast/core/stream_traits.hpp +++ b/include/boost/beast/core/stream_traits.hpp @@ -1,5 +1,5 @@ // -// Copyright (c) 2018 Vinnie Falco (vinnie dot falco at gmail dot com) +// Copyright (c) 2019 Vinnie Falco (vinnie dot falco at gmail dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -87,6 +87,8 @@ get_lowest_layer(T& t) noexcept t, detail::has_next_layer{}); } +//------------------------------------------------------------------------------ + /** A trait to determine the return type of get_executor. This type alias will be the type of values returned by @@ -110,6 +112,318 @@ using executor_type = decltype(std::declval().get_executor()); #endif +/** Determine if `T` has the `get_executor` member function. + + Metafunctions are used to perform compile time checking of template + types. This type will be `std::true_type` if `T` has the member + function with the correct signature, else type will be `std::false_type`. + + @par Example + + Use with tag dispatching: + + @code + template + void maybe_hello(T const& t, std::true_type) + { + net::post( + t.get_executor(), + [] + { + std::cout << "Hello, world!" << std::endl; + }); + } + + template + void maybe_hello(T const&, std::false_type) + { + // T does not have get_executor + } + + template + void maybe_hello(T const& t) + { + maybe_hello(t, has_get_executor{}); + } + @endcode + + Use with `static_assert`: + + @code + struct stream + { + using executor_type = net::io_context::executor_type; + executor_type get_executor() noexcept; + }; + + static_assert(has_get_executor::value, "Missing get_executor member"); + @endcode +*/ +#if BOOST_BEAST_DOXYGEN +template +struct has_get_executor : std::integral_constant{}; +#else +template +struct has_get_executor : std::false_type {}; + +template +struct has_get_executor().get_executor())>> : std::true_type {}; +#endif + +//------------------------------------------------------------------------------ + +/** Determine if `T` meets the requirements of @b SyncReadStream. + + Metafunctions are used to perform compile time checking of template + types. This type will be `std::true_type` if `T` meets the requirements, + else the type will be `std::false_type`. + + @par Example + + Use with `static_assert`: + + @code + template + void f(SyncReadStream& stream) + { + static_assert(is_sync_read_stream::value, + "SyncReadStream requirements not met"); + ... + @endcode + + Use with `std::enable_if` (SFINAE): + + @code + template + typename std::enable_if::value>::type + f(SyncReadStream& stream); + @endcode +*/ +#if BOOST_BEAST_DOXYGEN +template +struct is_sync_read_stream : std::integral_constant{}; +#else +template +struct is_sync_read_stream : std::false_type {}; + +template +struct is_sync_read_stream() = std::declval().read_some( + std::declval()), + std::declval() = std::declval().read_some( + std::declval(), + std::declval()) + )>> : std::true_type {}; +#endif + +/** Determine if `T` meets the requirements of @b SyncWriteStream. + + Metafunctions are used to perform compile time checking of template + types. This type will be `std::true_type` if `T` meets the requirements, + else the type will be `std::false_type`. + + @par Example + + Use with `static_assert`: + + @code + template + void f(SyncReadStream& stream) + { + static_assert(is_sync_read_stream::value, + "SyncReadStream requirements not met"); + ... + @endcode + + Use with `std::enable_if` (SFINAE): + + @code + template + typename std::enable_if::value>::type + f(SyncReadStream& stream); + @endcode +*/ +#if BOOST_BEAST_DOXYGEN +template +struct is_sync_write_stream : std::integral_constant{}; +#else +template +struct is_sync_write_stream : std::false_type {}; + +template +struct is_sync_write_stream() = std::declval().write_some( + std::declval())) + ,std::declval() = std::declval().write_some( + std::declval(), + std::declval()) + )>> : std::true_type {}; +#endif + +/** Determine if `T` meets the requirements of @b SyncStream. + + Metafunctions are used to perform compile time checking of template + types. This type will be `std::true_type` if `T` meets the requirements, + else the type will be `std::false_type`. + + @par Example + + Use with `static_assert`: + + @code + template + void f(SyncStream& stream) + { + static_assert(is_sync_stream::value, + "SyncStream requirements not met"); + ... + @endcode + + Use with `std::enable_if` (SFINAE): + + @code + template + typename std::enable_if::value>::type + f(SyncStream& stream); + @endcode +*/ +#if BOOST_BEAST_DOXYGEN +template +struct is_sync_stream : std::integral_constant{}; +#else +template +using is_sync_stream = std::integral_constant::value && is_sync_write_stream::value>; +#endif + +//------------------------------------------------------------------------------ + +/** Determine if `T` meets the requirements of @b AsyncReadStream. + + Metafunctions are used to perform compile time checking of template + types. This type will be `std::true_type` if `T` meets the requirements, + else the type will be `std::false_type`. + + @par Example + + Use with `static_assert`: + + @code + template + void f(AsyncReadStream& stream) + { + static_assert(is_async_read_stream::value, + "AsyncReadStream requirements not met"); + ... + @endcode + + Use with `std::enable_if` (SFINAE): + + @code + template + typename std::enable_if::value>::type + f(AsyncReadStream& stream); + @endcode +*/ +#if BOOST_BEAST_DOXYGEN +template +struct is_async_read_stream : std::integral_constant{}; +#else +template +struct is_async_read_stream : std::false_type {}; + +template +struct is_async_read_stream().async_read_some( + std::declval(), + std::declval()) + )>> : std::integral_constant::value + > {}; +#endif + +/** Determine if `T` meets the requirements of @b AsyncWriteStream. + + Metafunctions are used to perform compile time checking of template + types. This type will be `std::true_type` if `T` meets the requirements, + else the type will be `std::false_type`. + + @par Example + + Use with `static_assert`: + + @code + template + void f(AsyncWriteStream& stream) + { + static_assert(is_async_write_stream::value, + "AsyncWriteStream requirements not met"); + ... + @endcode + + Use with `std::enable_if` (SFINAE): + + @code + template + typename std::enable_if::value>::type + f(AsyncWriteStream& stream); + @endcode +*/ +#if BOOST_BEAST_DOXYGEN +template +struct is_async_write_stream : std::integral_constant{}; +#else +template +struct is_async_write_stream : std::false_type {}; + +template +struct is_async_write_stream().async_write_some( + std::declval(), + std::declval()) + )>> : std::integral_constant::value + > {}; +#endif + +/** Determine if `T` meets the requirements of @b AsyncStream. + + Metafunctions are used to perform compile time checking of template + types. This type will be `std::true_type` if `T` meets the requirements, + else the type will be `std::false_type`. + + @par Example + + Use with `static_assert`: + + @code + template + void f(AsyncStream& stream) + { + static_assert(is_async_stream::value, + "AsyncStream requirements not met"); + ... + @endcode + + Use with `std::enable_if` (SFINAE): + + @code + template + typename std::enable_if::value>::type + f(AsyncStream& stream); + @endcode +*/ +#if BOOST_BEAST_DOXYGEN +template +struct is_async_stream : std::integral_constant{}; +#else +template +using is_async_stream = std::integral_constant::value && is_async_write_stream::value>; +#endif + } // beast } // boost diff --git a/include/boost/beast/core/type_traits.hpp b/include/boost/beast/core/type_traits.hpp index 17c91d5e..eeafb8c4 100644 --- a/include/boost/beast/core/type_traits.hpp +++ b/include/boost/beast/core/type_traits.hpp @@ -56,320 +56,6 @@ using is_completion_handler = std::integral_constant::value>; #endif -//------------------------------------------------------------------------------ -// -// Stream concepts -// -//------------------------------------------------------------------------------ - -/** Determine if `T` has the `get_executor` member function. - - Metafunctions are used to perform compile time checking of template - types. This type will be `std::true_type` if `T` has the member - function with the correct signature, else type will be `std::false_type`. - - @par Example - - Use with tag dispatching: - - @code - template - void maybe_hello(T& t, std::true_type) - { - net::post( - t.get_executor(), - [] - { - std::cout << "Hello, world!" << std::endl; - }); - } - - template - void maybe_hello(T&, std::false_type) - { - // T does not have get_executor - } - - template - void maybe_hello(T& t) - { - maybe_hello(t, has_get_executor{}); - } - @endcode - - Use with `static_assert`: - - @code - struct stream - { - using executor_type = net::io_context::executor_type; - executor_type get_executor() noexcept; - }; - - static_assert(has_get_executor::value, "Missing get_executor member"); - @endcode -*/ -#if BOOST_BEAST_DOXYGEN -template -struct has_get_executor : std::integral_constant{}; -#else -template -struct has_get_executor : std::false_type {}; - -template -struct has_get_executor().get_executor())>> : std::true_type {}; -#endif - -/** Determine if `T` meets the requirements of @b AsyncReadStream. - - Metafunctions are used to perform compile time checking of template - types. This type will be `std::true_type` if `T` meets the requirements, - else the type will be `std::false_type`. - - @par Example - - Use with `static_assert`: - - @code - template - void f(AsyncReadStream& stream) - { - static_assert(is_async_read_stream::value, - "AsyncReadStream requirements not met"); - ... - @endcode - - Use with `std::enable_if` (SFINAE): - - @code - template - typename std::enable_if::value>::type - f(AsyncReadStream& stream); - @endcode -*/ -#if BOOST_BEAST_DOXYGEN -template -struct is_async_read_stream : std::integral_constant{}; -#else -template -struct is_async_read_stream : std::false_type {}; - -template -struct is_async_read_stream().async_read_some( - std::declval(), - std::declval()) - )>> : std::integral_constant::value - > {}; -#endif - -/** Determine if `T` meets the requirements of @b AsyncWriteStream. - - Metafunctions are used to perform compile time checking of template - types. This type will be `std::true_type` if `T` meets the requirements, - else the type will be `std::false_type`. - - @par Example - - Use with `static_assert`: - - @code - template - void f(AsyncWriteStream& stream) - { - static_assert(is_async_write_stream::value, - "AsyncWriteStream requirements not met"); - ... - @endcode - - Use with `std::enable_if` (SFINAE): - - @code - template - typename std::enable_if::value>::type - f(AsyncWriteStream& stream); - @endcode -*/ -#if BOOST_BEAST_DOXYGEN -template -struct is_async_write_stream : std::integral_constant{}; -#else -template -struct is_async_write_stream : std::false_type {}; - -template -struct is_async_write_stream().async_write_some( - std::declval(), - std::declval()) - )>> : std::integral_constant::value - > {}; -#endif - -/** Determine if `T` meets the requirements of @b SyncReadStream. - - Metafunctions are used to perform compile time checking of template - types. This type will be `std::true_type` if `T` meets the requirements, - else the type will be `std::false_type`. - - @par Example - - Use with `static_assert`: - - @code - template - void f(SyncReadStream& stream) - { - static_assert(is_sync_read_stream::value, - "SyncReadStream requirements not met"); - ... - @endcode - - Use with `std::enable_if` (SFINAE): - - @code - template - typename std::enable_if::value>::type - f(SyncReadStream& stream); - @endcode -*/ -#if BOOST_BEAST_DOXYGEN -template -struct is_sync_read_stream : std::integral_constant{}; -#else -template -struct is_sync_read_stream : std::false_type {}; - -template -struct is_sync_read_stream() = std::declval().read_some( - std::declval()), - std::declval() = std::declval().read_some( - std::declval(), - std::declval()) - )>> : std::true_type {}; -#endif - -/** Determine if `T` meets the requirements of @b SyncWriteStream. - - Metafunctions are used to perform compile time checking of template - types. This type will be `std::true_type` if `T` meets the requirements, - else the type will be `std::false_type`. - - @par Example - - Use with `static_assert`: - - @code - template - void f(SyncReadStream& stream) - { - static_assert(is_sync_read_stream::value, - "SyncReadStream requirements not met"); - ... - @endcode - - Use with `std::enable_if` (SFINAE): - - @code - template - typename std::enable_if::value>::type - f(SyncReadStream& stream); - @endcode -*/ -#if BOOST_BEAST_DOXYGEN -template -struct is_sync_write_stream : std::integral_constant{}; -#else -template -struct is_sync_write_stream : std::false_type {}; - -template -struct is_sync_write_stream() = std::declval().write_some( - std::declval())) - ,std::declval() = std::declval().write_some( - std::declval(), - std::declval()) - )>> : std::true_type {}; -#endif - -/** Determine if `T` meets the requirements of @b AsyncStream. - - Metafunctions are used to perform compile time checking of template - types. This type will be `std::true_type` if `T` meets the requirements, - else the type will be `std::false_type`. - - @par Example - - Use with `static_assert`: - - @code - template - void f(AsyncStream& stream) - { - static_assert(is_async_stream::value, - "AsyncStream requirements not met"); - ... - @endcode - - Use with `std::enable_if` (SFINAE): - - @code - template - typename std::enable_if::value>::type - f(AsyncStream& stream); - @endcode -*/ -#if BOOST_BEAST_DOXYGEN -template -struct is_async_stream : std::integral_constant{}; -#else -template -using is_async_stream = std::integral_constant::value && is_async_write_stream::value>; -#endif - -/** Determine if `T` meets the requirements of @b SyncStream. - - Metafunctions are used to perform compile time checking of template - types. This type will be `std::true_type` if `T` meets the requirements, - else the type will be `std::false_type`. - - @par Example - - Use with `static_assert`: - - @code - template - void f(SyncStream& stream) - { - static_assert(is_sync_stream::value, - "SyncStream requirements not met"); - ... - @endcode - - Use with `std::enable_if` (SFINAE): - - @code - template - typename std::enable_if::value>::type - f(SyncStream& stream); - @endcode -*/ -#if BOOST_BEAST_DOXYGEN -template -struct is_sync_stream : std::integral_constant{}; -#else -template -using is_sync_stream = std::integral_constant::value && is_sync_write_stream::value>; -#endif - //------------------------------------------------------------------------------ // // File concepts diff --git a/test/beast/core/stream_tests.hpp b/test/beast/core/stream_tests.hpp index 7166ec84..b17c3dc9 100644 --- a/test/beast/core/stream_tests.hpp +++ b/test/beast/core/stream_tests.hpp @@ -12,7 +12,7 @@ #include #include -#include +#include #include #include #include diff --git a/test/beast/core/stream_traits.cpp b/test/beast/core/stream_traits.cpp index 3cd55ae7..d1aed4aa 100644 --- a/test/beast/core/stream_traits.cpp +++ b/test/beast/core/stream_traits.cpp @@ -13,6 +13,7 @@ #include #include #include +#include namespace boost { namespace beast { @@ -161,7 +162,7 @@ public: }; void - testJavadoc() + testGetLowestLayerJavadoc() { write_stream s; BOOST_STATIC_ASSERT( @@ -178,11 +179,102 @@ public: //-------------------------------------------------------------------------- + void + testExecutorType() + { + } + + void + testExecutorTypeJavadoc() + { + } + + //-------------------------------------------------------------------------- + + struct sync_read_stream + { + template + std::size_t + read_some(MutableBufferSequence const&); + + template + std::size_t + read_some(MutableBufferSequence const&, + error_code& ec); + }; + + struct sync_write_stream + { + template + std::size_t + write_some(ConstBufferSequence const&); + + template + std::size_t + write_some( + ConstBufferSequence const&, error_code&); + }; + + struct async_read_stream + { + net::io_context::executor_type + get_executor(); + + template + void + async_read_some( + MutableBufferSequence const&, ReadHandler&&); + }; + + struct async_write_stream + { + net::io_context::executor_type + get_executor(); + + template + void + async_write_some( + ConstBufferSequence const&, WriteHandler&&); + }; + + struct sync_stream : sync_read_stream, sync_write_stream + { + }; + + struct async_stream : async_read_stream, async_write_stream + { + using async_read_stream::get_executor; + }; + + BOOST_STATIC_ASSERT(is_sync_read_stream::value); + BOOST_STATIC_ASSERT(is_sync_write_stream::value); + BOOST_STATIC_ASSERT(is_sync_read_stream::value); + BOOST_STATIC_ASSERT(is_sync_write_stream::value); + BOOST_STATIC_ASSERT(is_sync_stream::value); + + BOOST_STATIC_ASSERT(is_async_read_stream::value); + BOOST_STATIC_ASSERT(is_async_write_stream::value); + BOOST_STATIC_ASSERT(is_async_read_stream::value); + BOOST_STATIC_ASSERT(is_async_write_stream::value); + BOOST_STATIC_ASSERT(is_async_stream::value); + + BOOST_STATIC_ASSERT(! is_sync_read_stream::value); + BOOST_STATIC_ASSERT(! is_sync_write_stream::value); + BOOST_STATIC_ASSERT(! is_async_read_stream::value); + BOOST_STATIC_ASSERT(! is_async_write_stream::value); + + BOOST_STATIC_ASSERT(! is_sync_stream::value); + BOOST_STATIC_ASSERT(! is_async_stream::value); + + //-------------------------------------------------------------------------- + void run() override { testGetLowestLayer(); - testJavadoc(); + testGetLowestLayerJavadoc(); + testExecutorType(); + testExecutorTypeJavadoc(); } }; diff --git a/test/beast/core/type_traits.cpp b/test/beast/core/type_traits.cpp index dbfdc5bf..9671afcc 100644 --- a/test/beast/core/type_traits.cpp +++ b/test/beast/core/type_traits.cpp @@ -79,80 +79,5 @@ struct H BOOST_STATIC_ASSERT(is_completion_handler::value); BOOST_STATIC_ASSERT(! is_completion_handler::value); -// -// stream concepts -// - -struct sync_write_stream -{ - net::io_context& - get_io_service(); - - template - std::size_t - write_some(ConstBufferSequence const& buffers); - - template - std::size_t - write_some( - ConstBufferSequence const& buffers, error_code& ec); -}; - -struct sync_read_stream -{ - template - std::size_t - read_some(MutableBufferSequence const& buffers); - - template - std::size_t - read_some(MutableBufferSequence const& buffers, - error_code& ec); -}; - -struct sync_stream : sync_read_stream, sync_write_stream -{ -}; - -BOOST_STATIC_ASSERT(! is_sync_read_stream::value); -BOOST_STATIC_ASSERT(! is_sync_write_stream::value); - -BOOST_STATIC_ASSERT(is_sync_read_stream::value); -BOOST_STATIC_ASSERT(is_sync_write_stream::value); - -BOOST_STATIC_ASSERT(is_sync_read_stream::value); -BOOST_STATIC_ASSERT(is_sync_write_stream::value); - -namespace { - -using stream_type = net::ip::tcp::socket; - -struct not_a_stream -{ - void - get_io_service(); -}; - -BOOST_STATIC_ASSERT(has_get_executor::value); -BOOST_STATIC_ASSERT(is_async_read_stream::value); -BOOST_STATIC_ASSERT(is_async_write_stream::value); -BOOST_STATIC_ASSERT(is_async_stream::value); -BOOST_STATIC_ASSERT(is_sync_read_stream::value); -BOOST_STATIC_ASSERT(is_sync_write_stream::value); -BOOST_STATIC_ASSERT(is_sync_stream::value); - -BOOST_STATIC_ASSERT(! has_get_executor::value); -BOOST_STATIC_ASSERT(! is_async_read_stream::value); -BOOST_STATIC_ASSERT(! is_async_write_stream::value); -BOOST_STATIC_ASSERT(! is_sync_read_stream::value); -BOOST_STATIC_ASSERT(! is_sync_write_stream::value); - -BOOST_STATIC_ASSERT(is_sync_read_stream::value); -BOOST_STATIC_ASSERT(is_sync_write_stream::value); -BOOST_STATIC_ASSERT(is_async_read_stream::value); -BOOST_STATIC_ASSERT(is_async_write_stream::value); - -} // (anonymous) - } // beast } // boost