diff --git a/CHANGELOG.md b/CHANGELOG.md index 623fa242..b6f294aa 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ Version 126: * Don't return end_of_stream on win32 file body writes * Fix doc typo * Fix shadowing in session_alloc +* Fix executor type compilation -------------------------------------------------------------------------------- diff --git a/example/common/detect_ssl.hpp b/example/common/detect_ssl.hpp index 6d031aa6..b7deba85 100644 --- a/example/common/detect_ssl.hpp +++ b/example/common/detect_ssl.hpp @@ -363,7 +363,7 @@ public: // final handler. using executor_type = boost::asio::associated_executor_t< - Handler, decltype(stream_.get_executor())>; + Handler, decltype(std::declval().get_executor())>; executor_type get_executor() const noexcept { diff --git a/example/common/session_alloc.hpp b/example/common/session_alloc.hpp index 2250b69d..7bd7a84e 100644 --- a/example/common/session_alloc.hpp +++ b/example/common/session_alloc.hpp @@ -222,6 +222,11 @@ dealloc(void* pv, std::size_t n) //------------------------------------------------------------------------------ +namespace detail { +template +class session_alloc_wrapper; +} // detail + template class session_alloc : private detail::session_alloc_base @@ -229,51 +234,6 @@ class session_alloc template friend class session_alloc; - template - class wrapped_handler - { - // Can't friend partial specializations, - // so we just friend the whole thing. - template - friend struct boost::asio::associated_executor; - - Handler h_; - session_alloc alloc_; - - public: - wrapped_handler(wrapped_handler&&) = default; - wrapped_handler(wrapped_handler const&) = default; - - template - wrapped_handler( - DeducedHandler&& h, - session_alloc const& alloc) - : h_(std::forward(h)) - , alloc_(alloc) - { - } - - using allocator_type = session_alloc; - - allocator_type - get_allocator() const noexcept; - - template - void - operator()(Args&&... args) const - { - h_(std::forward(args)...); - } - - friend - bool - asio_handler_is_continuation(wrapped_handler* w) - { - using boost::asio::asio_handler_is_continuation; - return asio_handler_is_continuation(std::addressof(w->h_)); - } - }; - using pool_t = typename detail::session_alloc_base::pool_t; @@ -319,7 +279,7 @@ public: } template - wrapped_handler::type> + detail::session_alloc_wrapper::type> wrap(Handler&& handler); value_type* @@ -387,17 +347,64 @@ protected: //------------------------------------------------------------------------------ -template +namespace detail { + +template +class session_alloc_wrapper +{ + // Can't friend partial specializations, + // so we just friend the whole thing. + template + friend struct boost::asio::associated_executor; + + Handler h_; + session_alloc alloc_; + +public: + session_alloc_wrapper(session_alloc_wrapper&&) = default; + session_alloc_wrapper(session_alloc_wrapper const&) = default; + + template + session_alloc_wrapper( + DeducedHandler&& h, + session_alloc const& alloc) + : h_(std::forward(h)) + , alloc_(alloc) + { + } + + using allocator_type = session_alloc; + + allocator_type + get_allocator() const noexcept; + + template + void + operator()(Args&&... args) const + { + h_(std::forward(args)...); + } + + friend + bool + asio_handler_is_continuation(session_alloc_wrapper* w) + { + using boost::asio::asio_handler_is_continuation; + return asio_handler_is_continuation(std::addressof(w->h_)); + } +}; + template auto -session_alloc:: -wrapped_handler:: +session_alloc_wrapper:: get_allocator() const noexcept -> allocator_type { return alloc_; } +} // detail + //------------------------------------------------------------------------------ template @@ -405,31 +412,34 @@ template auto session_alloc:: wrap(Handler&& handler) -> - wrapped_handler::type> + detail::session_alloc_wrapper::type> { - return wrapped_handler< + return detail::session_alloc_wrapper< typename std::decay::type>( std::forward(handler), *this); } +//------------------------------------------------------------------------------ + namespace boost { namespace asio { -template +template struct associated_executor< - session_alloc::wrapped_handler, Executor> + ::detail::session_alloc_wrapper, Executor> { using type = typename associated_executor::type; static type - get(session_alloc::wrapped_handler const& h, + get(::detail::session_alloc_wrapper const& h, Executor const& ex = Executor()) noexcept { return associated_executor< Handler, Executor>::get(h.h_, ex); } }; + } // asio } // boost diff --git a/example/common/ssl_stream.hpp b/example/common/ssl_stream.hpp index 90245c43..ad21880f 100644 --- a/example/common/ssl_stream.hpp +++ b/example/common/ssl_stream.hpp @@ -58,6 +58,9 @@ public: /// The type of the lowest layer. using lowest_layer_type = typename stream_type::lowest_layer_type; + /// The type of the executor associated with the object. + using executor_type = typename stream_type::executor_type; + ssl_stream( boost::asio::ip::tcp::socket socket, boost::asio::ssl::context& ctx) @@ -88,7 +91,7 @@ public: return *this; } - decltype(p_->get_executor()) + executor_type get_executor() noexcept { return p_->get_executor(); diff --git a/example/echo-op/echo_op.cpp b/example/echo-op/echo_op.cpp index 45024f3a..b7c7a16c 100644 --- a/example/echo-op/echo_op.cpp +++ b/example/echo-op/echo_op.cpp @@ -164,7 +164,7 @@ public: // final handler. using executor_type = boost::asio::associated_executor_t< - Handler, decltype(p_->stream.get_executor())>; + Handler, decltype(std::declval().get_executor())>; executor_type get_executor() const noexcept { diff --git a/include/boost/beast/core/impl/buffered_read_stream.ipp b/include/boost/beast/core/impl/buffered_read_stream.ipp index f88c2748..0afdfb64 100644 --- a/include/boost/beast/core/impl/buffered_read_stream.ipp +++ b/include/boost/beast/core/impl/buffered_read_stream.ipp @@ -58,10 +58,12 @@ public: return boost::asio::get_associated_allocator(h_); } - using executor_type = boost::asio::associated_executor_t< - Handler, decltype(s_.get_executor())>; + using executor_type = + boost::asio::associated_executor_t().get_executor())>; - executor_type get_executor() const noexcept + executor_type + get_executor() const noexcept { return boost::asio::get_associated_executor( h_, s_.get_executor()); diff --git a/include/boost/beast/http/impl/file_body_win32.ipp b/include/boost/beast/http/impl/file_body_win32.ipp index 0243732e..2d37b62b 100644 --- a/include/boost/beast/http/impl/file_body_win32.ipp +++ b/include/boost/beast/http/impl/file_body_win32.ipp @@ -367,10 +367,12 @@ public: return boost::asio::get_associated_allocator(h_); } - using executor_type = boost::asio::associated_executor_t< - Handler, decltype(sock_.get_executor())>; + using executor_type = + boost::asio::associated_executor_t&>().get_executor())>; - executor_type get_executor() const noexcept + executor_type + get_executor() const noexcept { return boost::asio::get_associated_executor( h_, sock_.get_executor()); diff --git a/include/boost/beast/http/impl/read.ipp b/include/boost/beast/http/impl/read.ipp index 7a639266..053a26c5 100644 --- a/include/boost/beast/http/impl/read.ipp +++ b/include/boost/beast/http/impl/read.ipp @@ -72,9 +72,10 @@ public: } using executor_type = boost::asio::associated_executor_t< - Handler, decltype(s_.get_executor())>; + Handler, decltype(std::declval().get_executor())>; - executor_type get_executor() const noexcept + executor_type + get_executor() const noexcept { return boost::asio::get_associated_executor( h_, s_.get_executor()); @@ -234,9 +235,10 @@ public: } using executor_type = boost::asio::associated_executor_t< - Handler, decltype(s_.get_executor())>; + Handler, decltype(std::declval().get_executor())>; - executor_type get_executor() const noexcept + executor_type + get_executor() const noexcept { return boost::asio::get_associated_executor( h_, s_.get_executor()); @@ -356,9 +358,10 @@ public: } using executor_type = boost::asio::associated_executor_t< - Handler, decltype(d_->s.get_executor())>; + Handler, decltype(std::declval().get_executor())>; - executor_type get_executor() const noexcept + executor_type + get_executor() const noexcept { return boost::asio::get_associated_executor( d_.handler(), d_->s.get_executor()); diff --git a/include/boost/beast/http/impl/write.ipp b/include/boost/beast/http/impl/write.ipp index 792045fc..7db5e6b3 100644 --- a/include/boost/beast/http/impl/write.ipp +++ b/include/boost/beast/http/impl/write.ipp @@ -88,9 +88,10 @@ public: } using executor_type = boost::asio::associated_executor_t< - Handler, decltype(s_.get_executor())>; + Handler, decltype(std::declval().get_executor())>; - executor_type get_executor() const noexcept + executor_type + get_executor() const noexcept { return boost::asio::get_associated_executor( h_, s_.get_executor()); @@ -223,9 +224,10 @@ public: } using executor_type = boost::asio::associated_executor_t< - Handler, decltype(s_.get_executor())>; + Handler, decltype(std::declval().get_executor())>; - executor_type get_executor() const noexcept + executor_type + get_executor() const noexcept { return boost::asio::get_associated_executor( h_, s_.get_executor()); @@ -335,9 +337,10 @@ public: } using executor_type = boost::asio::associated_executor_t< - Handler, decltype(d_->s.get_executor())>; + Handler, decltype(std::declval().get_executor())>; - executor_type get_executor() const noexcept + executor_type + get_executor() const noexcept { return boost::asio::get_associated_executor( d_.handler(), d_->s.get_executor()); diff --git a/include/boost/beast/websocket/impl/accept.ipp b/include/boost/beast/websocket/impl/accept.ipp index c6429382..29adfb00 100644 --- a/include/boost/beast/websocket/impl/accept.ipp +++ b/include/boost/beast/websocket/impl/accept.ipp @@ -78,9 +78,10 @@ public: } using executor_type = boost::asio::associated_executor_t< - Handler, decltype(d_->ws.get_executor())>; + Handler, decltype(std::declval&>().get_executor())>; - executor_type get_executor() const noexcept + executor_type + get_executor() const noexcept { return boost::asio::get_associated_executor( d_.handler(), d_->ws.get_executor()); @@ -173,9 +174,10 @@ public: } using executor_type = boost::asio::associated_executor_t< - Handler, decltype(d_->ws.get_executor())>; + Handler, decltype(std::declval&>().get_executor())>; - executor_type get_executor() const noexcept + executor_type + get_executor() const noexcept { return boost::asio::get_associated_executor( d_.handler(), d_->ws.get_executor()); diff --git a/include/boost/beast/websocket/impl/close.ipp b/include/boost/beast/websocket/impl/close.ipp index c5559b20..0349dd14 100644 --- a/include/boost/beast/websocket/impl/close.ipp +++ b/include/boost/beast/websocket/impl/close.ipp @@ -85,9 +85,10 @@ public: } using executor_type = boost::asio::associated_executor_t< - Handler, decltype(d_->ws.get_executor())>; + Handler, decltype(std::declval&>().get_executor())>; - executor_type get_executor() const noexcept + executor_type + get_executor() const noexcept { return boost::asio::get_associated_executor( d_.handler(), d_->ws.get_executor()); diff --git a/include/boost/beast/websocket/impl/handshake.ipp b/include/boost/beast/websocket/impl/handshake.ipp index dc22bfb3..cdd8d473 100644 --- a/include/boost/beast/websocket/impl/handshake.ipp +++ b/include/boost/beast/websocket/impl/handshake.ipp @@ -85,9 +85,10 @@ public: } using executor_type = boost::asio::associated_executor_t< - Handler, decltype(d_->ws.get_executor())>; + Handler, decltype(std::declval&>().get_executor())>; - executor_type get_executor() const noexcept + executor_type + get_executor() const noexcept { return boost::asio::get_associated_executor( d_.handler(), d_->ws.get_executor()); diff --git a/include/boost/beast/websocket/impl/ping.ipp b/include/boost/beast/websocket/impl/ping.ipp index 77d85dde..79003261 100644 --- a/include/boost/beast/websocket/impl/ping.ipp +++ b/include/boost/beast/websocket/impl/ping.ipp @@ -85,9 +85,10 @@ public: } using executor_type = boost::asio::associated_executor_t< - Handler, decltype(d_->ws.get_executor())>; + Handler, decltype(std::declval&>().get_executor())>; - executor_type get_executor() const noexcept + executor_type + get_executor() const noexcept { return boost::asio::get_associated_executor( d_.handler(), d_->ws.get_executor()); diff --git a/include/boost/beast/websocket/impl/read.ipp b/include/boost/beast/websocket/impl/read.ipp index 9cd0a9c9..b61087e6 100644 --- a/include/boost/beast/websocket/impl/read.ipp +++ b/include/boost/beast/websocket/impl/read.ipp @@ -85,9 +85,10 @@ public: } using executor_type = boost::asio::associated_executor_t< - Handler, decltype(ws_.get_executor())>; + Handler, decltype(std::declval&>().get_executor())>; - executor_type get_executor() const noexcept + executor_type + get_executor() const noexcept { return boost::asio::get_associated_executor( h_, ws_.get_executor()); @@ -707,9 +708,10 @@ public: } using executor_type = boost::asio::associated_executor_t< - Handler, decltype(ws_.get_executor())>; + Handler, decltype(std::declval&>().get_executor())>; - executor_type get_executor() const noexcept + executor_type + get_executor() const noexcept { return boost::asio::get_associated_executor( h_, ws_.get_executor()); diff --git a/include/boost/beast/websocket/impl/teardown.ipp b/include/boost/beast/websocket/impl/teardown.ipp index bf7f418e..8f4475f2 100644 --- a/include/boost/beast/websocket/impl/teardown.ipp +++ b/include/boost/beast/websocket/impl/teardown.ipp @@ -60,9 +60,10 @@ public: } using executor_type = boost::asio::associated_executor_t< - Handler, decltype(s_.get_executor())>; + Handler, decltype(std::declval().get_executor())>; - executor_type get_executor() const noexcept + executor_type + get_executor() const noexcept { return boost::asio::get_associated_executor( h_, s_.get_executor()); diff --git a/include/boost/beast/websocket/impl/write.ipp b/include/boost/beast/websocket/impl/write.ipp index 0a29c052..b04f2826 100644 --- a/include/boost/beast/websocket/impl/write.ipp +++ b/include/boost/beast/websocket/impl/write.ipp @@ -81,9 +81,10 @@ public: } using executor_type = boost::asio::associated_executor_t< - Handler, decltype(ws_.get_executor())>; + Handler, decltype(std::declval&>().get_executor())>; - executor_type get_executor() const noexcept + executor_type + get_executor() const noexcept { return boost::asio::get_associated_executor( h_, ws_.get_executor()); diff --git a/include/boost/beast/websocket/stream.hpp b/include/boost/beast/websocket/stream.hpp index 8f75d339..a3ab03ae 100644 --- a/include/boost/beast/websocket/stream.hpp +++ b/include/boost/beast/websocket/stream.hpp @@ -245,6 +245,9 @@ public: using lowest_layer_type = typename get_lowest_layer::type; + /// The type of the executor associated with the object. + using executor_type = typename next_layer_type::executor_type; + /** Destructor Destroys the stream and all associated resources. @@ -293,25 +296,13 @@ public: /** Get the executor associated with the object. - This function may be used to obtain the executor object that the stream - uses to dispatch handlers for asynchronous operations. + This function may be used to obtain the executor object that the + stream uses to dispatch handlers for asynchronous operations. @return A copy of the executor that stream will use to dispatch handlers. - - @note This function participates in overload resolution only if - `NextLayer` has a member function named `get_executor`. */ -#if BOOST_BEAST_DOXYGEN - implementation_defined -#else - template< - class T = next_layer_type, - class = typename std::enable_if< - has_get_executor::value>::type> - auto -#endif - get_executor() noexcept -> - decltype(std::declval().get_executor()) + executor_type + get_executor() noexcept { return stream_.get_executor(); } diff --git a/test/bench/wsload/wsload.cpp b/test/bench/wsload/wsload.cpp index 34c475ba..9cd0a1ec 100644 --- a/test/bench/wsload/wsload.cpp +++ b/test/bench/wsload/wsload.cpp @@ -299,7 +299,7 @@ main(int argc, char** argv) auto const messages= static_cast(std::atoi(argv[4])); auto const workers = static_cast(std::atoi(argv[5])); auto const threads = static_cast(std::atoi(argv[6])); - auto const deflate = static_cast(std::atoi(argv[7])); + auto const deflate = std::atoi(argv[7]) != 0; auto const work = (messages + workers - 1) / workers; test_buffer tb; for(auto i = trials; i != 0; --i)