mirror of
https://github.com/boostorg/asio.git
synced 2026-01-25 05:52:09 +00:00
Fix channels to support C++14 and (partially) C++11.
C++11 support is limited to channels with a single completion signature, or channels with a void() signature (plus the error signature added by the channel traits).
This commit is contained in:
@@ -1443,6 +1443,30 @@
|
||||
# endif // !defined(BOOST_ASIO_DISABLE_STD_ANY)
|
||||
#endif // !defined(BOOST_ASIO_HAS_STD_ANY)
|
||||
|
||||
// Standard library support for std::variant.
|
||||
#if !defined(BOOST_ASIO_HAS_STD_VARIANT)
|
||||
# if !defined(BOOST_ASIO_DISABLE_STD_VARIANT)
|
||||
# if defined(__clang__)
|
||||
# if (__cplusplus >= 201703)
|
||||
# if __has_include(<variant>)
|
||||
# define BOOST_ASIO_HAS_STD_VARIANT 1
|
||||
# endif // __has_include(<variant>)
|
||||
# endif // (__cplusplus >= 201703)
|
||||
# elif defined(__GNUC__)
|
||||
# if (__GNUC__ >= 7)
|
||||
# if (__cplusplus >= 201703)
|
||||
# define BOOST_ASIO_HAS_STD_VARIANT 1
|
||||
# endif // (__cplusplus >= 201703)
|
||||
# endif // (__GNUC__ >= 7)
|
||||
# endif // defined(__GNUC__)
|
||||
# if defined(BOOST_ASIO_MSVC)
|
||||
# if (_MSC_VER >= 1910) && (_MSVC_LANG >= 201703)
|
||||
# define BOOST_ASIO_HAS_STD_VARIANT 1
|
||||
# endif // (_MSC_VER >= 1910) && (_MSVC_LANG >= 201703)
|
||||
# endif // defined(BOOST_ASIO_MSVC)
|
||||
# endif // !defined(BOOST_ASIO_DISABLE_STD_VARIANT)
|
||||
#endif // !defined(BOOST_ASIO_HAS_STD_VARIANT)
|
||||
|
||||
// Standard library support for std::source_location.
|
||||
#if !defined(BOOST_ASIO_HAS_STD_SOURCE_LOCATION)
|
||||
# if !defined(BOOST_ASIO_DISABLE_STD_SOURCE_LOCATION)
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
#include <boost/asio/detail/config.hpp>
|
||||
#include <tuple>
|
||||
#include <boost/asio/detail/type_traits.hpp>
|
||||
#include <boost/asio/detail/utility.hpp>
|
||||
|
||||
#include <boost/asio/detail/push_options.hpp>
|
||||
|
||||
@@ -105,11 +106,17 @@ public:
|
||||
template <typename Handler>
|
||||
void receive(Handler& h)
|
||||
{
|
||||
std::apply(BOOST_ASIO_MOVE_OR_LVALUE(Handler)(h),
|
||||
BOOST_ASIO_MOVE_CAST(args_type)(args_));
|
||||
this->do_receive(h, boost::asio::detail::index_sequence_for<Args...>());
|
||||
}
|
||||
|
||||
private:
|
||||
template <typename Handler, std::size_t... I>
|
||||
void do_receive(Handler& h, boost::asio::detail::index_sequence<I...>)
|
||||
{
|
||||
BOOST_ASIO_MOVE_OR_LVALUE(Handler)(h)(
|
||||
std::get<I>(BOOST_ASIO_MOVE_CAST(args_type)(args_))...);
|
||||
}
|
||||
|
||||
typedef std::tuple<typename decay<Args>::type...> args_type;
|
||||
args_type args_;
|
||||
};
|
||||
|
||||
@@ -16,10 +16,14 @@
|
||||
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||
|
||||
#include <boost/asio/detail/config.hpp>
|
||||
#include <variant>
|
||||
#include <boost/asio/detail/type_traits.hpp>
|
||||
#include <boost/system/error_code.hpp>
|
||||
#include <boost/asio/experimental/detail/channel_message.hpp>
|
||||
|
||||
#if defined(BOOST_ASIO_HAS_STD_VARIANT)
|
||||
# include <variant>
|
||||
#endif // defined(BOOST_ASIO_HAS_STD_VARIANT)
|
||||
|
||||
#include <boost/asio/detail/push_options.hpp>
|
||||
|
||||
namespace boost {
|
||||
@@ -28,28 +32,7 @@ namespace experimental {
|
||||
namespace detail {
|
||||
|
||||
template <typename... Signatures>
|
||||
class channel_payload
|
||||
{
|
||||
public:
|
||||
template <typename Signature>
|
||||
channel_payload(BOOST_ASIO_MOVE_ARG(channel_message<Signature>) m)
|
||||
: message_(BOOST_ASIO_MOVE_CAST(channel_message<Signature>)(m))
|
||||
{
|
||||
}
|
||||
|
||||
template <typename Handler>
|
||||
void receive(Handler& handler)
|
||||
{
|
||||
std::visit(
|
||||
[&](auto& message)
|
||||
{
|
||||
message.receive(handler);
|
||||
}, message_);
|
||||
}
|
||||
|
||||
private:
|
||||
std::variant<channel_message<Signatures>...> message_;
|
||||
};
|
||||
class channel_payload;
|
||||
|
||||
template <typename R>
|
||||
class channel_payload<R()>
|
||||
@@ -85,6 +68,69 @@ private:
|
||||
channel_message<Signature> message_;
|
||||
};
|
||||
|
||||
#if defined(BOOST_ASIO_HAS_STD_VARIANT)
|
||||
|
||||
template <typename... Signatures>
|
||||
class channel_payload
|
||||
{
|
||||
public:
|
||||
template <typename Signature>
|
||||
channel_payload(BOOST_ASIO_MOVE_ARG(channel_message<Signature>) m)
|
||||
: message_(BOOST_ASIO_MOVE_CAST(channel_message<Signature>)(m))
|
||||
{
|
||||
}
|
||||
|
||||
template <typename Handler>
|
||||
void receive(Handler& handler)
|
||||
{
|
||||
std::visit(
|
||||
[&](auto& message)
|
||||
{
|
||||
message.receive(handler);
|
||||
}, message_);
|
||||
}
|
||||
|
||||
private:
|
||||
std::variant<channel_message<Signatures>...> message_;
|
||||
};
|
||||
|
||||
#else // defined(BOOST_ASIO_HAS_STD_VARIANT)
|
||||
|
||||
template <typename R1, typename R2>
|
||||
class channel_payload<R1(), R2(boost::system::error_code)>
|
||||
{
|
||||
public:
|
||||
typedef channel_message<R1()> void_message_type;
|
||||
typedef channel_message<R2(boost::system::error_code)> error_message_type;
|
||||
|
||||
channel_payload(BOOST_ASIO_MOVE_ARG(void_message_type))
|
||||
: message_(0, boost::system::error_code()),
|
||||
empty_(true)
|
||||
{
|
||||
}
|
||||
|
||||
channel_payload(BOOST_ASIO_MOVE_ARG(error_message_type) m)
|
||||
: message_(BOOST_ASIO_MOVE_CAST(error_message_type)(m)),
|
||||
empty_(false)
|
||||
{
|
||||
}
|
||||
|
||||
template <typename Handler>
|
||||
void receive(Handler& handler)
|
||||
{
|
||||
if (empty_)
|
||||
channel_message<R1()>(0).receive(handler);
|
||||
else
|
||||
message_.receive(handler);
|
||||
}
|
||||
|
||||
private:
|
||||
error_message_type message_;
|
||||
bool empty_;
|
||||
};
|
||||
|
||||
#endif // defined(BOOST_ASIO_HAS_STD_VARIANT)
|
||||
|
||||
} // namespace detail
|
||||
} // namespace experimental
|
||||
} // namespace asio
|
||||
|
||||
@@ -65,6 +65,12 @@ public:
|
||||
auto async_send(Args... args,
|
||||
BOOST_ASIO_MOVE_ARG(CompletionToken) token
|
||||
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(Executor))
|
||||
-> decltype(
|
||||
async_initiate<CompletionToken, void (boost::system::error_code)>(
|
||||
declval<typename conditional<false, CompletionToken,
|
||||
Derived>::type::initiate_async_send>(), token,
|
||||
declval<typename conditional<false, CompletionToken,
|
||||
Derived>::type::payload_type>()))
|
||||
{
|
||||
typedef typename Derived::payload_type payload_type;
|
||||
typedef typename detail::channel_message<R(Args...)> message_type;
|
||||
@@ -114,6 +120,12 @@ public:
|
||||
auto async_send(Args... args,
|
||||
BOOST_ASIO_MOVE_ARG(CompletionToken) token
|
||||
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(Executor))
|
||||
-> decltype(
|
||||
async_initiate<CompletionToken, void (boost::system::error_code)>(
|
||||
declval<typename conditional<false, CompletionToken,
|
||||
Derived>::type::initiate_async_send>(), token,
|
||||
declval<typename conditional<false, CompletionToken,
|
||||
Derived>::type::payload_type>()))
|
||||
{
|
||||
typedef typename Derived::payload_type payload_type;
|
||||
typedef typename detail::channel_message<R(Args...)> message_type;
|
||||
|
||||
@@ -537,6 +537,7 @@ struct channel_service<Mutex>::implementation_type<
|
||||
implementation_type()
|
||||
: size_(0)
|
||||
{
|
||||
first_.count_ = 0;
|
||||
}
|
||||
|
||||
// Move from another buffer.
|
||||
@@ -637,7 +638,7 @@ private:
|
||||
struct buffered_value
|
||||
{
|
||||
boost::system::error_code value_;
|
||||
std::size_t count_ = 0;
|
||||
std::size_t count_;
|
||||
};
|
||||
|
||||
struct value_handler
|
||||
|
||||
Reference in New Issue
Block a user