Vinnie Falco
2016-03-24 21:05:01 UTC
My websocket stream wrapper interface tries to resemble asio's socket
interfaces as much as possible. I'm adapting my asynchronous initiation
functions to also work with futures by respecting the customization points,
leading to this implementation:
template<class... Args>
using handler_type =
typename boost::asio::handler_type<Args...>::type;
template<class Stream>
template<class Buffers, class Handler>
BOOST_ASIO_INITFN_RESULT_TYPE(Handler,
void(boost::system::error_code))
socket<Stream>::async_write(opcode::value op, bool fin,
Buffers&& bs, Handler&& h)
{
static_assert(beast::is_call_possible<Handler,
void(error_code)>::value,
"Type does not meet the handler requirements");
assert((! wr_cont_ && op != opcode::cont) ||
(wr_cont_ && op == opcode::cont));
wr_cont_ = ! fin;
boost::asio::detail::async_result_init<Handler,
void(boost::system::error_code)> init(
std::forward<Handler>(h));
write_op<std::decay_t<Buffers>, handler_type<Handler,
void(boost::system::error_code)>>{
std::forward<Handler>(init.handler), *this,
op, fin, std::forward<Buffers>(bs)};
return init.result.get();
}
I'm wondering about the call to construct write_op, is it okay to std::move
the init.handler out? Or could a possible implementation of
async_result_init::get need it?
Also, I'm concerned that I have to use detail classes from asio in order to
make user-defined asynchronous initiation functions "first class" (that is,
support the same set of features supported by the initiation functions in
the asio library itself). Is this a legitimate concern and is there a plan
going forward?
Thanks
interfaces as much as possible. I'm adapting my asynchronous initiation
functions to also work with futures by respecting the customization points,
leading to this implementation:
template<class... Args>
using handler_type =
typename boost::asio::handler_type<Args...>::type;
template<class Stream>
template<class Buffers, class Handler>
BOOST_ASIO_INITFN_RESULT_TYPE(Handler,
void(boost::system::error_code))
socket<Stream>::async_write(opcode::value op, bool fin,
Buffers&& bs, Handler&& h)
{
static_assert(beast::is_call_possible<Handler,
void(error_code)>::value,
"Type does not meet the handler requirements");
assert((! wr_cont_ && op != opcode::cont) ||
(wr_cont_ && op == opcode::cont));
wr_cont_ = ! fin;
boost::asio::detail::async_result_init<Handler,
void(boost::system::error_code)> init(
std::forward<Handler>(h));
write_op<std::decay_t<Buffers>, handler_type<Handler,
void(boost::system::error_code)>>{
std::forward<Handler>(init.handler), *this,
op, fin, std::forward<Buffers>(bs)};
return init.result.get();
}
I'm wondering about the call to construct write_op, is it okay to std::move
the init.handler out? Or could a possible implementation of
async_result_init::get need it?
Also, I'm concerned that I have to use detail classes from asio in order to
make user-defined asynchronous initiation functions "first class" (that is,
support the same set of features supported by the initiation functions in
the asio library itself). Is this a legitimate concern and is there a plan
going forward?
Thanks
--
Follow me on Github: https://github.com/vinniefalco
Follow me on Github: https://github.com/vinniefalco