Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:28:50

0001 //
0002 // experimental/detail/channel_payload.hpp
0003 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
0004 //
0005 // Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)
0006 //
0007 // Distributed under the Boost Software License, Version 1.0. (See accompanying
0008 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
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 // defined(_MSC_VER) && (_MSC_VER >= 1200)
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 // defined(BOOST_ASIO_HAS_STD_VARIANT)
0026 # include <new>
0027 #endif // defined(BOOST_ASIO_HAS_STD_VARIANT)
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 // defined(BOOST_ASIO_HAS_STD_VARIANT)
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 // defined(BOOST_ASIO_HAS_STD_VARIANT)
0216 
0217 } // namespace detail
0218 } // namespace experimental
0219 } // namespace asio
0220 } // namespace boost
0221 
0222 #include <boost/asio/detail/pop_options.hpp>
0223 
0224 #endif // BOOST_ASIO_EXPERIMENTAL_DETAIL_CHANNEL_PAYLOAD_HPP