Provide friendlier compiler errors when the wrong handler signature is used.

This commit is contained in:
Christopher Kohlhoff 2011-02-08 18:49:49 +11:00
parent 066e739628
commit b3206af5f2
21 changed files with 569 additions and 1 deletions

View File

@ -53,6 +53,7 @@ nobase_include_HEADERS = \
asio/detail/gcc_x86_fenced_block.hpp \
asio/detail/handler_alloc_helpers.hpp \
asio/detail/handler_invoke_helpers.hpp \
asio/detail/handler_type_requirements.hpp \
asio/detail/hash_map.hpp \
asio/detail/impl/descriptor_ops.ipp \
asio/detail/impl/dev_poll_reactor.hpp \

View File

@ -19,6 +19,7 @@
#include <cstddef>
#include "asio/basic_socket.hpp"
#include "asio/datagram_socket_service.hpp"
#include "asio/detail/handler_type_requirements.hpp"
#include "asio/detail/throw_error.hpp"
#include "asio/error.hpp"
@ -248,6 +249,10 @@ public:
template <typename ConstBufferSequence, typename WriteHandler>
void async_send(const ConstBufferSequence& buffers, WriteHandler handler)
{
// If you get an error on the following line it means that your handler does
// not meet the documented type requirements for a WriteHandler.
ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
this->service.async_send(this->implementation, buffers, 0,
ASIO_MOVE_CAST(WriteHandler)(handler));
}
@ -285,6 +290,10 @@ public:
void async_send(const ConstBufferSequence& buffers,
socket_base::message_flags flags, WriteHandler handler)
{
// If you get an error on the following line it means that your handler does
// not meet the documented type requirements for a WriteHandler.
ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
this->service.async_send(this->implementation, buffers, flags,
ASIO_MOVE_CAST(WriteHandler)(handler));
}
@ -418,6 +427,10 @@ public:
void async_send_to(const ConstBufferSequence& buffers,
const endpoint_type& destination, WriteHandler handler)
{
// If you get an error on the following line it means that your handler does
// not meet the documented type requirements for a WriteHandler.
ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
this->service.async_send_to(this->implementation, buffers, destination, 0,
ASIO_MOVE_CAST(WriteHandler)(handler));
}
@ -454,6 +467,10 @@ public:
const endpoint_type& destination, socket_base::message_flags flags,
WriteHandler handler)
{
// If you get an error on the following line it means that your handler does
// not meet the documented type requirements for a WriteHandler.
ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
this->service.async_send_to(this->implementation, buffers, destination,
flags, ASIO_MOVE_CAST(WriteHandler)(handler));
}
@ -585,6 +602,10 @@ public:
template <typename MutableBufferSequence, typename ReadHandler>
void async_receive(const MutableBufferSequence& buffers, ReadHandler handler)
{
// If you get an error on the following line it means that your handler does
// not meet the documented type requirements for a ReadHandler.
ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
this->service.async_receive(this->implementation, buffers, 0,
ASIO_MOVE_CAST(ReadHandler)(handler));
}
@ -621,6 +642,10 @@ public:
void async_receive(const MutableBufferSequence& buffers,
socket_base::message_flags flags, ReadHandler handler)
{
// If you get an error on the following line it means that your handler does
// not meet the documented type requirements for a ReadHandler.
ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
this->service.async_receive(this->implementation, buffers, flags,
ASIO_MOVE_CAST(ReadHandler)(handler));
}
@ -754,6 +779,10 @@ public:
void async_receive_from(const MutableBufferSequence& buffers,
endpoint_type& sender_endpoint, ReadHandler handler)
{
// If you get an error on the following line it means that your handler does
// not meet the documented type requirements for a ReadHandler.
ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
this->service.async_receive_from(this->implementation, buffers,
sender_endpoint, 0, ASIO_MOVE_CAST(ReadHandler)(handler));
}
@ -792,6 +821,10 @@ public:
endpoint_type& sender_endpoint, socket_base::message_flags flags,
ReadHandler handler)
{
// If you get an error on the following line it means that your handler does
// not meet the documented type requirements for a ReadHandler.
ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
this->service.async_receive_from(this->implementation, buffers,
sender_endpoint, flags, ASIO_MOVE_CAST(ReadHandler)(handler));
}

View File

@ -19,6 +19,7 @@
#include <cstddef>
#include "asio/basic_io_object.hpp"
#include "asio/deadline_timer_service.hpp"
#include "asio/detail/handler_type_requirements.hpp"
#include "asio/detail/throw_error.hpp"
#include "asio/error.hpp"
@ -492,6 +493,10 @@ public:
template <typename WaitHandler>
void async_wait(WaitHandler handler)
{
// If you get an error on the following line it means that your handler does
// not meet the documented type requirements for a WaitHandler.
ASIO_WAIT_HANDLER_CHECK(WaitHandler, handler) type_check;
this->service.async_wait(this->implementation,
ASIO_MOVE_CAST(WaitHandler)(handler));
}

View File

@ -18,6 +18,7 @@
#include "asio/detail/config.hpp"
#include <cstddef>
#include "asio/basic_socket.hpp"
#include "asio/detail/handler_type_requirements.hpp"
#include "asio/detail/throw_error.hpp"
#include "asio/error.hpp"
#include "asio/raw_socket_service.hpp"
@ -244,6 +245,10 @@ public:
template <typename ConstBufferSequence, typename WriteHandler>
void async_send(const ConstBufferSequence& buffers, WriteHandler handler)
{
// If you get an error on the following line it means that your handler does
// not meet the documented type requirements for a WriteHandler.
ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
this->service.async_send(this->implementation, buffers, 0,
ASIO_MOVE_CAST(WriteHandler)(handler));
}
@ -280,6 +285,10 @@ public:
void async_send(const ConstBufferSequence& buffers,
socket_base::message_flags flags, WriteHandler handler)
{
// If you get an error on the following line it means that your handler does
// not meet the documented type requirements for a WriteHandler.
ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
this->service.async_send(this->implementation, buffers, flags,
ASIO_MOVE_CAST(WriteHandler)(handler));
}
@ -413,6 +422,10 @@ public:
void async_send_to(const ConstBufferSequence& buffers,
const endpoint_type& destination, WriteHandler handler)
{
// If you get an error on the following line it means that your handler does
// not meet the documented type requirements for a WriteHandler.
ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
this->service.async_send_to(this->implementation, buffers, destination, 0,
ASIO_MOVE_CAST(WriteHandler)(handler));
}
@ -449,6 +462,10 @@ public:
const endpoint_type& destination, socket_base::message_flags flags,
WriteHandler handler)
{
// If you get an error on the following line it means that your handler does
// not meet the documented type requirements for a WriteHandler.
ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
this->service.async_send_to(this->implementation, buffers, destination,
flags, ASIO_MOVE_CAST(WriteHandler)(handler));
}
@ -580,6 +597,10 @@ public:
template <typename MutableBufferSequence, typename ReadHandler>
void async_receive(const MutableBufferSequence& buffers, ReadHandler handler)
{
// If you get an error on the following line it means that your handler does
// not meet the documented type requirements for a ReadHandler.
ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
this->service.async_receive(this->implementation, buffers, 0,
ASIO_MOVE_CAST(ReadHandler)(handler));
}
@ -616,6 +637,10 @@ public:
void async_receive(const MutableBufferSequence& buffers,
socket_base::message_flags flags, ReadHandler handler)
{
// If you get an error on the following line it means that your handler does
// not meet the documented type requirements for a ReadHandler.
ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
this->service.async_receive(this->implementation, buffers, flags,
ASIO_MOVE_CAST(ReadHandler)(handler));
}
@ -749,6 +774,10 @@ public:
void async_receive_from(const MutableBufferSequence& buffers,
endpoint_type& sender_endpoint, ReadHandler handler)
{
// If you get an error on the following line it means that your handler does
// not meet the documented type requirements for a ReadHandler.
ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
this->service.async_receive_from(this->implementation, buffers,
sender_endpoint, 0, ASIO_MOVE_CAST(ReadHandler)(handler));
}
@ -787,6 +816,10 @@ public:
endpoint_type& sender_endpoint, socket_base::message_flags flags,
ReadHandler handler)
{
// If you get an error on the following line it means that your handler does
// not meet the documented type requirements for a ReadHandler.
ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
this->service.async_receive_from(this->implementation, buffers,
sender_endpoint, flags, ASIO_MOVE_CAST(ReadHandler)(handler));
}

View File

@ -23,6 +23,7 @@
#include <string>
#include "asio/basic_io_object.hpp"
#include "asio/detail/handler_type_requirements.hpp"
#include "asio/detail/throw_error.hpp"
#include "asio/error.hpp"
#include "asio/serial_port_base.hpp"
@ -502,6 +503,10 @@ public:
void async_write_some(const ConstBufferSequence& buffers,
WriteHandler handler)
{
// If you get an error on the following line it means that your handler does
// not meet the documented type requirements for a WriteHandler.
ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
this->service.async_write_some(this->implementation, buffers,
ASIO_MOVE_CAST(WriteHandler)(handler));
}
@ -607,6 +612,10 @@ public:
void async_read_some(const MutableBufferSequence& buffers,
ReadHandler handler)
{
// If you get an error on the following line it means that your handler does
// not meet the documented type requirements for a ReadHandler.
ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
this->service.async_read_some(this->implementation, buffers,
ASIO_MOVE_CAST(ReadHandler)(handler));
}

View File

@ -17,6 +17,7 @@
#include "asio/detail/config.hpp"
#include "asio/basic_io_object.hpp"
#include "asio/detail/handler_type_requirements.hpp"
#include "asio/detail/throw_error.hpp"
#include "asio/error.hpp"
#include "asio/socket_base.hpp"
@ -639,6 +640,10 @@ public:
template <typename ConnectHandler>
void async_connect(const endpoint_type& peer_endpoint, ConnectHandler handler)
{
// If you get an error on the following line it means that your handler does
// not meet the documented type requirements for a ConnectHandler.
ASIO_CONNECT_HANDLER_CHECK(ConnectHandler, handler) type_check;
if (!is_open())
{
asio::error_code ec;

View File

@ -18,6 +18,7 @@
#include "asio/detail/config.hpp"
#include "asio/basic_io_object.hpp"
#include "asio/basic_socket.hpp"
#include "asio/detail/handler_type_requirements.hpp"
#include "asio/detail/throw_error.hpp"
#include "asio/error.hpp"
#include "asio/socket_acceptor_service.hpp"
@ -712,6 +713,10 @@ public:
void async_accept(basic_socket<protocol_type, SocketService>& peer,
AcceptHandler handler)
{
// If you get an error on the following line it means that your handler does
// not meet the documented type requirements for a AcceptHandler.
ASIO_ACCEPT_HANDLER_CHECK(AcceptHandler, handler) type_check;
this->service.async_accept(this->implementation, peer, 0,
ASIO_MOVE_CAST(AcceptHandler)(handler));
}
@ -814,6 +819,10 @@ public:
void async_accept(basic_socket<protocol_type, SocketService>& peer,
endpoint_type& peer_endpoint, AcceptHandler handler)
{
// If you get an error on the following line it means that your handler does
// not meet the documented type requirements for a AcceptHandler.
ASIO_ACCEPT_HANDLER_CHECK(AcceptHandler, handler) type_check;
this->service.async_accept(this->implementation, peer,
&peer_endpoint, ASIO_MOVE_CAST(AcceptHandler)(handler));
}

View File

@ -18,6 +18,7 @@
#include "asio/detail/config.hpp"
#include <cstddef>
#include "asio/basic_socket.hpp"
#include "asio/detail/handler_type_requirements.hpp"
#include "asio/detail/throw_error.hpp"
#include "asio/error.hpp"
#include "asio/stream_socket_service.hpp"
@ -263,6 +264,10 @@ public:
template <typename ConstBufferSequence, typename WriteHandler>
void async_send(const ConstBufferSequence& buffers, WriteHandler handler)
{
// If you get an error on the following line it means that your handler does
// not meet the documented type requirements for a WriteHandler.
ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
this->service.async_send(this->implementation, buffers, 0,
ASIO_MOVE_CAST(WriteHandler)(handler));
}
@ -308,6 +313,10 @@ public:
void async_send(const ConstBufferSequence& buffers,
socket_base::message_flags flags, WriteHandler handler)
{
// If you get an error on the following line it means that your handler does
// not meet the documented type requirements for a WriteHandler.
ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
this->service.async_send(this->implementation, buffers, flags,
ASIO_MOVE_CAST(WriteHandler)(handler));
}
@ -455,6 +464,10 @@ public:
template <typename MutableBufferSequence, typename ReadHandler>
void async_receive(const MutableBufferSequence& buffers, ReadHandler handler)
{
// If you get an error on the following line it means that your handler does
// not meet the documented type requirements for a ReadHandler.
ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
this->service.async_receive(this->implementation, buffers, 0,
ASIO_MOVE_CAST(ReadHandler)(handler));
}
@ -502,6 +515,10 @@ public:
void async_receive(const MutableBufferSequence& buffers,
socket_base::message_flags flags, ReadHandler handler)
{
// If you get an error on the following line it means that your handler does
// not meet the documented type requirements for a ReadHandler.
ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
this->service.async_receive(this->implementation, buffers, flags,
ASIO_MOVE_CAST(ReadHandler)(handler));
}
@ -604,6 +621,10 @@ public:
void async_write_some(const ConstBufferSequence& buffers,
WriteHandler handler)
{
// If you get an error on the following line it means that your handler does
// not meet the documented type requirements for a WriteHandler.
ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
this->service.async_send(this->implementation, buffers, 0,
ASIO_MOVE_CAST(WriteHandler)(handler));
}
@ -709,6 +730,10 @@ public:
void async_read_some(const MutableBufferSequence& buffers,
ReadHandler handler)
{
// If you get an error on the following line it means that your handler does
// not meet the documented type requirements for a ReadHandler.
ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
this->service.async_receive(this->implementation, buffers, 0,
ASIO_MOVE_CAST(ReadHandler)(handler));
}

View File

@ -0,0 +1,286 @@
//
// detail/handler_type_requirements.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2011 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef ASIO_DETAIL_HANDLER_TYPE_REQUIREMENTS_HPP
#define ASIO_DETAIL_HANDLER_TYPE_REQUIREMENTS_HPP
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
# pragma once
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
#include "asio/detail/config.hpp"
namespace asio {
namespace detail {
// Older versions of gcc have difficulty compiling the sizeof expressions where
// we test the handler type requirements. We'll disable checking of handler type
// requirements for those compilers, but otherwise enable it by default.
#if !defined(ASIO_DISABLE_HANDLER_TYPE_REQUIREMENTS)
# if !defined(__GNUC__) || (__GNUC__ >= 4)
# define ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS 1
# endif // !defined(__GNUC__) || (__GNUC__ >= 4)
#endif // !defined(ASIO_DISABLE_HANDLER_TYPE_REQUIREMENTS)
// With C++0x we can use a combination of enhanced SFINAE and static_assert to
// generate better template error messages. As this technique is not yet widely
// portable, we'll only enable it for tested compilers.
#if !defined(ASIO_DISABLE_HANDLER_TYPE_REQUIREMENTS_ASSERT)
# if defined(__GNUC__)
# if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 5)) || (__GNUC__ > 4)
# if defined(__GXX_EXPERIMENTAL_CXX0X__)
# define ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS_ASSERT 1
# endif // defined(__GXX_EXPERIMENTAL_CXX0X__)
# endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 5)) || (__GNUC__ > 4)
# endif // defined(__GNUC__)
# if defined(BOOST_MSVC)
# if (_MSC_VER >= 1600)
# define ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS_ASSERT 1
# endif // (_MSC_VER >= 1600)
# endif // defined(BOOST_MSVC)
#endif // !defined(ASIO_DISABLE_HANDLER_TYPE_REQUIREMENTS)
#if defined(ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS)
# if defined(ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS_ASSERT)
template <typename Handler>
auto zero_arg_handler_test(Handler* h)
-> decltype(
sizeof(Handler(*static_cast<const Handler*>(h))),
((*h)()),
char(0));
char (&zero_arg_handler_test(...))[2];
template <typename Handler, typename Arg1>
auto one_arg_handler_test(Handler* h, Arg1* a1)
-> decltype(
sizeof(Handler(*static_cast<const Handler*>(h))),
((*h)(*a1)),
char(0));
char (&one_arg_handler_test(...))[2];
template <typename Handler, typename Arg1, typename Arg2>
auto two_arg_handler_test(Handler* h, Arg1* a1, Arg2* a2)
-> decltype(
sizeof(Handler(*static_cast<const Handler*>(h))),
((*h)(*a1, *a2)),
char(0));
char (&two_arg_handler_test(...))[2];
# define ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT(expr, msg) \
static_assert(expr, msg);
# else // defined(ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS_ASSERT)
# define ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT(expr, msg)
# endif // defined(ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS_ASSERT)
template <typename T> T& lvref();
template <int>
struct handler_type_requirements
{
};
#define ASIO_COMPLETION_HANDLER_CHECK( \
handler_type, handler) \
\
ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \
sizeof(asio::detail::zero_arg_handler_test( \
static_cast<handler_type*>(0))) == 1, \
"CompletionHandler type requirements not met") \
\
typedef asio::detail::handler_type_requirements< \
sizeof( \
handler_type( \
static_cast<const handler_type&>(handler))) + \
sizeof( \
handler(), \
char(0))>
#define ASIO_READ_HANDLER_CHECK( \
handler_type, handler) \
\
ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \
sizeof(asio::detail::two_arg_handler_test( \
static_cast<handler_type*>(0), \
static_cast<const asio::error_code*>(0), \
static_cast<const std::size_t*>(0))) == 1, \
"ReadHandler type requirements not met") \
\
typedef asio::detail::handler_type_requirements< \
sizeof( \
handler_type( \
static_cast<const handler_type&>(handler))) + \
sizeof( \
handler( \
asio::detail::lvref<const asio::error_code>(), \
asio::detail::lvref<const std::size_t>()), \
char(0))>
#define ASIO_WRITE_HANDLER_CHECK( \
handler_type, handler) \
\
ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \
sizeof(asio::detail::two_arg_handler_test( \
static_cast<handler_type*>(0), \
static_cast<const asio::error_code*>(0), \
static_cast<const std::size_t*>(0))) == 1, \
"WriteHandler type requirements not met") \
\
typedef asio::detail::handler_type_requirements< \
sizeof( \
handler_type( \
static_cast<const handler_type&>(handler))) + \
sizeof( \
handler( \
asio::detail::lvref<const asio::error_code>(), \
asio::detail::lvref<const std::size_t>()), \
char(0))>
#define ASIO_ACCEPT_HANDLER_CHECK( \
handler_type, handler) \
\
ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \
sizeof(asio::detail::one_arg_handler_test( \
static_cast<handler_type*>(0), \
static_cast<const asio::error_code*>(0))) == 1, \
"AcceptHandler type requirements not met") \
\
typedef asio::detail::handler_type_requirements< \
sizeof( \
handler_type( \
static_cast<const handler_type&>(handler))) + \
sizeof( \
handler( \
asio::detail::lvref<const asio::error_code>()), \
char(0))>
#define ASIO_CONNECT_HANDLER_CHECK( \
handler_type, handler) \
\
ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \
sizeof(asio::detail::one_arg_handler_test( \
static_cast<handler_type*>(0), \
static_cast<const asio::error_code*>(0))) == 1, \
"ConnectHandler type requirements not met") \
\
typedef asio::detail::handler_type_requirements< \
sizeof( \
handler_type( \
static_cast<const handler_type&>(handler))) + \
sizeof( \
handler( \
asio::detail::lvref<const asio::error_code>()), \
char(0))>
#define ASIO_COMPOSED_CONNECT_HANDLER_CHECK( \
handler_type, handler, iter_type) \
\
ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \
sizeof(asio::detail::two_arg_handler_test( \
static_cast<handler_type*>(0), \
static_cast<const asio::error_code*>(0), \
static_cast<const iter_type*>(0))) == 1, \
"ComposedConnectHandler type requirements not met") \
\
typedef asio::detail::handler_type_requirements< \
sizeof( \
handler_type( \
static_cast<const handler_type&>(handler))) + \
sizeof( \
handler( \
asio::detail::lvref<const asio::error_code>(), \
asio::detail::lvref<const iter_type>()), \
char(0))>
#define ASIO_RESOLVE_HANDLER_CHECK( \
handler_type, handler, iter_type) \
\
ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \
sizeof(asio::detail::two_arg_handler_test( \
static_cast<handler_type*>(0), \
static_cast<const asio::error_code*>(0), \
static_cast<const iter_type*>(0))) == 1, \
"ResolveHandler type requirements not met") \
\
typedef asio::detail::handler_type_requirements< \
sizeof( \
handler_type( \
static_cast<const handler_type&>(handler))) + \
sizeof( \
handler( \
asio::detail::lvref<const asio::error_code>(), \
asio::detail::lvref<const iter_type>()), \
char(0))>
#define ASIO_WAIT_HANDLER_CHECK( \
handler_type, handler) \
\
ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \
sizeof(asio::detail::one_arg_handler_test( \
static_cast<handler_type*>(0), \
static_cast<const asio::error_code*>(0))) == 1, \
"WaitHandler type requirements not met") \
\
typedef asio::detail::handler_type_requirements< \
sizeof( \
handler_type( \
static_cast<const handler_type&>(handler))) + \
sizeof( \
handler( \
asio::detail::lvref<const asio::error_code>()), \
char(0))>
#else // !defined(ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS)
#define ASIO_COMPLETION_HANDLER_CHECK( \
handler_type, handler) \
typedef int
#define ASIO_READ_HANDLER_CHECK( \
handler_type, handler) \
typedef int
#define ASIO_WRITE_HANDLER_CHECK( \
handler_type, handler) \
typedef int
#define ASIO_ACCEPT_HANDLER_CHECK( \
handler_type, handler) \
typedef int
#define ASIO_CONNECT_HANDLER_CHECK( \
handler_type, handler) \
typedef int
#define ASIO_COMPOSED_CONNECT_HANDLER_CHECK( \
handler_type, handler, iter_type) \
typedef int
#define ASIO_RESOLVE_HANDLER_CHECK( \
handler_type, handler, iter_type) \
typedef int
#define ASIO_WAIT_HANDLER_CHECK( \
handler_type, handler) \
typedef int
#endif // !defined(ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS)
} // namespace detail
} // namespace asio
#endif // ASIO_DETAIL_HANDLER_TYPE_REQUIREMENTS_HPP

View File

@ -19,6 +19,7 @@
#include "asio/detail/consuming_buffers.hpp"
#include "asio/detail/handler_alloc_helpers.hpp"
#include "asio/detail/handler_invoke_helpers.hpp"
#include "asio/detail/handler_type_requirements.hpp"
#include "asio/detail/throw_error.hpp"
#include "asio/error.hpp"
@ -266,6 +267,11 @@ template <typename Socket, typename Iterator, typename ComposedConnectHandler>
inline void async_connect(Socket& s, Iterator begin,
ComposedConnectHandler handler)
{
// If you get an error on the following line it means that your handler does
// not meet the documented type requirements for a ComposedConnectHandler.
ASIO_COMPOSED_CONNECT_HANDLER_CHECK(
ComposedConnectHandler, handler, Iterator) type_check;
detail::connect_op<Socket, Iterator,
detail::default_connect_condition, ComposedConnectHandler>(
s, begin, Iterator(), detail::default_connect_condition(), handler)(
@ -276,6 +282,11 @@ template <typename Socket, typename Iterator, typename ComposedConnectHandler>
inline void async_connect(Socket& s, Iterator begin, Iterator end,
ComposedConnectHandler handler)
{
// If you get an error on the following line it means that your handler does
// not meet the documented type requirements for a ComposedConnectHandler.
ASIO_COMPOSED_CONNECT_HANDLER_CHECK(
ComposedConnectHandler, handler, Iterator) type_check;
detail::connect_op<Socket, Iterator,
detail::default_connect_condition, ComposedConnectHandler>(
s, begin, end, detail::default_connect_condition(), handler)(
@ -287,6 +298,11 @@ template <typename Socket, typename Iterator,
inline void async_connect(Socket& s, Iterator begin,
ConnectCondition connect_condition, ComposedConnectHandler handler)
{
// If you get an error on the following line it means that your handler does
// not meet the documented type requirements for a ComposedConnectHandler.
ASIO_COMPOSED_CONNECT_HANDLER_CHECK(
ComposedConnectHandler, handler, Iterator) type_check;
detail::connect_op<Socket, Iterator,
ConnectCondition, ComposedConnectHandler>(
s, begin, Iterator(), connect_condition, handler)(
@ -298,6 +314,11 @@ template <typename Socket, typename Iterator,
void async_connect(Socket& s, Iterator begin, Iterator end,
ConnectCondition connect_condition, ComposedConnectHandler handler)
{
// If you get an error on the following line it means that your handler does
// not meet the documented type requirements for a ComposedConnectHandler.
ASIO_COMPOSED_CONNECT_HANDLER_CHECK(
ComposedConnectHandler, handler, Iterator) type_check;
detail::connect_op<Socket, Iterator,
ConnectCondition, ComposedConnectHandler>(
s, begin, end, connect_condition, handler)(

View File

@ -15,6 +15,7 @@
# pragma once
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
#include "asio/detail/handler_type_requirements.hpp"
#include "asio/detail/service_registry.hpp"
#include "asio/detail/push_options.hpp"
@ -68,12 +69,20 @@ namespace asio {
template <typename CompletionHandler>
inline void io_service::dispatch(CompletionHandler handler)
{
// If you get an error on the following line it means that your handler does
// not meet the documented type requirements for a CompletionHandler.
ASIO_COMPLETION_HANDLER_CHECK(CompletionHandler, handler) type_check;
impl_.dispatch(handler);
}
template <typename CompletionHandler>
inline void io_service::post(CompletionHandler handler)
{
// If you get an error on the following line it means that your handler does
// not meet the documented type requirements for a CompletionHandler.
ASIO_COMPLETION_HANDLER_CHECK(CompletionHandler, handler) type_check;
impl_.post(handler);
}

View File

@ -23,6 +23,7 @@
#include "asio/detail/consuming_buffers.hpp"
#include "asio/detail/handler_alloc_helpers.hpp"
#include "asio/detail/handler_invoke_helpers.hpp"
#include "asio/detail/handler_type_requirements.hpp"
#include "asio/detail/throw_error.hpp"
#include "asio/error.hpp"
@ -259,6 +260,10 @@ template <typename AsyncReadStream, typename MutableBufferSequence,
inline void async_read(AsyncReadStream& s, const MutableBufferSequence& buffers,
CompletionCondition completion_condition, ReadHandler handler)
{
// If you get an error on the following line it means that your handler does
// not meet the documented type requirements for a ReadHandler.
ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
detail::read_op<AsyncReadStream, MutableBufferSequence,
CompletionCondition, ReadHandler>(
s, buffers, completion_condition, handler)(
@ -270,6 +275,10 @@ template <typename AsyncReadStream, typename MutableBufferSequence,
inline void async_read(AsyncReadStream& s, const MutableBufferSequence& buffers,
ReadHandler handler)
{
// If you get an error on the following line it means that your handler does
// not meet the documented type requirements for a ReadHandler.
ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
detail::read_op<AsyncReadStream, MutableBufferSequence,
detail::transfer_all_t, ReadHandler>(
s, buffers, transfer_all(), handler)(
@ -367,6 +376,10 @@ inline void async_read(AsyncReadStream& s,
asio::basic_streambuf<Allocator>& b,
CompletionCondition completion_condition, ReadHandler handler)
{
// If you get an error on the following line it means that your handler does
// not meet the documented type requirements for a ReadHandler.
ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
detail::read_streambuf_op<AsyncReadStream,
Allocator, CompletionCondition, ReadHandler>(
s, b, completion_condition, handler)(
@ -377,6 +390,10 @@ template <typename AsyncReadStream, typename Allocator, typename ReadHandler>
inline void async_read(AsyncReadStream& s,
asio::basic_streambuf<Allocator>& b, ReadHandler handler)
{
// If you get an error on the following line it means that your handler does
// not meet the documented type requirements for a ReadHandler.
ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
detail::read_streambuf_op<AsyncReadStream,
Allocator, detail::transfer_all_t, ReadHandler>(
s, b, transfer_all(), handler)(

View File

@ -23,6 +23,7 @@
#include "asio/detail/consuming_buffers.hpp"
#include "asio/detail/handler_alloc_helpers.hpp"
#include "asio/detail/handler_invoke_helpers.hpp"
#include "asio/detail/handler_type_requirements.hpp"
#include "asio/detail/throw_error.hpp"
#include "asio/error.hpp"
@ -277,6 +278,10 @@ inline void async_read_at(AsyncRandomAccessReadDevice& d,
boost::uint64_t offset, const MutableBufferSequence& buffers,
CompletionCondition completion_condition, ReadHandler handler)
{
// If you get an error on the following line it means that your handler does
// not meet the documented type requirements for a ReadHandler.
ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
detail::read_at_op<AsyncRandomAccessReadDevice,
MutableBufferSequence, CompletionCondition, ReadHandler>(
d, offset, buffers, completion_condition, handler)(
@ -289,6 +294,10 @@ inline void async_read_at(AsyncRandomAccessReadDevice& d,
boost::uint64_t offset, const MutableBufferSequence& buffers,
ReadHandler handler)
{
// If you get an error on the following line it means that your handler does
// not meet the documented type requirements for a ReadHandler.
ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
detail::read_at_op<AsyncRandomAccessReadDevice,
MutableBufferSequence, detail::transfer_all_t, ReadHandler>(
d, offset, buffers, transfer_all(), handler)(
@ -389,6 +398,10 @@ inline void async_read_at(AsyncRandomAccessReadDevice& d,
boost::uint64_t offset, asio::basic_streambuf<Allocator>& b,
CompletionCondition completion_condition, ReadHandler handler)
{
// If you get an error on the following line it means that your handler does
// not meet the documented type requirements for a ReadHandler.
ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
detail::read_at_streambuf_op<AsyncRandomAccessReadDevice,
Allocator, CompletionCondition, ReadHandler>(
d, offset, b, completion_condition, handler)(
@ -401,6 +414,10 @@ inline void async_read_at(AsyncRandomAccessReadDevice& d,
boost::uint64_t offset, asio::basic_streambuf<Allocator>& b,
ReadHandler handler)
{
// If you get an error on the following line it means that your handler does
// not meet the documented type requirements for a ReadHandler.
ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
detail::read_at_streambuf_op<AsyncRandomAccessReadDevice,
Allocator, detail::transfer_all_t, ReadHandler>(
d, offset, b, transfer_all(), handler)(

View File

@ -25,6 +25,7 @@
#include "asio/detail/bind_handler.hpp"
#include "asio/detail/handler_alloc_helpers.hpp"
#include "asio/detail/handler_invoke_helpers.hpp"
#include "asio/detail/handler_type_requirements.hpp"
#include "asio/detail/throw_error.hpp"
#include "asio/detail/push_options.hpp"
@ -444,6 +445,10 @@ template <typename AsyncReadStream, typename Allocator, typename ReadHandler>
void async_read_until(AsyncReadStream& s,
asio::basic_streambuf<Allocator>& b, char delim, ReadHandler handler)
{
// If you get an error on the following line it means that your handler does
// not meet the documented type requirements for a ReadHandler.
ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
detail::read_until_delim_op<
AsyncReadStream, Allocator, ReadHandler>(
s, b, delim, handler)(
@ -589,6 +594,10 @@ void async_read_until(AsyncReadStream& s,
asio::basic_streambuf<Allocator>& b, const std::string& delim,
ReadHandler handler)
{
// If you get an error on the following line it means that your handler does
// not meet the documented type requirements for a ReadHandler.
ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
detail::read_until_delim_string_op<
AsyncReadStream, Allocator, ReadHandler>(
s, b, delim, handler)(
@ -740,6 +749,10 @@ void async_read_until(AsyncReadStream& s,
asio::basic_streambuf<Allocator>& b, const boost::regex& expr,
ReadHandler handler)
{
// If you get an error on the following line it means that your handler does
// not meet the documented type requirements for a ReadHandler.
ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
detail::read_until_expr_op<AsyncReadStream,
Allocator, boost::regex, ReadHandler>(
s, b, expr, handler)(
@ -889,6 +902,10 @@ void async_read_until(AsyncReadStream& s,
MatchCondition match_condition, ReadHandler handler,
typename boost::enable_if<is_match_condition<MatchCondition> >::type*)
{
// If you get an error on the following line it means that your handler does
// not meet the documented type requirements for a ReadHandler.
ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
detail::read_until_match_op<
AsyncReadStream, Allocator, MatchCondition, ReadHandler>(
s, b, match_condition, handler)(

View File

@ -22,6 +22,7 @@
#include "asio/detail/consuming_buffers.hpp"
#include "asio/detail/handler_alloc_helpers.hpp"
#include "asio/detail/handler_invoke_helpers.hpp"
#include "asio/detail/handler_type_requirements.hpp"
#include "asio/detail/throw_error.hpp"
#include "asio/detail/push_options.hpp"
@ -296,6 +297,10 @@ template <typename AsyncWriteStream, typename ConstBufferSequence,
inline void async_write(AsyncWriteStream& s, const ConstBufferSequence& buffers,
CompletionCondition completion_condition, WriteHandler handler)
{
// If you get an error on the following line it means that your handler does
// not meet the documented type requirements for a WriteHandler.
ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
detail::write_op<AsyncWriteStream, ConstBufferSequence,
CompletionCondition, WriteHandler>(
s, buffers, completion_condition, handler)(
@ -307,6 +312,10 @@ template <typename AsyncWriteStream, typename ConstBufferSequence,
inline void async_write(AsyncWriteStream& s, const ConstBufferSequence& buffers,
WriteHandler handler)
{
// If you get an error on the following line it means that your handler does
// not meet the documented type requirements for a WriteHandler.
ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
detail::write_op<AsyncWriteStream, ConstBufferSequence,
detail::transfer_all_t, WriteHandler>(
s, buffers, transfer_all(), handler)(
@ -378,6 +387,10 @@ inline void async_write(AsyncWriteStream& s,
asio::basic_streambuf<Allocator>& b,
CompletionCondition completion_condition, WriteHandler handler)
{
// If you get an error on the following line it means that your handler does
// not meet the documented type requirements for a WriteHandler.
ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
async_write(s, b.data(), completion_condition,
detail::write_streambuf_handler<
AsyncWriteStream, Allocator, WriteHandler>(b, handler));
@ -387,6 +400,10 @@ template <typename AsyncWriteStream, typename Allocator, typename WriteHandler>
inline void async_write(AsyncWriteStream& s,
asio::basic_streambuf<Allocator>& b, WriteHandler handler)
{
// If you get an error on the following line it means that your handler does
// not meet the documented type requirements for a WriteHandler.
ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
async_write(s, b.data(), transfer_all(),
detail::write_streambuf_handler<
AsyncWriteStream, Allocator, WriteHandler>(b, handler));

View File

@ -22,6 +22,7 @@
#include "asio/detail/consuming_buffers.hpp"
#include "asio/detail/handler_alloc_helpers.hpp"
#include "asio/detail/handler_invoke_helpers.hpp"
#include "asio/detail/handler_type_requirements.hpp"
#include "asio/detail/throw_error.hpp"
#include "asio/detail/push_options.hpp"
@ -313,6 +314,10 @@ inline void async_write_at(AsyncRandomAccessWriteDevice& d,
boost::uint64_t offset, const ConstBufferSequence& buffers,
CompletionCondition completion_condition, WriteHandler handler)
{
// If you get an error on the following line it means that your handler does
// not meet the documented type requirements for a WriteHandler.
ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
detail::write_at_op<AsyncRandomAccessWriteDevice,
ConstBufferSequence, CompletionCondition, WriteHandler>(
d, offset, buffers, completion_condition, handler)(
@ -325,6 +330,10 @@ inline void async_write_at(AsyncRandomAccessWriteDevice& d,
boost::uint64_t offset, const ConstBufferSequence& buffers,
WriteHandler handler)
{
// If you get an error on the following line it means that your handler does
// not meet the documented type requirements for a WriteHandler.
ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
detail::write_at_op<AsyncRandomAccessWriteDevice,
ConstBufferSequence, detail::transfer_all_t, WriteHandler>(
d, offset, buffers, transfer_all(), handler)(
@ -397,6 +406,10 @@ inline void async_write_at(AsyncRandomAccessWriteDevice& d,
boost::uint64_t offset, asio::basic_streambuf<Allocator>& b,
CompletionCondition completion_condition, WriteHandler handler)
{
// If you get an error on the following line it means that your handler does
// not meet the documented type requirements for a WriteHandler.
ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
async_write_at(d, offset, b.data(), completion_condition,
detail::write_at_streambuf_op<
AsyncRandomAccessWriteDevice, Allocator, WriteHandler>(b, handler));
@ -408,6 +421,10 @@ inline void async_write_at(AsyncRandomAccessWriteDevice& d,
boost::uint64_t offset, asio::basic_streambuf<Allocator>& b,
WriteHandler handler)
{
// If you get an error on the following line it means that your handler does
// not meet the documented type requirements for a WriteHandler.
ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
async_write_at(d, offset, b.data(), transfer_all(),
detail::write_at_streambuf_op<
AsyncRandomAccessWriteDevice, Allocator, WriteHandler>(b, handler));

View File

@ -17,6 +17,7 @@
#include "asio/detail/config.hpp"
#include "asio/basic_io_object.hpp"
#include "asio/detail/handler_type_requirements.hpp"
#include "asio/detail/throw_error.hpp"
#include "asio/error.hpp"
#include "asio/ip/basic_resolver_iterator.hpp"
@ -153,6 +154,11 @@ public:
template <typename ResolveHandler>
void async_resolve(const query& q, ResolveHandler handler)
{
// If you get an error on the following line it means that your handler does
// not meet the documented type requirements for a ResolveHandler.
ASIO_RESOLVE_HANDLER_CHECK(
ResolveHandler, handler, iterator) type_check;
return this->service.async_resolve(this->implementation, q,
ASIO_MOVE_CAST(ResolveHandler)(handler));
}
@ -238,6 +244,11 @@ public:
template <typename ResolveHandler>
void async_resolve(const endpoint_type& e, ResolveHandler handler)
{
// If you get an error on the following line it means that your handler does
// not meet the documented type requirements for a ResolveHandler.
ASIO_RESOLVE_HANDLER_CHECK(
ResolveHandler, handler, iterator) type_check;
return this->service.async_resolve(this->implementation, e,
ASIO_MOVE_CAST(ResolveHandler)(handler));
}

View File

@ -21,6 +21,7 @@
|| defined(GENERATING_DOCUMENTATION)
#include <cstddef>
#include "asio/detail/handler_type_requirements.hpp"
#include "asio/detail/throw_error.hpp"
#include "asio/error.hpp"
#include "asio/posix/basic_descriptor.hpp"
@ -183,6 +184,10 @@ public:
void async_write_some(const ConstBufferSequence& buffers,
WriteHandler handler)
{
// If you get an error on the following line it means that your handler does
// not meet the documented type requirements for a WriteHandler.
ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
this->service.async_write_some(this->implementation, buffers,
ASIO_MOVE_CAST(WriteHandler)(handler));
}
@ -288,6 +293,10 @@ public:
void async_read_some(const MutableBufferSequence& buffers,
ReadHandler handler)
{
// If you get an error on the following line it means that your handler does
// not meet the documented type requirements for a ReadHandler.
ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
this->service.async_read_some(this->implementation, buffers,
ASIO_MOVE_CAST(ReadHandler)(handler));
}

View File

@ -16,6 +16,7 @@
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
#include "asio/detail/config.hpp"
#include "asio/detail/handler_type_requirements.hpp"
#include "asio/detail/strand_service.hpp"
#include "asio/detail/wrapped_handler.hpp"
#include "asio/io_service.hpp"
@ -141,6 +142,10 @@ public:
template <typename CompletionHandler>
void dispatch(CompletionHandler handler)
{
// If you get an error on the following line it means that your handler does
// not meet the documented type requirements for a CompletionHandler.
ASIO_COMPLETION_HANDLER_CHECK(CompletionHandler, handler) type_check;
service_.dispatch(impl_, handler);
}
@ -163,6 +168,10 @@ public:
template <typename CompletionHandler>
void post(CompletionHandler handler)
{
// If you get an error on the following line it means that your handler does
// not meet the documented type requirements for a CompletionHandler.
ASIO_COMPLETION_HANDLER_CHECK(CompletionHandler, handler) type_check;
service_.post(impl_, handler);
}

View File

@ -21,6 +21,7 @@
|| defined(GENERATING_DOCUMENTATION)
#include <cstddef>
#include "asio/detail/handler_type_requirements.hpp"
#include "asio/detail/throw_error.hpp"
#include "asio/error.hpp"
#include "asio/windows/basic_handle.hpp"
@ -188,6 +189,10 @@ public:
void async_write_some_at(boost::uint64_t offset,
const ConstBufferSequence& buffers, WriteHandler handler)
{
// If you get an error on the following line it means that your handler does
// not meet the documented type requirements for a WriteHandler.
ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
this->service.async_write_some_at(this->implementation,
offset, buffers, ASIO_MOVE_CAST(WriteHandler)(handler));
}
@ -302,6 +307,10 @@ public:
void async_read_some_at(boost::uint64_t offset,
const MutableBufferSequence& buffers, ReadHandler handler)
{
// If you get an error on the following line it means that your handler does
// not meet the documented type requirements for a ReadHandler.
ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
this->service.async_read_some_at(this->implementation,
offset, buffers, ASIO_MOVE_CAST(ReadHandler)(handler));
}

View File

@ -21,10 +21,11 @@
|| defined(GENERATING_DOCUMENTATION)
#include <cstddef>
#include "asio/detail/handler_type_requirements.hpp"
#include "asio/detail/throw_error.hpp"
#include "asio/error.hpp"
#include "asio/windows/basic_handle.hpp"
#include "asio/windows/stream_handle_service.hpp"
#include "asio/detail/throw_error.hpp"
#include "asio/detail/push_options.hpp"
@ -181,6 +182,10 @@ public:
void async_write_some(const ConstBufferSequence& buffers,
WriteHandler handler)
{
// If you get an error on the following line it means that your handler does
// not meet the documented type requirements for a WriteHandler.
ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
this->service.async_write_some(this->implementation, buffers,
ASIO_MOVE_CAST(WriteHandler)(handler));
}
@ -286,6 +291,10 @@ public:
void async_read_some(const MutableBufferSequence& buffers,
ReadHandler handler)
{
// If you get an error on the following line it means that your handler does
// not meet the documented type requirements for a ReadHandler.
ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
this->service.async_read_some(this->implementation, buffers,
ASIO_MOVE_CAST(ReadHandler)(handler));
}