File indexing completed on 2025-01-18 09:28:50
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #ifndef BOOST_ASIO_EXPERIMENTAL_DETAIL_CHANNEL_PAYLOAD_HPP
0012 #define BOOST_ASIO_EXPERIMENTAL_DETAIL_CHANNEL_PAYLOAD_HPP
0013
0014 #if defined(_MSC_VER) && (_MSC_VER >= 1200)
0015 # pragma once
0016 #endif
0017
0018 #include <boost/asio/detail/config.hpp>
0019 #include <boost/asio/detail/type_traits.hpp>
0020 #include <boost/system/error_code.hpp>
0021 #include <boost/asio/experimental/detail/channel_message.hpp>
0022
0023 #if defined(BOOST_ASIO_HAS_STD_VARIANT)
0024 # include <variant>
0025 #else
0026 # include <new>
0027 #endif
0028
0029 #include <boost/asio/detail/push_options.hpp>
0030
0031 namespace boost {
0032 namespace asio {
0033 namespace experimental {
0034 namespace detail {
0035
0036 template <typename... Signatures>
0037 class channel_payload;
0038
0039 template <typename R>
0040 class channel_payload<R()>
0041 {
0042 public:
0043 explicit channel_payload(channel_message<R()>)
0044 {
0045 }
0046
0047 template <typename Handler>
0048 void receive(Handler& handler)
0049 {
0050 static_cast<Handler&&>(handler)();
0051 }
0052 };
0053
0054 template <typename Signature>
0055 class channel_payload<Signature>
0056 {
0057 public:
0058 channel_payload(channel_message<Signature>&& m)
0059 : message_(static_cast<channel_message<Signature>&&>(m))
0060 {
0061 }
0062
0063 template <typename Handler>
0064 void receive(Handler& handler)
0065 {
0066 message_.receive(handler);
0067 }
0068
0069 private:
0070 channel_message<Signature> message_;
0071 };
0072
0073 #if defined(BOOST_ASIO_HAS_STD_VARIANT)
0074
0075 template <typename... Signatures>
0076 class channel_payload
0077 {
0078 public:
0079 template <typename Signature>
0080 channel_payload(channel_message<Signature>&& m)
0081 : message_(static_cast<channel_message<Signature>&&>(m))
0082 {
0083 }
0084
0085 template <typename Handler>
0086 void receive(Handler& handler)
0087 {
0088 std::visit(
0089 [&](auto& message)
0090 {
0091 message.receive(handler);
0092 }, message_);
0093 }
0094
0095 private:
0096 std::variant<channel_message<Signatures>...> message_;
0097 };
0098
0099 #else
0100
0101 template <typename R1, typename R2>
0102 class channel_payload<R1(), R2(boost::system::error_code)>
0103 {
0104 public:
0105 typedef channel_message<R1()> void_message_type;
0106 typedef channel_message<R2(boost::system::error_code)> error_message_type;
0107
0108 channel_payload(void_message_type&&)
0109 : message_(0, boost::system::error_code()),
0110 empty_(true)
0111 {
0112 }
0113
0114 channel_payload(error_message_type&& m)
0115 : message_(static_cast<error_message_type&&>(m)),
0116 empty_(false)
0117 {
0118 }
0119
0120 template <typename Handler>
0121 void receive(Handler& handler)
0122 {
0123 if (empty_)
0124 channel_message<R1()>(0).receive(handler);
0125 else
0126 message_.receive(handler);
0127 }
0128
0129 private:
0130 error_message_type message_;
0131 bool empty_;
0132 };
0133
0134 template <typename Sig1, typename Sig2>
0135 class channel_payload<Sig1, Sig2>
0136 {
0137 public:
0138 typedef channel_message<Sig1> message_1_type;
0139 typedef channel_message<Sig2> message_2_type;
0140
0141 channel_payload(message_1_type&& m)
0142 : index_(1)
0143 {
0144 new (&storage_.message_1_) message_1_type(static_cast<message_1_type&&>(m));
0145 }
0146
0147 channel_payload(message_2_type&& m)
0148 : index_(2)
0149 {
0150 new (&storage_.message_2_) message_2_type(static_cast<message_2_type&&>(m));
0151 }
0152
0153 channel_payload(channel_payload&& other)
0154 : index_(other.index_)
0155 {
0156 switch (index_)
0157 {
0158 case 1:
0159 new (&storage_.message_1_) message_1_type(
0160 static_cast<message_1_type&&>(other.storage_.message_1_));
0161 break;
0162 case 2:
0163 new (&storage_.message_2_) message_2_type(
0164 static_cast<message_2_type&&>(other.storage_.message_2_));
0165 break;
0166 default:
0167 break;
0168 }
0169 }
0170
0171 ~channel_payload()
0172 {
0173 switch (index_)
0174 {
0175 case 1:
0176 storage_.message_1_.~message_1_type();
0177 break;
0178 case 2:
0179 storage_.message_2_.~message_2_type();
0180 break;
0181 default:
0182 break;
0183 }
0184 }
0185
0186 template <typename Handler>
0187 void receive(Handler& handler)
0188 {
0189 switch (index_)
0190 {
0191 case 1:
0192 storage_.message_1_.receive(handler);
0193 break;
0194 case 2:
0195 storage_.message_2_.receive(handler);
0196 break;
0197 default:
0198 break;
0199 }
0200 }
0201
0202 private:
0203 union storage
0204 {
0205 storage() {}
0206 ~storage() {}
0207
0208 char dummy_;
0209 message_1_type message_1_;
0210 message_2_type message_2_;
0211 } storage_;
0212 unsigned char index_;
0213 };
0214
0215 #endif
0216
0217 }
0218 }
0219 }
0220 }
0221
0222 #include <boost/asio/detail/pop_options.hpp>
0223
0224 #endif