Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-07-02 08:06:50

0001 //
0002 // associated_immediate_executor.hpp
0003 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
0004 //
0005 // Copyright (c) 2003-2024 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_ASSOCIATED_IMMEDIATE_EXECUTOR_HPP
0012 #define BOOST_ASIO_ASSOCIATED_IMMEDIATE_EXECUTOR_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/associator.hpp>
0020 #include <boost/asio/detail/functional.hpp>
0021 #include <boost/asio/detail/type_traits.hpp>
0022 #include <boost/asio/execution/blocking.hpp>
0023 #include <boost/asio/execution/executor.hpp>
0024 #include <boost/asio/execution_context.hpp>
0025 #include <boost/asio/is_executor.hpp>
0026 #include <boost/asio/require.hpp>
0027 
0028 #include <boost/asio/detail/push_options.hpp>
0029 
0030 namespace boost {
0031 namespace asio {
0032 
0033 template <typename T, typename Executor>
0034 struct associated_immediate_executor;
0035 
0036 namespace detail {
0037 
0038 template <typename T, typename = void>
0039 struct has_immediate_executor_type : false_type
0040 {
0041 };
0042 
0043 template <typename T>
0044 struct has_immediate_executor_type<T,
0045   void_t<typename T::immediate_executor_type>>
0046     : true_type
0047 {
0048 };
0049 
0050 template <typename E, typename = void, typename = void>
0051 struct default_immediate_executor
0052 {
0053   typedef decay_t<require_result_t<E, execution::blocking_t::never_t>> type;
0054 
0055   static auto get(const E& e) noexcept
0056     -> decltype(boost::asio::require(e, execution::blocking.never))
0057   {
0058     return boost::asio::require(e, execution::blocking.never);
0059   }
0060 };
0061 
0062 template <typename E>
0063 struct default_immediate_executor<E,
0064   enable_if_t<
0065     !execution::is_executor<E>::value
0066   >,
0067   enable_if_t<
0068     is_executor<E>::value
0069   >>
0070 {
0071   class type : public E
0072   {
0073   public:
0074     template <typename Executor1>
0075     explicit type(const Executor1& e,
0076         constraint_t<
0077           conditional_t<
0078             !is_same<Executor1, type>::value,
0079             is_convertible<Executor1, E>,
0080             false_type
0081           >::value
0082         > = 0) noexcept
0083       : E(e)
0084     {
0085     }
0086 
0087     type(const type& other) noexcept
0088       : E(static_cast<const E&>(other))
0089     {
0090     }
0091 
0092     type(type&& other) noexcept
0093       : E(static_cast<E&&>(other))
0094     {
0095     }
0096 
0097     template <typename Function, typename Allocator>
0098     void dispatch(Function&& f, const Allocator& a) const
0099     {
0100       this->post(static_cast<Function&&>(f), a);
0101     }
0102 
0103     friend bool operator==(const type& a, const type& b) noexcept
0104     {
0105       return static_cast<const E&>(a) == static_cast<const E&>(b);
0106     }
0107 
0108     friend bool operator!=(const type& a, const type& b) noexcept
0109     {
0110       return static_cast<const E&>(a) != static_cast<const E&>(b);
0111     }
0112   };
0113 
0114   static type get(const E& e) noexcept
0115   {
0116     return type(e);
0117   }
0118 };
0119 
0120 template <typename T, typename E, typename = void, typename = void>
0121 struct associated_immediate_executor_impl
0122 {
0123   typedef void asio_associated_immediate_executor_is_unspecialised;
0124 
0125   typedef typename default_immediate_executor<E>::type type;
0126 
0127   static auto get(const T&, const E& e) noexcept
0128     -> decltype(default_immediate_executor<E>::get(e))
0129   {
0130     return default_immediate_executor<E>::get(e);
0131   }
0132 };
0133 
0134 template <typename T, typename E>
0135 struct associated_immediate_executor_impl<T, E,
0136   void_t<typename T::immediate_executor_type>>
0137 {
0138   typedef typename T::immediate_executor_type type;
0139 
0140   static auto get(const T& t, const E&) noexcept
0141     -> decltype(t.get_immediate_executor())
0142   {
0143     return t.get_immediate_executor();
0144   }
0145 };
0146 
0147 template <typename T, typename E>
0148 struct associated_immediate_executor_impl<T, E,
0149   enable_if_t<
0150     !has_immediate_executor_type<T>::value
0151   >,
0152   void_t<
0153     typename associator<associated_immediate_executor, T, E>::type
0154   >> : associator<associated_immediate_executor, T, E>
0155 {
0156 };
0157 
0158 } // namespace detail
0159 
0160 /// Traits type used to obtain the immediate executor associated with an object.
0161 /**
0162  * A program may specialise this traits type if the @c T template parameter in
0163  * the specialisation is a user-defined type. The template parameter @c
0164  * Executor shall be a type meeting the Executor requirements.
0165  *
0166  * Specialisations shall meet the following requirements, where @c t is a const
0167  * reference to an object of type @c T, and @c e is an object of type @c
0168  * Executor.
0169  *
0170  * @li Provide a nested typedef @c type that identifies a type meeting the
0171  * Executor requirements.
0172  *
0173  * @li Provide a noexcept static member function named @c get, callable as @c
0174  * get(t) and with return type @c type or a (possibly const) reference to @c
0175  * type.
0176  *
0177  * @li Provide a noexcept static member function named @c get, callable as @c
0178  * get(t,e) and with return type @c type or a (possibly const) reference to @c
0179  * type.
0180  */
0181 template <typename T, typename Executor>
0182 struct associated_immediate_executor
0183 #if !defined(GENERATING_DOCUMENTATION)
0184   : detail::associated_immediate_executor_impl<T, Executor>
0185 #endif // !defined(GENERATING_DOCUMENTATION)
0186 {
0187 #if defined(GENERATING_DOCUMENTATION)
0188   /// If @c T has a nested type @c immediate_executor_type,
0189   // <tt>T::immediate_executor_type</tt>. Otherwise @c Executor.
0190   typedef see_below type;
0191 
0192   /// If @c T has a nested type @c immediate_executor_type, returns
0193   /// <tt>t.get_immediate_executor()</tt>. Otherwise returns
0194   /// <tt>boost::asio::require(ex, boost::asio::execution::blocking.never)</tt>.
0195   static decltype(auto) get(const T& t, const Executor& ex) noexcept;
0196 #endif // defined(GENERATING_DOCUMENTATION)
0197 };
0198 
0199 /// Helper function to obtain an object's associated executor.
0200 /**
0201  * @returns <tt>associated_immediate_executor<T, Executor>::get(t, ex)</tt>
0202  */
0203 template <typename T, typename Executor>
0204 BOOST_ASIO_NODISCARD inline auto get_associated_immediate_executor(
0205     const T& t, const Executor& ex,
0206     constraint_t<
0207       is_executor<Executor>::value || execution::is_executor<Executor>::value
0208     > = 0) noexcept
0209   -> decltype(associated_immediate_executor<T, Executor>::get(t, ex))
0210 {
0211   return associated_immediate_executor<T, Executor>::get(t, ex);
0212 }
0213 
0214 /// Helper function to obtain an object's associated executor.
0215 /**
0216  * @returns <tt>associated_immediate_executor<T, typename
0217  * ExecutionContext::executor_type>::get(t, ctx.get_executor())</tt>
0218  */
0219 template <typename T, typename ExecutionContext>
0220 BOOST_ASIO_NODISCARD inline typename associated_immediate_executor<T,
0221     typename ExecutionContext::executor_type>::type
0222 get_associated_immediate_executor(const T& t, ExecutionContext& ctx,
0223     constraint_t<
0224       is_convertible<ExecutionContext&, execution_context&>::value
0225     > = 0) noexcept
0226 {
0227   return associated_immediate_executor<T,
0228     typename ExecutionContext::executor_type>::get(t, ctx.get_executor());
0229 }
0230 
0231 template <typename T, typename Executor>
0232 using associated_immediate_executor_t =
0233   typename associated_immediate_executor<T, Executor>::type;
0234 
0235 namespace detail {
0236 
0237 template <typename T, typename E, typename = void>
0238 struct associated_immediate_executor_forwarding_base
0239 {
0240 };
0241 
0242 template <typename T, typename E>
0243 struct associated_immediate_executor_forwarding_base<T, E,
0244     enable_if_t<
0245       is_same<
0246         typename associated_immediate_executor<T,
0247           E>::asio_associated_immediate_executor_is_unspecialised,
0248         void
0249       >::value
0250     >>
0251 {
0252   typedef void asio_associated_immediate_executor_is_unspecialised;
0253 };
0254 
0255 } // namespace detail
0256 
0257 /// Specialisation of associated_immediate_executor for
0258 /// @c std::reference_wrapper.
0259 template <typename T, typename Executor>
0260 struct associated_immediate_executor<reference_wrapper<T>, Executor>
0261 #if !defined(GENERATING_DOCUMENTATION)
0262   : detail::associated_immediate_executor_forwarding_base<T, Executor>
0263 #endif // !defined(GENERATING_DOCUMENTATION)
0264 {
0265   /// Forwards @c type to the associator specialisation for the unwrapped type
0266   /// @c T.
0267   typedef typename associated_immediate_executor<T, Executor>::type type;
0268 
0269   /// Forwards the request to get the executor to the associator specialisation
0270   /// for the unwrapped type @c T.
0271   static auto get(reference_wrapper<T> t, const Executor& ex) noexcept
0272     -> decltype(associated_immediate_executor<T, Executor>::get(t.get(), ex))
0273   {
0274     return associated_immediate_executor<T, Executor>::get(t.get(), ex);
0275   }
0276 };
0277 
0278 } // namespace asio
0279 } // namespace boost
0280 
0281 #include <boost/asio/detail/pop_options.hpp>
0282 
0283 #endif // BOOST_ASIO_ASSOCIATED_IMMEDIATE_EXECUTOR_HPP