forked from boostorg/beast
bind_handler allows placeholders
This commit is contained in:
@@ -18,11 +18,14 @@ namespace beast {
|
||||
|
||||
/** Bind parameters to a completion handler, creating a new handler.
|
||||
|
||||
This function creates a new handler which, when invoked with no
|
||||
parameters, calls the original handler with the list of bound
|
||||
arguments. The passed handler and arguments are forwarded into
|
||||
the returned handler, which provides the same `io_service`
|
||||
execution guarantees as the original handler.
|
||||
This function creates a new handler which, when invoked, calls
|
||||
the original handler with the list of bound arguments. Any
|
||||
parameters passed in the invocation will be subtituted for
|
||||
placeholders present in the list of bound arguments. Parameters
|
||||
which are not matched to placeholders are silently discarded.
|
||||
The passed handler and arguments are forwarded into the returned
|
||||
handler, which provides the same `io_service` execution guarantees
|
||||
as the original handler.
|
||||
|
||||
Unlike `boost::asio::io_service::wrap`, the returned handler can
|
||||
be used in a subsequent call to `boost::asio::io_service::post`
|
||||
@@ -57,9 +60,11 @@ detail::bound_handler<
|
||||
#endif
|
||||
bind_handler(Handler&& handler, Args&&... args)
|
||||
{
|
||||
#if 0
|
||||
static_assert(is_completion_handler<
|
||||
Handler, void(Args...)>::value,
|
||||
"Handler requirements not met");
|
||||
#endif
|
||||
return detail::bound_handler<typename std::decay<
|
||||
Handler>::type, Args...>(std::forward<
|
||||
Handler>(handler), std::forward<Args>(args)...);
|
||||
|
||||
@@ -12,6 +12,8 @@
|
||||
#include <boost/asio/handler_alloc_hook.hpp>
|
||||
#include <boost/asio/handler_continuation_hook.hpp>
|
||||
#include <boost/asio/handler_invoke_hook.hpp>
|
||||
#include <boost/core/ignore_unused.hpp>
|
||||
#include <functional>
|
||||
#include <utility>
|
||||
|
||||
namespace beast {
|
||||
@@ -32,16 +34,72 @@ private:
|
||||
Handler h_;
|
||||
args_type args_;
|
||||
|
||||
template<class Tuple, std::size_t... S>
|
||||
static void invoke(Handler& h, Tuple& args,
|
||||
template<class Arg, class Vals>
|
||||
static
|
||||
typename std::enable_if<
|
||||
std::is_placeholder<typename
|
||||
std::decay<Arg>::type>::value == 0,
|
||||
Arg&&>::type
|
||||
extract(Arg&& arg, Vals& vals)
|
||||
{
|
||||
return arg;
|
||||
}
|
||||
|
||||
template<class Arg, class Vals>
|
||||
static
|
||||
typename std::enable_if<
|
||||
std::is_placeholder<typename
|
||||
std::decay<Arg>::type>::value != 0,
|
||||
typename std::tuple_element<
|
||||
std::is_placeholder<
|
||||
typename std::decay<Arg>::type>::value - 1,
|
||||
Vals>::type&&>::type
|
||||
extract(Arg&&, Vals&& vals)
|
||||
{
|
||||
return std::get<std::is_placeholder<
|
||||
typename std::decay<Arg>::type>::value - 1>(
|
||||
std::forward<Vals>(vals));
|
||||
}
|
||||
|
||||
template<
|
||||
class ArgsTuple,
|
||||
std::size_t... S>
|
||||
static
|
||||
void
|
||||
invoke(
|
||||
Handler& h,
|
||||
ArgsTuple& args,
|
||||
std::tuple<>&&,
|
||||
index_sequence<S...>)
|
||||
{
|
||||
boost::ignore_unused(args);
|
||||
h(std::get<S>(args)...);
|
||||
}
|
||||
|
||||
template<
|
||||
class ArgsTuple,
|
||||
class ValsTuple,
|
||||
std::size_t... S>
|
||||
static
|
||||
void
|
||||
invoke(
|
||||
Handler& h,
|
||||
ArgsTuple& args,
|
||||
ValsTuple&& vals,
|
||||
index_sequence<S...>)
|
||||
{
|
||||
boost::ignore_unused(args);
|
||||
boost::ignore_unused(vals);
|
||||
h(extract(std::get<S>(args),
|
||||
std::forward<ValsTuple>(vals))...);
|
||||
}
|
||||
|
||||
public:
|
||||
using result_type = void;
|
||||
|
||||
bound_handler(bound_handler&&) = default;
|
||||
bound_handler(bound_handler const&) = default;
|
||||
|
||||
template<class DeducedHandler>
|
||||
explicit
|
||||
bound_handler(
|
||||
@@ -51,17 +109,23 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
template<class... Values>
|
||||
void
|
||||
operator()()
|
||||
operator()(Values&&... values)
|
||||
{
|
||||
invoke(h_, args_,
|
||||
std::forward_as_tuple(
|
||||
std::forward<Values>(values)...),
|
||||
index_sequence_for<Args...>());
|
||||
}
|
||||
|
||||
template<class... Values>
|
||||
void
|
||||
operator()() const
|
||||
operator()(Values&&... values) const
|
||||
{
|
||||
invoke(h_, args_,
|
||||
std::forward_as_tuple(
|
||||
std::forward<Values>(values)...),
|
||||
index_sequence_for<Args...>());
|
||||
}
|
||||
|
||||
@@ -107,8 +171,6 @@ public:
|
||||
} // detail
|
||||
} // beast
|
||||
|
||||
#include <functional>
|
||||
|
||||
namespace std {
|
||||
template<class Handler, class... Args>
|
||||
void
|
||||
|
||||
Reference in New Issue
Block a user