Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-30 09:33:38

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