Fix executor type compilation

This commit is contained in:
Vinnie Falco
2017-10-24 06:40:22 -07:00
parent e94dcae10c
commit 41e61a7458
18 changed files with 134 additions and 110 deletions

View File

@@ -7,6 +7,7 @@ Version 126:
* Don't return end_of_stream on win32 file body writes * Don't return end_of_stream on win32 file body writes
* Fix doc typo * Fix doc typo
* Fix shadowing in session_alloc * Fix shadowing in session_alloc
* Fix executor type compilation
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------

View File

@@ -363,7 +363,7 @@ public:
// final handler. // final handler.
using executor_type = boost::asio::associated_executor_t< using executor_type = boost::asio::associated_executor_t<
Handler, decltype(stream_.get_executor())>; Handler, decltype(std::declval<AsyncReadStream&>().get_executor())>;
executor_type get_executor() const noexcept executor_type get_executor() const noexcept
{ {

View File

@@ -222,6 +222,11 @@ dealloc(void* pv, std::size_t n)
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
namespace detail {
template<class Handler>
class session_alloc_wrapper;
} // detail
template<class T> template<class T>
class session_alloc class session_alloc
: private detail::session_alloc_base<void> : private detail::session_alloc_base<void>
@@ -229,51 +234,6 @@ class session_alloc
template<class U> template<class U>
friend class session_alloc; friend class session_alloc;
template<class Handler>
class wrapped_handler
{
// Can't friend partial specializations,
// so we just friend the whole thing.
template<class U, class Executor>
friend struct boost::asio::associated_executor;
Handler h_;
session_alloc<char> alloc_;
public:
wrapped_handler(wrapped_handler&&) = default;
wrapped_handler(wrapped_handler const&) = default;
template<class DeducedHandler>
wrapped_handler(
DeducedHandler&& h,
session_alloc const& alloc)
: h_(std::forward<DeducedHandler>(h))
, alloc_(alloc)
{
}
using allocator_type = session_alloc<char>;
allocator_type
get_allocator() const noexcept;
template<class... Args>
void
operator()(Args&&... args) const
{
h_(std::forward<Args>(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 using pool_t = typename
detail::session_alloc_base<void>::pool_t; detail::session_alloc_base<void>::pool_t;
@@ -319,7 +279,7 @@ public:
} }
template<class Handler> template<class Handler>
wrapped_handler<typename std::decay<Handler>::type> detail::session_alloc_wrapper<typename std::decay<Handler>::type>
wrap(Handler&& handler); wrap(Handler&& handler);
value_type* value_type*
@@ -387,17 +347,64 @@ protected:
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
template<class T> namespace detail {
template<class Handler>
class session_alloc_wrapper
{
// Can't friend partial specializations,
// so we just friend the whole thing.
template<class U, class Executor>
friend struct boost::asio::associated_executor;
Handler h_;
session_alloc<char> alloc_;
public:
session_alloc_wrapper(session_alloc_wrapper&&) = default;
session_alloc_wrapper(session_alloc_wrapper const&) = default;
template<class DeducedHandler>
session_alloc_wrapper(
DeducedHandler&& h,
session_alloc<char> const& alloc)
: h_(std::forward<DeducedHandler>(h))
, alloc_(alloc)
{
}
using allocator_type = session_alloc<char>;
allocator_type
get_allocator() const noexcept;
template<class... Args>
void
operator()(Args&&... args) const
{
h_(std::forward<Args>(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<class Handler> template<class Handler>
auto auto
session_alloc<T>:: session_alloc_wrapper<Handler>::
wrapped_handler<Handler>::
get_allocator() const noexcept -> get_allocator() const noexcept ->
allocator_type allocator_type
{ {
return alloc_; return alloc_;
} }
} // detail
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
template<class T> template<class T>
@@ -405,31 +412,34 @@ template<class Handler>
auto auto
session_alloc<T>:: session_alloc<T>::
wrap(Handler&& handler) -> wrap(Handler&& handler) ->
wrapped_handler<typename std::decay<Handler>::type> detail::session_alloc_wrapper<typename std::decay<Handler>::type>
{ {
return wrapped_handler< return detail::session_alloc_wrapper<
typename std::decay<Handler>::type>( typename std::decay<Handler>::type>(
std::forward<Handler>(handler), *this); std::forward<Handler>(handler), *this);
} }
//------------------------------------------------------------------------------
namespace boost { namespace boost {
namespace asio { namespace asio {
template<class T, class Handler, class Executor> template<class Handler, class Executor>
struct associated_executor< struct associated_executor<
session_alloc<T>::wrapped_handler<Handler>, Executor> ::detail::session_alloc_wrapper<Handler>, Executor>
{ {
using type = typename using type = typename
associated_executor<Handler, Executor>::type; associated_executor<Handler, Executor>::type;
static static
type type
get(session_alloc<T>::wrapped_handler<Handler> const& h, get(::detail::session_alloc_wrapper<Handler> const& h,
Executor const& ex = Executor()) noexcept Executor const& ex = Executor()) noexcept
{ {
return associated_executor< return associated_executor<
Handler, Executor>::get(h.h_, ex); Handler, Executor>::get(h.h_, ex);
} }
}; };
} // asio } // asio
} // boost } // boost

View File

@@ -58,6 +58,9 @@ public:
/// The type of the lowest layer. /// The type of the lowest layer.
using lowest_layer_type = typename stream_type::lowest_layer_type; 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( ssl_stream(
boost::asio::ip::tcp::socket socket, boost::asio::ip::tcp::socket socket,
boost::asio::ssl::context& ctx) boost::asio::ssl::context& ctx)
@@ -88,7 +91,7 @@ public:
return *this; return *this;
} }
decltype(p_->get_executor()) executor_type
get_executor() noexcept get_executor() noexcept
{ {
return p_->get_executor(); return p_->get_executor();

View File

@@ -164,7 +164,7 @@ public:
// final handler. // final handler.
using executor_type = boost::asio::associated_executor_t< using executor_type = boost::asio::associated_executor_t<
Handler, decltype(p_->stream.get_executor())>; Handler, decltype(std::declval<AsyncStream&>().get_executor())>;
executor_type get_executor() const noexcept executor_type get_executor() const noexcept
{ {

View File

@@ -58,10 +58,12 @@ public:
return boost::asio::get_associated_allocator(h_); return boost::asio::get_associated_allocator(h_);
} }
using executor_type = boost::asio::associated_executor_t< using executor_type =
Handler, decltype(s_.get_executor())>; boost::asio::associated_executor_t<Handler, decltype(
std::declval<buffered_read_stream&>().get_executor())>;
executor_type get_executor() const noexcept executor_type
get_executor() const noexcept
{ {
return boost::asio::get_associated_executor( return boost::asio::get_associated_executor(
h_, s_.get_executor()); h_, s_.get_executor());

View File

@@ -367,10 +367,12 @@ public:
return boost::asio::get_associated_allocator(h_); return boost::asio::get_associated_allocator(h_);
} }
using executor_type = boost::asio::associated_executor_t< using executor_type =
Handler, decltype(sock_.get_executor())>; boost::asio::associated_executor_t<Handler, decltype(std::declval<
boost::asio::basic_stream_socket<Protocol>&>().get_executor())>;
executor_type get_executor() const noexcept executor_type
get_executor() const noexcept
{ {
return boost::asio::get_associated_executor( return boost::asio::get_associated_executor(
h_, sock_.get_executor()); h_, sock_.get_executor());

View File

@@ -72,9 +72,10 @@ public:
} }
using executor_type = boost::asio::associated_executor_t< using executor_type = boost::asio::associated_executor_t<
Handler, decltype(s_.get_executor())>; Handler, decltype(std::declval<Stream&>().get_executor())>;
executor_type get_executor() const noexcept executor_type
get_executor() const noexcept
{ {
return boost::asio::get_associated_executor( return boost::asio::get_associated_executor(
h_, s_.get_executor()); h_, s_.get_executor());
@@ -234,9 +235,10 @@ public:
} }
using executor_type = boost::asio::associated_executor_t< using executor_type = boost::asio::associated_executor_t<
Handler, decltype(s_.get_executor())>; Handler, decltype(std::declval<Stream&>().get_executor())>;
executor_type get_executor() const noexcept executor_type
get_executor() const noexcept
{ {
return boost::asio::get_associated_executor( return boost::asio::get_associated_executor(
h_, s_.get_executor()); h_, s_.get_executor());
@@ -356,9 +358,10 @@ public:
} }
using executor_type = boost::asio::associated_executor_t< using executor_type = boost::asio::associated_executor_t<
Handler, decltype(d_->s.get_executor())>; Handler, decltype(std::declval<Stream&>().get_executor())>;
executor_type get_executor() const noexcept executor_type
get_executor() const noexcept
{ {
return boost::asio::get_associated_executor( return boost::asio::get_associated_executor(
d_.handler(), d_->s.get_executor()); d_.handler(), d_->s.get_executor());

View File

@@ -88,9 +88,10 @@ public:
} }
using executor_type = boost::asio::associated_executor_t< using executor_type = boost::asio::associated_executor_t<
Handler, decltype(s_.get_executor())>; Handler, decltype(std::declval<Stream&>().get_executor())>;
executor_type get_executor() const noexcept executor_type
get_executor() const noexcept
{ {
return boost::asio::get_associated_executor( return boost::asio::get_associated_executor(
h_, s_.get_executor()); h_, s_.get_executor());
@@ -223,9 +224,10 @@ public:
} }
using executor_type = boost::asio::associated_executor_t< using executor_type = boost::asio::associated_executor_t<
Handler, decltype(s_.get_executor())>; Handler, decltype(std::declval<Stream&>().get_executor())>;
executor_type get_executor() const noexcept executor_type
get_executor() const noexcept
{ {
return boost::asio::get_associated_executor( return boost::asio::get_associated_executor(
h_, s_.get_executor()); h_, s_.get_executor());
@@ -335,9 +337,10 @@ public:
} }
using executor_type = boost::asio::associated_executor_t< using executor_type = boost::asio::associated_executor_t<
Handler, decltype(d_->s.get_executor())>; Handler, decltype(std::declval<Stream&>().get_executor())>;
executor_type get_executor() const noexcept executor_type
get_executor() const noexcept
{ {
return boost::asio::get_associated_executor( return boost::asio::get_associated_executor(
d_.handler(), d_->s.get_executor()); d_.handler(), d_->s.get_executor());

View File

@@ -78,9 +78,10 @@ public:
} }
using executor_type = boost::asio::associated_executor_t< using executor_type = boost::asio::associated_executor_t<
Handler, decltype(d_->ws.get_executor())>; Handler, decltype(std::declval<stream<NextLayer>&>().get_executor())>;
executor_type get_executor() const noexcept executor_type
get_executor() const noexcept
{ {
return boost::asio::get_associated_executor( return boost::asio::get_associated_executor(
d_.handler(), d_->ws.get_executor()); d_.handler(), d_->ws.get_executor());
@@ -173,9 +174,10 @@ public:
} }
using executor_type = boost::asio::associated_executor_t< using executor_type = boost::asio::associated_executor_t<
Handler, decltype(d_->ws.get_executor())>; Handler, decltype(std::declval<stream<NextLayer>&>().get_executor())>;
executor_type get_executor() const noexcept executor_type
get_executor() const noexcept
{ {
return boost::asio::get_associated_executor( return boost::asio::get_associated_executor(
d_.handler(), d_->ws.get_executor()); d_.handler(), d_->ws.get_executor());

View File

@@ -85,9 +85,10 @@ public:
} }
using executor_type = boost::asio::associated_executor_t< using executor_type = boost::asio::associated_executor_t<
Handler, decltype(d_->ws.get_executor())>; Handler, decltype(std::declval<stream<NextLayer>&>().get_executor())>;
executor_type get_executor() const noexcept executor_type
get_executor() const noexcept
{ {
return boost::asio::get_associated_executor( return boost::asio::get_associated_executor(
d_.handler(), d_->ws.get_executor()); d_.handler(), d_->ws.get_executor());

View File

@@ -85,9 +85,10 @@ public:
} }
using executor_type = boost::asio::associated_executor_t< using executor_type = boost::asio::associated_executor_t<
Handler, decltype(d_->ws.get_executor())>; Handler, decltype(std::declval<stream<NextLayer>&>().get_executor())>;
executor_type get_executor() const noexcept executor_type
get_executor() const noexcept
{ {
return boost::asio::get_associated_executor( return boost::asio::get_associated_executor(
d_.handler(), d_->ws.get_executor()); d_.handler(), d_->ws.get_executor());

View File

@@ -85,9 +85,10 @@ public:
} }
using executor_type = boost::asio::associated_executor_t< using executor_type = boost::asio::associated_executor_t<
Handler, decltype(d_->ws.get_executor())>; Handler, decltype(std::declval<stream<NextLayer>&>().get_executor())>;
executor_type get_executor() const noexcept executor_type
get_executor() const noexcept
{ {
return boost::asio::get_associated_executor( return boost::asio::get_associated_executor(
d_.handler(), d_->ws.get_executor()); d_.handler(), d_->ws.get_executor());

View File

@@ -85,9 +85,10 @@ public:
} }
using executor_type = boost::asio::associated_executor_t< using executor_type = boost::asio::associated_executor_t<
Handler, decltype(ws_.get_executor())>; Handler, decltype(std::declval<stream<NextLayer>&>().get_executor())>;
executor_type get_executor() const noexcept executor_type
get_executor() const noexcept
{ {
return boost::asio::get_associated_executor( return boost::asio::get_associated_executor(
h_, ws_.get_executor()); h_, ws_.get_executor());
@@ -707,9 +708,10 @@ public:
} }
using executor_type = boost::asio::associated_executor_t< using executor_type = boost::asio::associated_executor_t<
Handler, decltype(ws_.get_executor())>; Handler, decltype(std::declval<stream<NextLayer>&>().get_executor())>;
executor_type get_executor() const noexcept executor_type
get_executor() const noexcept
{ {
return boost::asio::get_associated_executor( return boost::asio::get_associated_executor(
h_, ws_.get_executor()); h_, ws_.get_executor());

View File

@@ -60,9 +60,10 @@ public:
} }
using executor_type = boost::asio::associated_executor_t< using executor_type = boost::asio::associated_executor_t<
Handler, decltype(s_.get_executor())>; Handler, decltype(std::declval<socket_type&>().get_executor())>;
executor_type get_executor() const noexcept executor_type
get_executor() const noexcept
{ {
return boost::asio::get_associated_executor( return boost::asio::get_associated_executor(
h_, s_.get_executor()); h_, s_.get_executor());

View File

@@ -81,9 +81,10 @@ public:
} }
using executor_type = boost::asio::associated_executor_t< using executor_type = boost::asio::associated_executor_t<
Handler, decltype(ws_.get_executor())>; Handler, decltype(std::declval<stream<NextLayer>&>().get_executor())>;
executor_type get_executor() const noexcept executor_type
get_executor() const noexcept
{ {
return boost::asio::get_associated_executor( return boost::asio::get_associated_executor(
h_, ws_.get_executor()); h_, ws_.get_executor());

View File

@@ -245,6 +245,9 @@ public:
using lowest_layer_type = using lowest_layer_type =
typename get_lowest_layer<next_layer_type>::type; typename get_lowest_layer<next_layer_type>::type;
/// The type of the executor associated with the object.
using executor_type = typename next_layer_type::executor_type;
/** Destructor /** Destructor
Destroys the stream and all associated resources. Destroys the stream and all associated resources.
@@ -293,25 +296,13 @@ public:
/** Get the executor associated with the object. /** Get the executor associated with the object.
This function may be used to obtain the executor object that the stream This function may be used to obtain the executor object that the
uses to dispatch handlers for asynchronous operations. stream uses to dispatch handlers for asynchronous operations.
@return A copy of the executor that stream will use to dispatch handlers. @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 executor_type
implementation_defined get_executor() noexcept
#else
template<
class T = next_layer_type,
class = typename std::enable_if<
has_get_executor<next_layer_type>::value>::type>
auto
#endif
get_executor() noexcept ->
decltype(std::declval<T&>().get_executor())
{ {
return stream_.get_executor(); return stream_.get_executor();
} }

View File

@@ -299,7 +299,7 @@ main(int argc, char** argv)
auto const messages= static_cast<std::size_t>(std::atoi(argv[4])); auto const messages= static_cast<std::size_t>(std::atoi(argv[4]));
auto const workers = static_cast<std::size_t>(std::atoi(argv[5])); auto const workers = static_cast<std::size_t>(std::atoi(argv[5]));
auto const threads = static_cast<std::size_t>(std::atoi(argv[6])); auto const threads = static_cast<std::size_t>(std::atoi(argv[6]));
auto const deflate = static_cast<bool>(std::atoi(argv[7])); auto const deflate = std::atoi(argv[7]) != 0;
auto const work = (messages + workers - 1) / workers; auto const work = (messages + workers - 1) / workers;
test_buffer tb; test_buffer tb;
for(auto i = trials; i != 0; --i) for(auto i = trials; i != 0; --i)