forked from boostorg/beast
@@ -1,6 +1,7 @@
|
|||||||
Version 201
|
Version 201
|
||||||
|
|
||||||
* Decay bound arguments in handler wrapper parameters
|
* Decay bound arguments in handler wrapper parameters
|
||||||
|
* Add bind_back_handler
|
||||||
|
|
||||||
--------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
@@ -52,11 +52,13 @@ composed operations:
|
|||||||
be the same as those of the original handler.
|
be the same as those of the original handler.
|
||||||
]]
|
]]
|
||||||
[[
|
[[
|
||||||
|
[link beast.ref.boost__beast__bind_back_handler `bind_back_handler`]
|
||||||
[link beast.ref.boost__beast__bind_front_handler `bind_front_handler`]
|
[link beast.ref.boost__beast__bind_front_handler `bind_front_handler`]
|
||||||
][
|
][
|
||||||
This function creates a new handler which, when invoked, calls
|
This function creates a new handler which, when invoked, calls
|
||||||
the original handler with the list of bound arguments, followed
|
the original handler with the list of bound arguments, along with
|
||||||
by the list of invoked arguments. Placeholders are not supported.
|
the list of invoked arguments at either the front or the back of
|
||||||
|
the argument list. Placeholders are not supported.
|
||||||
|
|
||||||
The passed handler and arguments are forwarded into the returned
|
The passed handler and arguments are forwarded into the returned
|
||||||
handler, whose associated allocator and associated executor will
|
handler, whose associated allocator and associated executor will
|
||||||
|
@@ -212,8 +212,9 @@
|
|||||||
<entry valign="top">
|
<entry valign="top">
|
||||||
<bridgehead renderas="sect3">Functions</bridgehead>
|
<bridgehead renderas="sect3">Functions</bridgehead>
|
||||||
<simplelist type="vert" columns="1">
|
<simplelist type="vert" columns="1">
|
||||||
<member><link linkend="beast.ref.boost__beast__bind_handler">bind_handler</link></member>
|
<member><link linkend="beast.ref.boost__beast__bind_back_handler">bind_back_handler</link></member>
|
||||||
<member><link linkend="beast.ref.boost__beast__bind_front_handler">bind_front_handler</link></member>
|
<member><link linkend="beast.ref.boost__beast__bind_front_handler">bind_front_handler</link></member>
|
||||||
|
<member><link linkend="beast.ref.boost__beast__bind_handler">bind_handler</link></member>
|
||||||
<member><link linkend="beast.ref.boost__beast__make_printable">make_printable</link></member>
|
<member><link linkend="beast.ref.boost__beast__make_printable">make_printable</link></member>
|
||||||
<member><link linkend="beast.ref.boost__beast__buffers_cat">buffers_cat</link></member>
|
<member><link linkend="beast.ref.boost__beast__buffers_cat">buffers_cat</link></member>
|
||||||
<member><link linkend="beast.ref.boost__beast__buffers_front">buffers_front</link></member>
|
<member><link linkend="beast.ref.boost__beast__buffers_front">buffers_front</link></member>
|
||||||
|
@@ -131,6 +131,59 @@ bind_front_handler(
|
|||||||
std::forward<Args>(args)...);
|
std::forward<Args>(args)...);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Bind parameters to a completion handler, creating a new 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 forwarded in
|
||||||
|
the parameter list before the bound arguments.
|
||||||
|
|
||||||
|
The passed handler and arguments are forwarded into the returned
|
||||||
|
handler, whose associated allocator and associated executor will
|
||||||
|
will be the same as those of the original handler.
|
||||||
|
|
||||||
|
@par Example
|
||||||
|
|
||||||
|
This function posts the invocation of the specified completion
|
||||||
|
handler with bound arguments:
|
||||||
|
|
||||||
|
@code
|
||||||
|
template <class AsyncReadStream, class ReadHandler>
|
||||||
|
void
|
||||||
|
signal_unreachable (AsyncReadStream& stream, ReadHandler&& handler)
|
||||||
|
{
|
||||||
|
net::post(
|
||||||
|
stream.get_executor(),
|
||||||
|
bind_back_handler (std::forward<ReadHandler> (handler),
|
||||||
|
net::error::network_unreachable, 0));
|
||||||
|
}
|
||||||
|
@endcode
|
||||||
|
|
||||||
|
@param handler The handler to wrap.
|
||||||
|
|
||||||
|
@param args A list of arguments to bind to the handler.
|
||||||
|
The arguments are forwarded into the returned object.
|
||||||
|
*/
|
||||||
|
template<class Handler, class... Args>
|
||||||
|
#if BOOST_BEAST_DOXYGEN
|
||||||
|
__implementation_defined__
|
||||||
|
#else
|
||||||
|
auto
|
||||||
|
#endif
|
||||||
|
bind_back_handler(
|
||||||
|
Handler&& handler,
|
||||||
|
Args&&... args) ->
|
||||||
|
detail::bind_back_wrapper<
|
||||||
|
typename std::decay<Handler>::type,
|
||||||
|
typename std::decay<Args>::type...>
|
||||||
|
{
|
||||||
|
return detail::bind_back_wrapper<
|
||||||
|
typename std::decay<Handler>::type,
|
||||||
|
typename std::decay<Args>::type...>(
|
||||||
|
std::forward<Handler>(handler),
|
||||||
|
std::forward<Args>(args)...);
|
||||||
|
}
|
||||||
|
|
||||||
} // beast
|
} // beast
|
||||||
} // boost
|
} // boost
|
||||||
|
|
||||||
|
@@ -28,6 +28,12 @@ namespace boost {
|
|||||||
namespace beast {
|
namespace beast {
|
||||||
namespace detail {
|
namespace detail {
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// bind_handler
|
||||||
|
//
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
template<class Handler, class... Args>
|
template<class Handler, class... Args>
|
||||||
class bind_wrapper
|
class bind_wrapper
|
||||||
{
|
{
|
||||||
@@ -170,10 +176,10 @@ public:
|
|||||||
template<class Function>
|
template<class Function>
|
||||||
friend
|
friend
|
||||||
void asio_handler_invoke(
|
void asio_handler_invoke(
|
||||||
Function&& f, bind_wrapper* w)
|
Function&& f, bind_wrapper* op)
|
||||||
{
|
{
|
||||||
using net::asio_handler_invoke;
|
using net::asio_handler_invoke;
|
||||||
asio_handler_invoke(f, std::addressof(w->h_));
|
asio_handler_invoke(f, std::addressof(op->h_));
|
||||||
}
|
}
|
||||||
|
|
||||||
friend
|
friend
|
||||||
@@ -184,11 +190,36 @@ public:
|
|||||||
return asio_handler_is_continuation(
|
return asio_handler_is_continuation(
|
||||||
std::addressof(op->h_));
|
std::addressof(op->h_));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
friend
|
||||||
|
void* asio_handler_allocate(
|
||||||
|
std::size_t size, bind_wrapper* op)
|
||||||
|
{
|
||||||
|
using net::asio_handler_allocate;
|
||||||
|
return asio_handler_allocate(
|
||||||
|
size, std::addressof(op->h_));
|
||||||
|
}
|
||||||
|
|
||||||
|
friend
|
||||||
|
void asio_handler_deallocate(
|
||||||
|
void* p, std::size_t size, bind_wrapper* op)
|
||||||
|
{
|
||||||
|
using net::asio_handler_deallocate;
|
||||||
|
asio_handler_deallocate(
|
||||||
|
p, size, std::addressof(op->h_));
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template<class Handler, class... Args>
|
||||||
|
class bind_back_wrapper;
|
||||||
|
|
||||||
template<class Handler, class... Args>
|
template<class Handler, class... Args>
|
||||||
class bind_front_wrapper;
|
class bind_front_wrapper;
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// bind_front
|
||||||
|
//
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
// 0-arg specialization
|
// 0-arg specialization
|
||||||
@@ -233,10 +264,10 @@ public:
|
|||||||
template<class Function>
|
template<class Function>
|
||||||
friend
|
friend
|
||||||
void asio_handler_invoke(
|
void asio_handler_invoke(
|
||||||
Function&& f, bind_front_wrapper* w)
|
Function&& f, bind_front_wrapper* op)
|
||||||
{
|
{
|
||||||
using net::asio_handler_invoke;
|
using net::asio_handler_invoke;
|
||||||
asio_handler_invoke(f, std::addressof(w->h_));
|
asio_handler_invoke(f, std::addressof(op->h_));
|
||||||
}
|
}
|
||||||
|
|
||||||
friend
|
friend
|
||||||
@@ -247,6 +278,24 @@ public:
|
|||||||
return asio_handler_is_continuation(
|
return asio_handler_is_continuation(
|
||||||
std::addressof(op->h_));
|
std::addressof(op->h_));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
friend
|
||||||
|
void* asio_handler_allocate(
|
||||||
|
std::size_t size, bind_front_wrapper* op)
|
||||||
|
{
|
||||||
|
using net::asio_handler_allocate;
|
||||||
|
return asio_handler_allocate(
|
||||||
|
size, std::addressof(op->h_));
|
||||||
|
}
|
||||||
|
|
||||||
|
friend
|
||||||
|
void asio_handler_deallocate(
|
||||||
|
void* p, std::size_t size, bind_front_wrapper* op)
|
||||||
|
{
|
||||||
|
using net::asio_handler_deallocate;
|
||||||
|
asio_handler_deallocate(
|
||||||
|
p, size, std::addressof(op->h_));
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
@@ -299,10 +348,10 @@ public:
|
|||||||
template<class Function>
|
template<class Function>
|
||||||
friend
|
friend
|
||||||
void asio_handler_invoke(
|
void asio_handler_invoke(
|
||||||
Function&& f, bind_front_wrapper* w)
|
Function&& f, bind_front_wrapper* op)
|
||||||
{
|
{
|
||||||
using net::asio_handler_invoke;
|
using net::asio_handler_invoke;
|
||||||
asio_handler_invoke(f, std::addressof(w->h_));
|
asio_handler_invoke(f, std::addressof(op->h_));
|
||||||
}
|
}
|
||||||
|
|
||||||
friend
|
friend
|
||||||
@@ -313,6 +362,24 @@ public:
|
|||||||
return asio_handler_is_continuation(
|
return asio_handler_is_continuation(
|
||||||
std::addressof(op->h_));
|
std::addressof(op->h_));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
friend
|
||||||
|
void* asio_handler_allocate(
|
||||||
|
std::size_t size, bind_front_wrapper* op)
|
||||||
|
{
|
||||||
|
using net::asio_handler_allocate;
|
||||||
|
return asio_handler_allocate(
|
||||||
|
size, std::addressof(op->h_));
|
||||||
|
}
|
||||||
|
|
||||||
|
friend
|
||||||
|
void asio_handler_deallocate(
|
||||||
|
void* p, std::size_t size, bind_front_wrapper* op)
|
||||||
|
{
|
||||||
|
using net::asio_handler_deallocate;
|
||||||
|
asio_handler_deallocate(
|
||||||
|
p, size, std::addressof(op->h_));
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
@@ -370,10 +437,10 @@ public:
|
|||||||
template<class Function>
|
template<class Function>
|
||||||
friend
|
friend
|
||||||
void asio_handler_invoke(
|
void asio_handler_invoke(
|
||||||
Function&& f, bind_front_wrapper* w)
|
Function&& f, bind_front_wrapper* op)
|
||||||
{
|
{
|
||||||
using net::asio_handler_invoke;
|
using net::asio_handler_invoke;
|
||||||
asio_handler_invoke(f, std::addressof(w->h_));
|
asio_handler_invoke(f, std::addressof(op->h_));
|
||||||
}
|
}
|
||||||
|
|
||||||
friend
|
friend
|
||||||
@@ -385,6 +452,23 @@ public:
|
|||||||
std::addressof(op->h_));
|
std::addressof(op->h_));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
friend
|
||||||
|
void* asio_handler_allocate(
|
||||||
|
std::size_t size, bind_front_wrapper* op)
|
||||||
|
{
|
||||||
|
using net::asio_handler_allocate;
|
||||||
|
return asio_handler_allocate(
|
||||||
|
size, std::addressof(op->h_));
|
||||||
|
}
|
||||||
|
|
||||||
|
friend
|
||||||
|
void asio_handler_deallocate(
|
||||||
|
void* p, std::size_t size, bind_front_wrapper* op)
|
||||||
|
{
|
||||||
|
using net::asio_handler_deallocate;
|
||||||
|
asio_handler_deallocate(
|
||||||
|
p, size, std::addressof(op->h_));
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
@@ -462,10 +546,10 @@ public:
|
|||||||
template<class Function>
|
template<class Function>
|
||||||
friend
|
friend
|
||||||
void asio_handler_invoke(
|
void asio_handler_invoke(
|
||||||
Function&& f, bind_front_wrapper* w)
|
Function&& f, bind_front_wrapper* op)
|
||||||
{
|
{
|
||||||
using net::asio_handler_invoke;
|
using net::asio_handler_invoke;
|
||||||
asio_handler_invoke(f, std::addressof(w->h_));
|
asio_handler_invoke(f, std::addressof(op->h_));
|
||||||
}
|
}
|
||||||
|
|
||||||
friend
|
friend
|
||||||
@@ -476,6 +560,24 @@ public:
|
|||||||
return asio_handler_is_continuation(
|
return asio_handler_is_continuation(
|
||||||
std::addressof(op->h_));
|
std::addressof(op->h_));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
friend
|
||||||
|
void* asio_handler_allocate(
|
||||||
|
std::size_t size, bind_front_wrapper* op)
|
||||||
|
{
|
||||||
|
using net::asio_handler_allocate;
|
||||||
|
return asio_handler_allocate(
|
||||||
|
size, std::addressof(op->h_));
|
||||||
|
}
|
||||||
|
|
||||||
|
friend
|
||||||
|
void asio_handler_deallocate(
|
||||||
|
void* p, std::size_t size, bind_front_wrapper* op)
|
||||||
|
{
|
||||||
|
using net::asio_handler_deallocate;
|
||||||
|
asio_handler_deallocate(
|
||||||
|
p, size, std::addressof(op->h_));
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
@@ -528,10 +630,10 @@ public:
|
|||||||
template<class Function>
|
template<class Function>
|
||||||
friend
|
friend
|
||||||
void asio_handler_invoke(
|
void asio_handler_invoke(
|
||||||
Function&& f, bind_front_wrapper* w)
|
Function&& f, bind_front_wrapper* op)
|
||||||
{
|
{
|
||||||
using net::asio_handler_invoke;
|
using net::asio_handler_invoke;
|
||||||
asio_handler_invoke(f, std::addressof(w->h_));
|
asio_handler_invoke(f, std::addressof(op->h_));
|
||||||
}
|
}
|
||||||
|
|
||||||
friend
|
friend
|
||||||
@@ -542,30 +644,475 @@ public:
|
|||||||
return asio_handler_is_continuation(
|
return asio_handler_is_continuation(
|
||||||
std::addressof(op->h_));
|
std::addressof(op->h_));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
friend
|
||||||
|
void* asio_handler_allocate(
|
||||||
|
std::size_t size, bind_front_wrapper* op)
|
||||||
|
{
|
||||||
|
using net::asio_handler_allocate;
|
||||||
|
return asio_handler_allocate(
|
||||||
|
size, std::addressof(op->h_));
|
||||||
|
}
|
||||||
|
|
||||||
|
friend
|
||||||
|
void asio_handler_deallocate(
|
||||||
|
void* p, std::size_t size, bind_front_wrapper* op)
|
||||||
|
{
|
||||||
|
using net::asio_handler_deallocate;
|
||||||
|
asio_handler_deallocate(
|
||||||
|
p, size, std::addressof(op->h_));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// bind_back
|
||||||
|
//
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// 0-arg specialization
|
||||||
|
template<class Handler>
|
||||||
|
class bind_back_wrapper<Handler>
|
||||||
|
{
|
||||||
|
Handler h_;
|
||||||
|
|
||||||
|
template<class T, class Executor>
|
||||||
|
friend struct net::associated_executor;
|
||||||
|
|
||||||
|
public:
|
||||||
|
using result_type = void;
|
||||||
|
|
||||||
|
bind_back_wrapper(bind_back_wrapper&&) = default;
|
||||||
|
bind_back_wrapper(bind_back_wrapper const&) = default;
|
||||||
|
|
||||||
|
template<class Handler_>
|
||||||
|
explicit
|
||||||
|
bind_back_wrapper(Handler_&& handler)
|
||||||
|
: h_(std::forward<Handler_>(handler))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class... Ts>
|
||||||
|
void operator()(Ts&&... ts)
|
||||||
|
{
|
||||||
|
h_(std::forward<Ts>(ts)...);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
|
using allocator_type =
|
||||||
|
net::associated_allocator_t<Handler>;
|
||||||
|
|
||||||
|
allocator_type
|
||||||
|
get_allocator() const noexcept
|
||||||
|
{
|
||||||
|
return net::get_associated_allocator(h_);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class Function>
|
||||||
|
friend
|
||||||
|
void asio_handler_invoke(
|
||||||
|
Function&& f, bind_back_wrapper* op)
|
||||||
|
{
|
||||||
|
using net::asio_handler_invoke;
|
||||||
|
asio_handler_invoke(f, std::addressof(op->h_));
|
||||||
|
}
|
||||||
|
|
||||||
|
friend
|
||||||
|
bool asio_handler_is_continuation(
|
||||||
|
bind_back_wrapper* op)
|
||||||
|
{
|
||||||
|
using net::asio_handler_is_continuation;
|
||||||
|
return asio_handler_is_continuation(
|
||||||
|
std::addressof(op->h_));
|
||||||
|
}
|
||||||
|
|
||||||
|
friend
|
||||||
|
void* asio_handler_allocate(
|
||||||
|
std::size_t size, bind_back_wrapper* op)
|
||||||
|
{
|
||||||
|
using net::asio_handler_allocate;
|
||||||
|
return asio_handler_allocate(
|
||||||
|
size, std::addressof(op->h_));
|
||||||
|
}
|
||||||
|
|
||||||
|
friend
|
||||||
|
void asio_handler_deallocate(
|
||||||
|
void* p, std::size_t size, bind_back_wrapper* op)
|
||||||
|
{
|
||||||
|
using net::asio_handler_deallocate;
|
||||||
|
asio_handler_deallocate(
|
||||||
|
p, size, std::addressof(op->h_));
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
// VFALCO These are only called when using deprecated
|
// 1-arg specialization
|
||||||
// network interfaces in conjunction with extensions,
|
template<class Handler, class Arg>
|
||||||
// and should not be needed. If this creates a problem
|
class bind_back_wrapper<Handler, Arg>
|
||||||
// please contact me.
|
{
|
||||||
|
Handler h_;
|
||||||
|
Arg arg_;
|
||||||
|
|
||||||
template<class Handler, class... Args>
|
template<class T, class Executor>
|
||||||
void* asio_handler_allocate(std::size_t,
|
friend struct net::associated_executor;
|
||||||
bind_wrapper<Handler, Args...>* op) = delete;
|
|
||||||
|
|
||||||
template<class Handler, class... Args>
|
public:
|
||||||
void asio_handler_deallocate(void*, std::size_t,
|
using result_type = void;
|
||||||
bind_wrapper<Handler, Args...>* op) = delete;
|
|
||||||
|
|
||||||
template<class Handler, class... Args>
|
bind_back_wrapper(bind_back_wrapper&&) = default;
|
||||||
void* asio_handler_allocate(std::size_t,
|
bind_back_wrapper(bind_back_wrapper const&) = default;
|
||||||
bind_front_wrapper<Handler, Args...>* op) = delete;
|
|
||||||
|
|
||||||
template<class Handler, class... Args>
|
template<
|
||||||
void asio_handler_deallocate(void*, std::size_t,
|
class Handler_,
|
||||||
bind_front_wrapper<Handler, Args...>* op) = delete;
|
class Arg_>
|
||||||
|
bind_back_wrapper(
|
||||||
|
Handler_&& handler,
|
||||||
|
Arg_&& arg)
|
||||||
|
: h_(std::forward<Handler_>(handler))
|
||||||
|
, arg_(std::forward<Arg_>(arg))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class... Ts>
|
||||||
|
void operator()(Ts&&... ts)
|
||||||
|
{
|
||||||
|
h_( std::forward<Ts>(ts)...,
|
||||||
|
std::move(arg_));
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
|
using allocator_type =
|
||||||
|
net::associated_allocator_t<Handler>;
|
||||||
|
|
||||||
|
allocator_type
|
||||||
|
get_allocator() const noexcept
|
||||||
|
{
|
||||||
|
return net::get_associated_allocator(h_);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class Function>
|
||||||
|
friend
|
||||||
|
void asio_handler_invoke(
|
||||||
|
Function&& f, bind_back_wrapper* op)
|
||||||
|
{
|
||||||
|
using net::asio_handler_invoke;
|
||||||
|
asio_handler_invoke(f, std::addressof(op->h_));
|
||||||
|
}
|
||||||
|
|
||||||
|
friend
|
||||||
|
bool asio_handler_is_continuation(
|
||||||
|
bind_back_wrapper* op)
|
||||||
|
{
|
||||||
|
using net::asio_handler_is_continuation;
|
||||||
|
return asio_handler_is_continuation(
|
||||||
|
std::addressof(op->h_));
|
||||||
|
}
|
||||||
|
|
||||||
|
friend
|
||||||
|
void* asio_handler_allocate(
|
||||||
|
std::size_t size, bind_back_wrapper* op)
|
||||||
|
{
|
||||||
|
using net::asio_handler_allocate;
|
||||||
|
return asio_handler_allocate(
|
||||||
|
size, std::addressof(op->h_));
|
||||||
|
}
|
||||||
|
|
||||||
|
friend
|
||||||
|
void asio_handler_deallocate(
|
||||||
|
void* p, std::size_t size, bind_back_wrapper* op)
|
||||||
|
{
|
||||||
|
using net::asio_handler_deallocate;
|
||||||
|
asio_handler_deallocate(
|
||||||
|
p, size, std::addressof(op->h_));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// 2-arg specialization
|
||||||
|
template<class Handler, class Arg1, class Arg2>
|
||||||
|
class bind_back_wrapper<Handler, Arg1, Arg2>
|
||||||
|
{
|
||||||
|
Handler h_;
|
||||||
|
Arg1 arg1_;
|
||||||
|
Arg2 arg2_;
|
||||||
|
|
||||||
|
template<class T, class Executor>
|
||||||
|
friend struct net::associated_executor;
|
||||||
|
|
||||||
|
public:
|
||||||
|
using result_type = void;
|
||||||
|
|
||||||
|
bind_back_wrapper(bind_back_wrapper&&) = default;
|
||||||
|
bind_back_wrapper(bind_back_wrapper const&) = default;
|
||||||
|
|
||||||
|
template<
|
||||||
|
class Handler_,
|
||||||
|
class Arg1_,
|
||||||
|
class Arg2_>
|
||||||
|
bind_back_wrapper(
|
||||||
|
Handler_&& handler,
|
||||||
|
Arg1_&& arg1,
|
||||||
|
Arg2_&& arg2)
|
||||||
|
: h_(std::forward<Handler_>(handler))
|
||||||
|
, arg1_(std::forward<Arg1_>(arg1))
|
||||||
|
, arg2_(std::forward<Arg2_>(arg2))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class... Ts>
|
||||||
|
void operator()(Ts&&... ts)
|
||||||
|
{
|
||||||
|
h_( std::forward<Ts>(ts)...,
|
||||||
|
std::move(arg1_),
|
||||||
|
std::move(arg2_));
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
|
using allocator_type =
|
||||||
|
net::associated_allocator_t<Handler>;
|
||||||
|
|
||||||
|
allocator_type
|
||||||
|
get_allocator() const noexcept
|
||||||
|
{
|
||||||
|
return net::get_associated_allocator(h_);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class Function>
|
||||||
|
friend
|
||||||
|
void asio_handler_invoke(
|
||||||
|
Function&& f, bind_back_wrapper* op)
|
||||||
|
{
|
||||||
|
using net::asio_handler_invoke;
|
||||||
|
asio_handler_invoke(f, std::addressof(op->h_));
|
||||||
|
}
|
||||||
|
|
||||||
|
friend
|
||||||
|
bool asio_handler_is_continuation(
|
||||||
|
bind_back_wrapper* op)
|
||||||
|
{
|
||||||
|
using net::asio_handler_is_continuation;
|
||||||
|
return asio_handler_is_continuation(
|
||||||
|
std::addressof(op->h_));
|
||||||
|
}
|
||||||
|
|
||||||
|
friend
|
||||||
|
void* asio_handler_allocate(
|
||||||
|
std::size_t size, bind_back_wrapper* op)
|
||||||
|
{
|
||||||
|
using net::asio_handler_allocate;
|
||||||
|
return asio_handler_allocate(
|
||||||
|
size, std::addressof(op->h_));
|
||||||
|
}
|
||||||
|
|
||||||
|
friend
|
||||||
|
void asio_handler_deallocate(
|
||||||
|
void* p, std::size_t size, bind_back_wrapper* op)
|
||||||
|
{
|
||||||
|
using net::asio_handler_deallocate;
|
||||||
|
asio_handler_deallocate(
|
||||||
|
p, size, std::addressof(op->h_));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// 3+ arg specialization
|
||||||
|
template<
|
||||||
|
class Handler,
|
||||||
|
class Arg1, class Arg2, class Arg3,
|
||||||
|
class... Args>
|
||||||
|
class bind_back_wrapper<
|
||||||
|
Handler, Arg1, Arg2, Arg3, Args...>
|
||||||
|
{
|
||||||
|
Handler h_;
|
||||||
|
detail::tuple<
|
||||||
|
Arg1, Arg2, Arg3, Args...> args_;
|
||||||
|
|
||||||
|
template<class T, class Executor>
|
||||||
|
friend struct net::associated_executor;
|
||||||
|
|
||||||
|
template<std::size_t... I, class... Ts>
|
||||||
|
void
|
||||||
|
invoke(
|
||||||
|
mp11::index_sequence<I...>,
|
||||||
|
Ts&&... ts)
|
||||||
|
{
|
||||||
|
h_( std::forward<Ts>(ts)...,
|
||||||
|
detail::get<I>(std::move(args_))...);
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
using result_type = void;
|
||||||
|
|
||||||
|
bind_back_wrapper(bind_back_wrapper&&) = default;
|
||||||
|
bind_back_wrapper(bind_back_wrapper const&) = default;
|
||||||
|
|
||||||
|
template<
|
||||||
|
class Handler_,
|
||||||
|
class Arg1_, class Arg2_, class Arg3_,
|
||||||
|
class... Args_>
|
||||||
|
bind_back_wrapper(
|
||||||
|
Handler_&& handler,
|
||||||
|
Arg1_&& arg1,
|
||||||
|
Arg2_&& arg2,
|
||||||
|
Arg3_&& arg3,
|
||||||
|
Args_&&... args)
|
||||||
|
: h_(std::forward<Handler_>(handler))
|
||||||
|
, args_(
|
||||||
|
std::forward<Arg1_>(arg1),
|
||||||
|
std::forward<Arg2_>(arg2),
|
||||||
|
std::forward<Arg3_>(arg3),
|
||||||
|
std::forward<Args_>(args)...)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class... Ts>
|
||||||
|
void operator()(Ts&&... ts)
|
||||||
|
{
|
||||||
|
invoke(
|
||||||
|
mp11::index_sequence_for<
|
||||||
|
Arg1, Arg2, Arg3, Args...>{},
|
||||||
|
std::forward<Ts>(ts)...);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
|
using allocator_type =
|
||||||
|
net::associated_allocator_t<Handler>;
|
||||||
|
|
||||||
|
allocator_type
|
||||||
|
get_allocator() const noexcept
|
||||||
|
{
|
||||||
|
return net::get_associated_allocator(h_);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class Function>
|
||||||
|
friend
|
||||||
|
void asio_handler_invoke(
|
||||||
|
Function&& f, bind_back_wrapper* op)
|
||||||
|
{
|
||||||
|
using net::asio_handler_invoke;
|
||||||
|
asio_handler_invoke(f, std::addressof(op->h_));
|
||||||
|
}
|
||||||
|
|
||||||
|
friend
|
||||||
|
bool asio_handler_is_continuation(
|
||||||
|
bind_back_wrapper* op)
|
||||||
|
{
|
||||||
|
using net::asio_handler_is_continuation;
|
||||||
|
return asio_handler_is_continuation(
|
||||||
|
std::addressof(op->h_));
|
||||||
|
}
|
||||||
|
|
||||||
|
friend
|
||||||
|
void* asio_handler_allocate(
|
||||||
|
std::size_t size, bind_back_wrapper* op)
|
||||||
|
{
|
||||||
|
using net::asio_handler_allocate;
|
||||||
|
return asio_handler_allocate(
|
||||||
|
size, std::addressof(op->h_));
|
||||||
|
}
|
||||||
|
|
||||||
|
friend
|
||||||
|
void asio_handler_deallocate(
|
||||||
|
void* p, std::size_t size, bind_back_wrapper* op)
|
||||||
|
{
|
||||||
|
using net::asio_handler_deallocate;
|
||||||
|
asio_handler_deallocate(
|
||||||
|
p, size, std::addressof(op->h_));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// specialization for the most common case,
|
||||||
|
// to reduce instantiation time and memory.
|
||||||
|
template<class Handler>
|
||||||
|
class bind_back_wrapper<
|
||||||
|
Handler, error_code, std::size_t>
|
||||||
|
{
|
||||||
|
template<class T, class Executor>
|
||||||
|
friend struct net::associated_executor;
|
||||||
|
|
||||||
|
Handler h_;
|
||||||
|
error_code ec_;
|
||||||
|
std::size_t n_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
using result_type = void;
|
||||||
|
|
||||||
|
bind_back_wrapper(bind_back_wrapper&&) = default;
|
||||||
|
bind_back_wrapper(bind_back_wrapper const&) = default;
|
||||||
|
|
||||||
|
template<class DeducedHandler>
|
||||||
|
bind_back_wrapper(DeducedHandler&& handler,
|
||||||
|
error_code ec, std::size_t n)
|
||||||
|
: h_(std::forward<DeducedHandler>(handler))
|
||||||
|
, ec_(ec)
|
||||||
|
, n_(n)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class... Ts>
|
||||||
|
void operator()(Ts&&... ts)
|
||||||
|
{
|
||||||
|
h_(std::forward<Ts>(ts)..., ec_, n_);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
|
using allocator_type =
|
||||||
|
net::associated_allocator_t<Handler>;
|
||||||
|
|
||||||
|
allocator_type
|
||||||
|
get_allocator() const noexcept
|
||||||
|
{
|
||||||
|
return net::get_associated_allocator(h_);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class Function>
|
||||||
|
friend
|
||||||
|
void asio_handler_invoke(
|
||||||
|
Function&& f, bind_back_wrapper* op)
|
||||||
|
{
|
||||||
|
using net::asio_handler_invoke;
|
||||||
|
asio_handler_invoke(f, std::addressof(op->h_));
|
||||||
|
}
|
||||||
|
|
||||||
|
friend
|
||||||
|
bool asio_handler_is_continuation(
|
||||||
|
bind_back_wrapper* op)
|
||||||
|
{
|
||||||
|
using net::asio_handler_is_continuation;
|
||||||
|
return asio_handler_is_continuation(
|
||||||
|
std::addressof(op->h_));
|
||||||
|
}
|
||||||
|
|
||||||
|
friend
|
||||||
|
void* asio_handler_allocate(
|
||||||
|
std::size_t size, bind_back_wrapper* op)
|
||||||
|
{
|
||||||
|
using net::asio_handler_allocate;
|
||||||
|
return asio_handler_allocate(
|
||||||
|
size, std::addressof(op->h_));
|
||||||
|
}
|
||||||
|
|
||||||
|
friend
|
||||||
|
void asio_handler_deallocate(
|
||||||
|
void* p, std::size_t size, bind_back_wrapper* op)
|
||||||
|
{
|
||||||
|
using net::asio_handler_deallocate;
|
||||||
|
asio_handler_deallocate(
|
||||||
|
p, size, std::addressof(op->h_));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
} // detail
|
} // detail
|
||||||
} // beast
|
} // beast
|
||||||
@@ -585,11 +1132,11 @@ struct associated_executor<
|
|||||||
|
|
||||||
static
|
static
|
||||||
type
|
type
|
||||||
get(beast::detail::bind_wrapper<Handler, Args...> const& w,
|
get(beast::detail::bind_wrapper<Handler, Args...> const& op,
|
||||||
Executor const& ex = Executor()) noexcept
|
Executor const& ex = Executor()) noexcept
|
||||||
{
|
{
|
||||||
return associated_executor<
|
return associated_executor<
|
||||||
Handler, Executor>::get(w.h_, ex);
|
Handler, Executor>::get(op.h_, ex);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -602,11 +1149,28 @@ struct associated_executor<
|
|||||||
|
|
||||||
static
|
static
|
||||||
type
|
type
|
||||||
get(beast::detail::bind_front_wrapper<Handler, Args...> const& w,
|
get(beast::detail::bind_front_wrapper<Handler, Args...> const& op,
|
||||||
Executor const& ex = Executor()) noexcept
|
Executor const& ex = Executor()) noexcept
|
||||||
{
|
{
|
||||||
return associated_executor<
|
return associated_executor<
|
||||||
Handler, Executor>::get(w.h_, ex);
|
Handler, Executor>::get(op.h_, ex);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class Handler, class... Args, class Executor>
|
||||||
|
struct associated_executor<
|
||||||
|
beast::detail::bind_back_wrapper<Handler, Args...>, Executor>
|
||||||
|
{
|
||||||
|
using type = typename
|
||||||
|
associated_executor<Handler, Executor>::type;
|
||||||
|
|
||||||
|
static
|
||||||
|
type
|
||||||
|
get(beast::detail::bind_back_wrapper<Handler, Args...> const& op,
|
||||||
|
Executor const& ex = Executor()) noexcept
|
||||||
|
{
|
||||||
|
return associated_executor<
|
||||||
|
Handler, Executor>::get(op.h_, ex);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -634,6 +1198,11 @@ void
|
|||||||
bind(boost::beast::detail::bind_front_wrapper<
|
bind(boost::beast::detail::bind_front_wrapper<
|
||||||
Handler, Args...>, ...) = delete;
|
Handler, Args...>, ...) = delete;
|
||||||
|
|
||||||
|
template<class Handler, class... Args>
|
||||||
|
void
|
||||||
|
bind(boost::beast::detail::bind_back_wrapper<
|
||||||
|
Handler, Args...>, ...) = delete;
|
||||||
|
|
||||||
} // std
|
} // std
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
@@ -62,6 +62,16 @@ public:
|
|||||||
net::error::eof, 0));
|
net::error::eof, 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <class AsyncReadStream, class ReadHandler>
|
||||||
|
void
|
||||||
|
signal_unreachable (AsyncReadStream& stream, ReadHandler&& handler)
|
||||||
|
{
|
||||||
|
net::post(
|
||||||
|
stream.get_executor(),
|
||||||
|
bind_back_handler (std::forward<ReadHandler> (handler),
|
||||||
|
net::error::network_unreachable, 0));
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
testJavadocs()
|
testJavadocs()
|
||||||
{
|
{
|
||||||
@@ -72,6 +82,10 @@ public:
|
|||||||
BEAST_EXPECT((
|
BEAST_EXPECT((
|
||||||
&bind_handler_test::signal_eof<
|
&bind_handler_test::signal_eof<
|
||||||
test::stream, handler<error_code, std::size_t>>));
|
test::stream, handler<error_code, std::size_t>>));
|
||||||
|
|
||||||
|
BEAST_EXPECT((
|
||||||
|
&bind_handler_test::signal_unreachable<
|
||||||
|
test::stream, handler<error_code, std::size_t>>));
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------------
|
//--------------------------------------------------------------------------
|
||||||
|
Reference in New Issue
Block a user