Restore binder support for 3, 4 and 5 arguments.
This commit is contained in:
parent
096660c474
commit
fddf89126a
@ -223,6 +223,363 @@ inline binder2<typename decay<Handler>::type, Arg1, Arg2> bind_handler(
|
||||
ASIO_MOVE_CAST(Handler)(handler), arg1, arg2);
|
||||
}
|
||||
|
||||
template <typename Handler, typename Arg1, typename Arg2, typename Arg3>
|
||||
class binder3
|
||||
{
|
||||
public:
|
||||
template <typename T>
|
||||
binder3(int, ASIO_MOVE_ARG(T) handler, const Arg1& arg1,
|
||||
const Arg2& arg2, const Arg3& arg3)
|
||||
: handler_(ASIO_MOVE_CAST(T)(handler)),
|
||||
arg1_(arg1),
|
||||
arg2_(arg2),
|
||||
arg3_(arg3)
|
||||
{
|
||||
}
|
||||
|
||||
binder3(Handler& handler, const Arg1& arg1,
|
||||
const Arg2& arg2, const Arg3& arg3)
|
||||
: handler_(ASIO_MOVE_CAST(Handler)(handler)),
|
||||
arg1_(arg1),
|
||||
arg2_(arg2),
|
||||
arg3_(arg3)
|
||||
{
|
||||
}
|
||||
|
||||
#if defined(ASIO_HAS_MOVE)
|
||||
binder3(const binder3& other)
|
||||
: handler_(other.handler_),
|
||||
arg1_(other.arg1_),
|
||||
arg2_(other.arg2_),
|
||||
arg3_(other.arg3_)
|
||||
{
|
||||
}
|
||||
|
||||
binder3(binder3&& other)
|
||||
: handler_(ASIO_MOVE_CAST(Handler)(other.handler_)),
|
||||
arg1_(ASIO_MOVE_CAST(Arg1)(other.arg1_)),
|
||||
arg2_(ASIO_MOVE_CAST(Arg2)(other.arg2_)),
|
||||
arg3_(ASIO_MOVE_CAST(Arg3)(other.arg3_))
|
||||
{
|
||||
}
|
||||
#endif // defined(ASIO_HAS_MOVE)
|
||||
|
||||
void operator()()
|
||||
{
|
||||
handler_(static_cast<const Arg1&>(arg1_),
|
||||
static_cast<const Arg2&>(arg2_), static_cast<const Arg3&>(arg3_));
|
||||
}
|
||||
|
||||
void operator()() const
|
||||
{
|
||||
handler_(arg1_, arg2_, arg3_);
|
||||
}
|
||||
|
||||
//private:
|
||||
Handler handler_;
|
||||
Arg1 arg1_;
|
||||
Arg2 arg2_;
|
||||
Arg3 arg3_;
|
||||
};
|
||||
|
||||
template <typename Handler, typename Arg1, typename Arg2, typename Arg3>
|
||||
inline void* asio_handler_allocate(std::size_t size,
|
||||
binder3<Handler, Arg1, Arg2, Arg3>* this_handler)
|
||||
{
|
||||
return asio_handler_alloc_helpers::allocate(
|
||||
size, this_handler->handler_);
|
||||
}
|
||||
|
||||
template <typename Handler, typename Arg1, typename Arg2, typename Arg3>
|
||||
inline void asio_handler_deallocate(void* pointer, std::size_t size,
|
||||
binder3<Handler, Arg1, Arg2, Arg3>* this_handler)
|
||||
{
|
||||
asio_handler_alloc_helpers::deallocate(
|
||||
pointer, size, this_handler->handler_);
|
||||
}
|
||||
|
||||
template <typename Handler, typename Arg1, typename Arg2, typename Arg3>
|
||||
inline bool asio_handler_is_continuation(
|
||||
binder3<Handler, Arg1, Arg2, Arg3>* this_handler)
|
||||
{
|
||||
return asio_handler_cont_helpers::is_continuation(
|
||||
this_handler->handler_);
|
||||
}
|
||||
|
||||
template <typename Function, typename Handler,
|
||||
typename Arg1, typename Arg2, typename Arg3>
|
||||
inline void asio_handler_invoke(Function& function,
|
||||
binder3<Handler, Arg1, Arg2, Arg3>* this_handler)
|
||||
{
|
||||
asio_handler_invoke_helpers::invoke(
|
||||
function, this_handler->handler_);
|
||||
}
|
||||
|
||||
template <typename Function, typename Handler,
|
||||
typename Arg1, typename Arg2, typename Arg3>
|
||||
inline void asio_handler_invoke(const Function& function,
|
||||
binder3<Handler, Arg1, Arg2, Arg3>* this_handler)
|
||||
{
|
||||
asio_handler_invoke_helpers::invoke(
|
||||
function, this_handler->handler_);
|
||||
}
|
||||
|
||||
template <typename Handler, typename Arg1, typename Arg2, typename Arg3>
|
||||
inline binder3<typename decay<Handler>::type, Arg1, Arg2, Arg3> bind_handler(
|
||||
ASIO_MOVE_ARG(Handler) handler, const Arg1& arg1, const Arg2& arg2,
|
||||
const Arg3& arg3)
|
||||
{
|
||||
return binder3<typename decay<Handler>::type, Arg1, Arg2, Arg3>(0,
|
||||
ASIO_MOVE_CAST(Handler)(handler), arg1, arg2, arg3);
|
||||
}
|
||||
|
||||
template <typename Handler, typename Arg1,
|
||||
typename Arg2, typename Arg3, typename Arg4>
|
||||
class binder4
|
||||
{
|
||||
public:
|
||||
template <typename T>
|
||||
binder4(int, ASIO_MOVE_ARG(T) handler, const Arg1& arg1,
|
||||
const Arg2& arg2, const Arg3& arg3, const Arg4& arg4)
|
||||
: handler_(ASIO_MOVE_CAST(T)(handler)),
|
||||
arg1_(arg1),
|
||||
arg2_(arg2),
|
||||
arg3_(arg3),
|
||||
arg4_(arg4)
|
||||
{
|
||||
}
|
||||
|
||||
binder4(Handler& handler, const Arg1& arg1,
|
||||
const Arg2& arg2, const Arg3& arg3, const Arg4& arg4)
|
||||
: handler_(ASIO_MOVE_CAST(Handler)(handler)),
|
||||
arg1_(arg1),
|
||||
arg2_(arg2),
|
||||
arg3_(arg3),
|
||||
arg4_(arg4)
|
||||
{
|
||||
}
|
||||
|
||||
#if defined(ASIO_HAS_MOVE)
|
||||
binder4(const binder4& other)
|
||||
: handler_(other.handler_),
|
||||
arg1_(other.arg1_),
|
||||
arg2_(other.arg2_),
|
||||
arg3_(other.arg3_),
|
||||
arg4_(other.arg4_)
|
||||
{
|
||||
}
|
||||
|
||||
binder4(binder4&& other)
|
||||
: handler_(ASIO_MOVE_CAST(Handler)(other.handler_)),
|
||||
arg1_(ASIO_MOVE_CAST(Arg1)(other.arg1_)),
|
||||
arg2_(ASIO_MOVE_CAST(Arg2)(other.arg2_)),
|
||||
arg3_(ASIO_MOVE_CAST(Arg3)(other.arg3_)),
|
||||
arg4_(ASIO_MOVE_CAST(Arg4)(other.arg4_))
|
||||
{
|
||||
}
|
||||
#endif // defined(ASIO_HAS_MOVE)
|
||||
|
||||
void operator()()
|
||||
{
|
||||
handler_(static_cast<const Arg1&>(arg1_),
|
||||
static_cast<const Arg2&>(arg2_), static_cast<const Arg3&>(arg3_),
|
||||
static_cast<const Arg4&>(arg4_));
|
||||
}
|
||||
|
||||
void operator()() const
|
||||
{
|
||||
handler_(arg1_, arg2_, arg3_, arg4_);
|
||||
}
|
||||
|
||||
//private:
|
||||
Handler handler_;
|
||||
Arg1 arg1_;
|
||||
Arg2 arg2_;
|
||||
Arg3 arg3_;
|
||||
Arg4 arg4_;
|
||||
};
|
||||
|
||||
template <typename Handler, typename Arg1,
|
||||
typename Arg2, typename Arg3, typename Arg4>
|
||||
inline void* asio_handler_allocate(std::size_t size,
|
||||
binder4<Handler, Arg1, Arg2, Arg3, Arg4>* this_handler)
|
||||
{
|
||||
return asio_handler_alloc_helpers::allocate(
|
||||
size, this_handler->handler_);
|
||||
}
|
||||
|
||||
template <typename Handler, typename Arg1,
|
||||
typename Arg2, typename Arg3, typename Arg4>
|
||||
inline void asio_handler_deallocate(void* pointer, std::size_t size,
|
||||
binder4<Handler, Arg1, Arg2, Arg3, Arg4>* this_handler)
|
||||
{
|
||||
asio_handler_alloc_helpers::deallocate(
|
||||
pointer, size, this_handler->handler_);
|
||||
}
|
||||
|
||||
template <typename Handler, typename Arg1,
|
||||
typename Arg2, typename Arg3, typename Arg4>
|
||||
inline bool asio_handler_is_continuation(
|
||||
binder4<Handler, Arg1, Arg2, Arg3, Arg4>* this_handler)
|
||||
{
|
||||
return asio_handler_cont_helpers::is_continuation(
|
||||
this_handler->handler_);
|
||||
}
|
||||
|
||||
template <typename Function, typename Handler, typename Arg1,
|
||||
typename Arg2, typename Arg3, typename Arg4>
|
||||
inline void asio_handler_invoke(Function& function,
|
||||
binder4<Handler, Arg1, Arg2, Arg3, Arg4>* this_handler)
|
||||
{
|
||||
asio_handler_invoke_helpers::invoke(
|
||||
function, this_handler->handler_);
|
||||
}
|
||||
|
||||
template <typename Function, typename Handler, typename Arg1,
|
||||
typename Arg2, typename Arg3, typename Arg4>
|
||||
inline void asio_handler_invoke(const Function& function,
|
||||
binder4<Handler, Arg1, Arg2, Arg3, Arg4>* this_handler)
|
||||
{
|
||||
asio_handler_invoke_helpers::invoke(
|
||||
function, this_handler->handler_);
|
||||
}
|
||||
|
||||
template <typename Handler, typename Arg1,
|
||||
typename Arg2, typename Arg3, typename Arg4>
|
||||
inline binder4<typename decay<Handler>::type, Arg1, Arg2, Arg3, Arg4>
|
||||
bind_handler(ASIO_MOVE_ARG(Handler) handler, const Arg1& arg1,
|
||||
const Arg2& arg2, const Arg3& arg3, const Arg4& arg4)
|
||||
{
|
||||
return binder4<typename decay<Handler>::type, Arg1, Arg2, Arg3, Arg4>(0,
|
||||
ASIO_MOVE_CAST(Handler)(handler), arg1, arg2, arg3, arg4);
|
||||
}
|
||||
|
||||
template <typename Handler, typename Arg1, typename Arg2,
|
||||
typename Arg3, typename Arg4, typename Arg5>
|
||||
class binder5
|
||||
{
|
||||
public:
|
||||
template <typename T>
|
||||
binder5(int, ASIO_MOVE_ARG(T) handler, const Arg1& arg1,
|
||||
const Arg2& arg2, const Arg3& arg3, const Arg4& arg4, const Arg5& arg5)
|
||||
: handler_(ASIO_MOVE_CAST(T)(handler)),
|
||||
arg1_(arg1),
|
||||
arg2_(arg2),
|
||||
arg3_(arg3),
|
||||
arg4_(arg4),
|
||||
arg5_(arg5)
|
||||
{
|
||||
}
|
||||
|
||||
binder5(Handler& handler, const Arg1& arg1, const Arg2& arg2,
|
||||
const Arg3& arg3, const Arg4& arg4, const Arg5& arg5)
|
||||
: handler_(ASIO_MOVE_CAST(Handler)(handler)),
|
||||
arg1_(arg1),
|
||||
arg2_(arg2),
|
||||
arg3_(arg3),
|
||||
arg4_(arg4),
|
||||
arg5_(arg5)
|
||||
{
|
||||
}
|
||||
|
||||
#if defined(ASIO_HAS_MOVE)
|
||||
binder5(const binder5& other)
|
||||
: handler_(other.handler_),
|
||||
arg1_(other.arg1_),
|
||||
arg2_(other.arg2_),
|
||||
arg3_(other.arg3_),
|
||||
arg4_(other.arg4_),
|
||||
arg5_(other.arg5_)
|
||||
{
|
||||
}
|
||||
|
||||
binder5(binder5&& other)
|
||||
: handler_(ASIO_MOVE_CAST(Handler)(other.handler_)),
|
||||
arg1_(ASIO_MOVE_CAST(Arg1)(other.arg1_)),
|
||||
arg2_(ASIO_MOVE_CAST(Arg2)(other.arg2_)),
|
||||
arg3_(ASIO_MOVE_CAST(Arg3)(other.arg3_)),
|
||||
arg4_(ASIO_MOVE_CAST(Arg4)(other.arg4_)),
|
||||
arg5_(ASIO_MOVE_CAST(Arg5)(other.arg5_))
|
||||
{
|
||||
}
|
||||
#endif // defined(ASIO_HAS_MOVE)
|
||||
|
||||
void operator()()
|
||||
{
|
||||
handler_(static_cast<const Arg1&>(arg1_),
|
||||
static_cast<const Arg2&>(arg2_), static_cast<const Arg3&>(arg3_),
|
||||
static_cast<const Arg4&>(arg4_), static_cast<const Arg5&>(arg5_));
|
||||
}
|
||||
|
||||
void operator()() const
|
||||
{
|
||||
handler_(arg1_, arg2_, arg3_, arg4_, arg5_);
|
||||
}
|
||||
|
||||
//private:
|
||||
Handler handler_;
|
||||
Arg1 arg1_;
|
||||
Arg2 arg2_;
|
||||
Arg3 arg3_;
|
||||
Arg4 arg4_;
|
||||
Arg5 arg5_;
|
||||
};
|
||||
|
||||
template <typename Handler, typename Arg1, typename Arg2,
|
||||
typename Arg3, typename Arg4, typename Arg5>
|
||||
inline void* asio_handler_allocate(std::size_t size,
|
||||
binder5<Handler, Arg1, Arg2, Arg3, Arg4, Arg5>* this_handler)
|
||||
{
|
||||
return asio_handler_alloc_helpers::allocate(
|
||||
size, this_handler->handler_);
|
||||
}
|
||||
|
||||
template <typename Handler, typename Arg1, typename Arg2,
|
||||
typename Arg3, typename Arg4, typename Arg5>
|
||||
inline void asio_handler_deallocate(void* pointer, std::size_t size,
|
||||
binder5<Handler, Arg1, Arg2, Arg3, Arg4, Arg5>* this_handler)
|
||||
{
|
||||
asio_handler_alloc_helpers::deallocate(
|
||||
pointer, size, this_handler->handler_);
|
||||
}
|
||||
|
||||
template <typename Handler, typename Arg1, typename Arg2,
|
||||
typename Arg3, typename Arg4, typename Arg5>
|
||||
inline bool asio_handler_is_continuation(
|
||||
binder5<Handler, Arg1, Arg2, Arg3, Arg4, Arg5>* this_handler)
|
||||
{
|
||||
return asio_handler_cont_helpers::is_continuation(
|
||||
this_handler->handler_);
|
||||
}
|
||||
|
||||
template <typename Function, typename Handler, typename Arg1,
|
||||
typename Arg2, typename Arg3, typename Arg4, typename Arg5>
|
||||
inline void asio_handler_invoke(Function& function,
|
||||
binder5<Handler, Arg1, Arg2, Arg3, Arg4, Arg5>* this_handler)
|
||||
{
|
||||
asio_handler_invoke_helpers::invoke(
|
||||
function, this_handler->handler_);
|
||||
}
|
||||
|
||||
template <typename Function, typename Handler, typename Arg1,
|
||||
typename Arg2, typename Arg3, typename Arg4, typename Arg5>
|
||||
inline void asio_handler_invoke(const Function& function,
|
||||
binder5<Handler, Arg1, Arg2, Arg3, Arg4, Arg5>* this_handler)
|
||||
{
|
||||
asio_handler_invoke_helpers::invoke(
|
||||
function, this_handler->handler_);
|
||||
}
|
||||
|
||||
template <typename Handler, typename Arg1, typename Arg2,
|
||||
typename Arg3, typename Arg4, typename Arg5>
|
||||
inline binder5<typename decay<Handler>::type, Arg1, Arg2, Arg3, Arg4, Arg5>
|
||||
bind_handler(ASIO_MOVE_ARG(Handler) handler, const Arg1& arg1,
|
||||
const Arg2& arg2, const Arg3& arg3, const Arg4& arg4, const Arg5& arg5)
|
||||
{
|
||||
return binder5<typename decay<Handler>::type, Arg1, Arg2, Arg3, Arg4, Arg5>(0,
|
||||
ASIO_MOVE_CAST(Handler)(handler), arg1, arg2, arg3, arg4, arg5);
|
||||
}
|
||||
|
||||
#if defined(ASIO_HAS_MOVE)
|
||||
|
||||
template <typename Handler, typename Arg1>
|
||||
|
@ -508,6 +508,10 @@ struct handler_type_requirements
|
||||
handler_type, handler) \
|
||||
typedef int ASIO_UNUSED_TYPEDEF
|
||||
|
||||
#define ASIO_MOVE_ACCEPT_HANDLER_CHECK( \
|
||||
handler_type, handler, socket_type) \
|
||||
typedef int ASIO_UNUSED_TYPEDEF
|
||||
|
||||
#define ASIO_CONNECT_HANDLER_CHECK( \
|
||||
handler_type, handler) \
|
||||
typedef int ASIO_UNUSED_TYPEDEF
|
||||
|
@ -90,6 +90,26 @@ void sleep_increment(io_context* ioc, int* count)
|
||||
++(*count);
|
||||
}
|
||||
|
||||
void increment_by_a(int* count, int a)
|
||||
{
|
||||
(*count) += a;
|
||||
}
|
||||
|
||||
void increment_by_a_b(int* count, int a, int b)
|
||||
{
|
||||
(*count) += a + b;
|
||||
}
|
||||
|
||||
void increment_by_a_b_c(int* count, int a, int b, int c)
|
||||
{
|
||||
(*count) += a + b + c;
|
||||
}
|
||||
|
||||
void increment_by_a_b_c_d(int* count, int a, int b, int c, int d)
|
||||
{
|
||||
(*count) += a + b + c + d;
|
||||
}
|
||||
|
||||
void start_sleep_increments(io_context* ioc, io_context::strand* s, int* count)
|
||||
{
|
||||
// Give all threads a chance to start.
|
||||
@ -217,8 +237,87 @@ void strand_test()
|
||||
ASIO_CHECK(count == 0);
|
||||
}
|
||||
|
||||
void strand_wrap_test()
|
||||
{
|
||||
io_context ioc;
|
||||
io_context::strand s(ioc);
|
||||
int count = 0;
|
||||
|
||||
s.wrap(bindns::bind(increment, &count))();
|
||||
|
||||
// No handlers can be called until run() is called.
|
||||
ASIO_CHECK(count == 0);
|
||||
|
||||
ioc.restart();
|
||||
ioc.run();
|
||||
|
||||
// The run() calls will not return until all work has finished.
|
||||
ASIO_CHECK(count == 1);
|
||||
|
||||
count = 0;
|
||||
s.wrap(increment)(&count);
|
||||
|
||||
// No handlers can be called until run() is called.
|
||||
ASIO_CHECK(count == 0);
|
||||
|
||||
ioc.restart();
|
||||
ioc.run();
|
||||
|
||||
// The run() calls will not return until all work has finished.
|
||||
ASIO_CHECK(count == 1);
|
||||
|
||||
count = 0;
|
||||
s.wrap(increment_by_a)(&count, 1);
|
||||
|
||||
// No handlers can be called until run() is called.
|
||||
ASIO_CHECK(count == 0);
|
||||
|
||||
ioc.restart();
|
||||
ioc.run();
|
||||
|
||||
// The run() calls will not return until all work has finished.
|
||||
ASIO_CHECK(count == 1);
|
||||
|
||||
count = 0;
|
||||
s.wrap(increment_by_a_b)(&count, 1, 2);
|
||||
|
||||
// No handlers can be called until run() is called.
|
||||
ASIO_CHECK(count == 0);
|
||||
|
||||
ioc.restart();
|
||||
ioc.run();
|
||||
|
||||
// The run() calls will not return until all work has finished.
|
||||
ASIO_CHECK(count == 3);
|
||||
|
||||
count = 0;
|
||||
s.wrap(increment_by_a_b_c)(&count, 1, 2, 3);
|
||||
|
||||
// No handlers can be called until run() is called.
|
||||
ASIO_CHECK(count == 0);
|
||||
|
||||
ioc.restart();
|
||||
ioc.run();
|
||||
|
||||
// The run() calls will not return until all work has finished.
|
||||
ASIO_CHECK(count == 6);
|
||||
|
||||
count = 0;
|
||||
s.wrap(increment_by_a_b_c_d)(&count, 1, 2, 3, 4);
|
||||
|
||||
// No handlers can be called until run() is called.
|
||||
ASIO_CHECK(count == 0);
|
||||
|
||||
ioc.restart();
|
||||
ioc.run();
|
||||
|
||||
// The run() calls will not return until all work has finished.
|
||||
ASIO_CHECK(count == 10);
|
||||
}
|
||||
|
||||
ASIO_TEST_SUITE
|
||||
(
|
||||
"strand",
|
||||
ASIO_TEST_CASE(strand_test)
|
||||
ASIO_TEST_CASE(strand_wrap_test)
|
||||
)
|
||||
|
Loading…
Reference in New Issue
Block a user