diff --git a/CHANGELOG.md b/CHANGELOG.md index d74e6bfc..4ac1a815 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +Version 201 + +* Decay bound arguments in handler wrapper parameters + +-------------------------------------------------------------------------------- + Version 200 * Don't include OpenSSL for core snippets diff --git a/include/boost/beast/core/bind_handler.hpp b/include/boost/beast/core/bind_handler.hpp index de4331f8..d9be4088 100644 --- a/include/boost/beast/core/bind_handler.hpp +++ b/include/boost/beast/core/bind_handler.hpp @@ -31,16 +31,19 @@ namespace beast { handler, whose associated allocator and associated executor will will be the same as those of the original handler. - Example: + @par Example + + This function posts the invocation of the specified completion + handler with bound arguments: @code - template + template void - signal_aborted(AsyncReadStream& stream, ReadHandler&& handler) + signal_aborted (AsyncReadStream& stream, ReadHandler&& handler) { net::post( stream.get_executor(), - bind_handler(std::forward(handler), + bind_handler (std::forward (handler), net::error::operation_aborted, 0)); } @endcode @@ -57,7 +60,8 @@ template __implementation_defined__ #else detail::bind_wrapper< - typename std::decay::type, Args...> + typename std::decay::type, + typename std::decay::type...> #endif bind_handler(Handler&& handler, Args&&... args) { @@ -67,9 +71,11 @@ bind_handler(Handler&& handler, Args&&... args) Handler, void(Args...)>::value, "Handler requirements not met"); #endif - return detail::bind_wrapper::type, Args...>(std::forward< - Handler>(handler), std::forward(args)...); + return detail::bind_wrapper< + typename std::decay::type, + typename std::decay::type...>( + std::forward(handler), + std::forward(args)...); } /** Bind parameters to a completion handler, creating a new handler. @@ -83,17 +89,20 @@ bind_handler(Handler&& handler, Args&&... args) handler, whose associated allocator and associated executor will will be the same as those of the original handler. - Example: + @par Example + + This function posts the invocation of the specified completion + handler with bound arguments: @code - template + template void - signal_aborted(AsyncReadStream& stream, ReadHandler&& handler) + signal_eof (AsyncReadStream& stream, ReadHandler&& handler) { net::post( stream.get_executor(), - bind_front_handler(std::forward(handler), - net::error::operation_aborted, 0)); + bind_front_handler (std::forward (handler), + net::error::eof, 0)); } @endcode diff --git a/include/boost/beast/core/detail/bind_handler.hpp b/include/boost/beast/core/detail/bind_handler.hpp index f498318b..f30613b9 100644 --- a/include/boost/beast/core/detail/bind_handler.hpp +++ b/include/boost/beast/core/detail/bind_handler.hpp @@ -31,8 +31,7 @@ namespace detail { template class bind_wrapper { - using args_type = detail::tuple< - typename std::decay::type...>; + using args_type = detail::tuple; Handler h_; args_type args_; @@ -84,9 +83,7 @@ class bind_wrapper std::forward(vals)); } - template< - class ArgsTuple, - std::size_t... S> + template static void invoke( @@ -123,12 +120,15 @@ public: bind_wrapper(bind_wrapper&&) = default; bind_wrapper(bind_wrapper const&) = default; - template + template< + class DeducedHandler, + class... Args_> explicit bind_wrapper( - DeducedHandler&& handler, Args&&... args) + DeducedHandler&& handler, + Args_&&... args) : h_(std::forward(handler)) - , args_(std::forward(args)...) + , args_(std::forward(args)...) { } diff --git a/test/beast/core/bind_handler.cpp b/test/beast/core/bind_handler.cpp index 7a656937..ee981a7a 100644 --- a/test/beast/core/bind_handler.cpp +++ b/test/beast/core/bind_handler.cpp @@ -12,6 +12,7 @@ #include #include +#include #include #include #include @@ -41,6 +42,40 @@ public: } }; + template + void + signal_aborted (AsyncReadStream& stream, ReadHandler&& handler) + { + net::post( + stream.get_executor(), + bind_handler (std::forward (handler), + net::error::operation_aborted, 0)); + } + + template + void + signal_eof (AsyncReadStream& stream, ReadHandler&& handler) + { + net::post( + stream.get_executor(), + bind_front_handler (std::forward (handler), + net::error::eof, 0)); + } + + void + testJavadocs() + { + BEAST_EXPECT(( + &bind_handler_test::signal_aborted< + test::stream, handler>)); + + BEAST_EXPECT(( + &bind_handler_test::signal_eof< + test::stream, handler>)); + } + + //-------------------------------------------------------------------------- + struct copyable { template @@ -469,6 +504,7 @@ public: void run() override { + testJavadocs(); testBindHandler(); testBindFrontHandler(); }