Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-12-15 09:44:10

0001 //
0002 // associated_executor.hpp
0003 // ~~~~~~~~~~~~~~~~~~~~~~~
0004 //
0005 // Copyright (c) 2003-2025 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_EXECUTOR_HPP
0012 #define BOOST_ASIO_ASSOCIATED_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/executor.hpp>
0023 #include <boost/asio/is_executor.hpp>
0024 #include <boost/asio/system_executor.hpp>
0025 
0026 #include <boost/asio/detail/push_options.hpp>
0027 
0028 namespace boost {
0029 namespace asio {
0030 
0031 template <typename T, typename Executor>
0032 struct associated_executor;
0033 
0034 namespace detail {
0035 
0036 template <typename T, typename = void>
0037 struct has_executor_type : false_type
0038 {
0039 };
0040 
0041 template <typename T>
0042 struct has_executor_type<T, void_t<typename T::executor_type>>
0043     : true_type
0044 {
0045 };
0046 
0047 template <typename T, typename E, typename = void, typename = void>
0048 struct associated_executor_impl
0049 {
0050   typedef void asio_associated_executor_is_unspecialised;
0051 
0052   typedef E type;
0053 
0054   static type get(const T&) noexcept
0055   {
0056     return type();
0057   }
0058 
0059   static const type& get(const T&, const E& e) noexcept
0060   {
0061     return e;
0062   }
0063 };
0064 
0065 template <typename T, typename E>
0066 struct associated_executor_impl<T, E, void_t<typename T::executor_type>>
0067 {
0068   typedef typename T::executor_type type;
0069 
0070   static auto get(const T& t) noexcept
0071     -> decltype(t.get_executor())
0072   {
0073     return t.get_executor();
0074   }
0075 
0076   static auto get(const T& t, const E&) noexcept
0077     -> decltype(t.get_executor())
0078   {
0079     return t.get_executor();
0080   }
0081 };
0082 
0083 template <typename T, typename E>
0084 struct associated_executor_impl<T, E,
0085   enable_if_t<
0086     !has_executor_type<T>::value
0087   >,
0088   void_t<
0089     typename associator<associated_executor, T, E>::type
0090   >> : associator<associated_executor, T, E>
0091 {
0092 };
0093 
0094 } // namespace detail
0095 
0096 /// Traits type used to obtain the executor associated with an object.
0097 /**
0098  * A program may specialise this traits type if the @c T template parameter in
0099  * the specialisation is a user-defined type. The template parameter @c
0100  * Executor shall be a type meeting the Executor requirements.
0101  *
0102  * Specialisations shall meet the following requirements, where @c t is a const
0103  * reference to an object of type @c T, and @c e is an object of type @c
0104  * Executor.
0105  *
0106  * @li Provide a nested typedef @c type that identifies a type meeting the
0107  * Executor requirements.
0108  *
0109  * @li Provide a noexcept static member function named @c get, callable as @c
0110  * get(t) and with return type @c type or a (possibly const) reference to @c
0111  * type.
0112  *
0113  * @li Provide a noexcept static member function named @c get, callable as @c
0114  * get(t,e) and with return type @c type or a (possibly const) reference to @c
0115  * type.
0116  */
0117 template <typename T, typename Executor = system_executor>
0118 struct associated_executor
0119 #if !defined(GENERATING_DOCUMENTATION)
0120   : detail::associated_executor_impl<T, Executor>
0121 #endif // !defined(GENERATING_DOCUMENTATION)
0122 {
0123 #if defined(GENERATING_DOCUMENTATION)
0124   /// If @c T has a nested type @c executor_type, <tt>T::executor_type</tt>.
0125   /// Otherwise @c Executor.
0126   typedef see_below type;
0127 
0128   /// If @c T has a nested type @c executor_type, returns
0129   /// <tt>t.get_executor()</tt>. Otherwise returns @c type().
0130   static decltype(auto) get(const T& t) noexcept;
0131 
0132   /// If @c T has a nested type @c executor_type, returns
0133   /// <tt>t.get_executor()</tt>. Otherwise returns @c ex.
0134   static decltype(auto) get(const T& t, const Executor& ex) noexcept;
0135 #endif // defined(GENERATING_DOCUMENTATION)
0136 };
0137 
0138 /// Helper function to obtain an object's associated executor.
0139 /**
0140  * @returns <tt>associated_executor<T>::get(t)</tt>
0141  */
0142 template <typename T>
0143 BOOST_ASIO_NODISCARD inline typename associated_executor<T>::type
0144 get_associated_executor(const T& t) noexcept
0145 {
0146   return associated_executor<T>::get(t);
0147 }
0148 
0149 /// Helper function to obtain an object's associated executor.
0150 /**
0151  * @returns <tt>associated_executor<T, Executor>::get(t, ex)</tt>
0152  */
0153 template <typename T, typename Executor>
0154 BOOST_ASIO_NODISCARD inline auto get_associated_executor(
0155     const T& t, const Executor& ex,
0156     constraint_t<
0157       is_executor<Executor>::value || execution::is_executor<Executor>::value
0158     > = 0) noexcept
0159   -> decltype(associated_executor<T, Executor>::get(t, ex))
0160 {
0161   return associated_executor<T, Executor>::get(t, ex);
0162 }
0163 
0164 /// Helper function to obtain an object's associated executor.
0165 /**
0166  * @returns <tt>associated_executor<T, typename
0167  * ExecutionContext::executor_type>::get(t, ctx.get_executor())</tt>
0168  */
0169 template <typename T, typename ExecutionContext>
0170 BOOST_ASIO_NODISCARD inline typename associated_executor<T,
0171     typename ExecutionContext::executor_type>::type
0172 get_associated_executor(const T& t, ExecutionContext& ctx,
0173     constraint_t<is_convertible<ExecutionContext&,
0174       execution_context&>::value> = 0) noexcept
0175 {
0176   return associated_executor<T,
0177     typename ExecutionContext::executor_type>::get(t, ctx.get_executor());
0178 }
0179 
0180 template <typename T, typename Executor = system_executor>
0181 using associated_executor_t = typename associated_executor<T, Executor>::type;
0182 
0183 namespace detail {
0184 
0185 template <typename T, typename E, typename = void>
0186 struct associated_executor_forwarding_base
0187 {
0188 };
0189 
0190 template <typename T, typename E>
0191 struct associated_executor_forwarding_base<T, E,
0192     enable_if_t<
0193       is_same<
0194         typename associated_executor<T,
0195           E>::asio_associated_executor_is_unspecialised,
0196         void
0197       >::value
0198     >>
0199 {
0200   typedef void asio_associated_executor_is_unspecialised;
0201 };
0202 
0203 } // namespace detail
0204 
0205 /// Specialisation of associated_executor for @c std::reference_wrapper.
0206 template <typename T, typename Executor>
0207 struct associated_executor<reference_wrapper<T>, Executor>
0208 #if !defined(GENERATING_DOCUMENTATION)
0209   : detail::associated_executor_forwarding_base<T, Executor>
0210 #endif // !defined(GENERATING_DOCUMENTATION)
0211 {
0212   /// Forwards @c type to the associator specialisation for the unwrapped type
0213   /// @c T.
0214   typedef typename associated_executor<T, Executor>::type type;
0215 
0216   /// Forwards the request to get the executor to the associator specialisation
0217   /// for the unwrapped type @c T.
0218   static type get(reference_wrapper<T> t) noexcept
0219   {
0220     return associated_executor<T, Executor>::get(t.get());
0221   }
0222 
0223   /// Forwards the request to get the executor to the associator specialisation
0224   /// for the unwrapped type @c T.
0225   static auto get(reference_wrapper<T> t, const Executor& ex) noexcept
0226     -> decltype(associated_executor<T, Executor>::get(t.get(), ex))
0227   {
0228     return associated_executor<T, Executor>::get(t.get(), ex);
0229   }
0230 };
0231 
0232 } // namespace asio
0233 } // namespace boost
0234 
0235 #include <boost/asio/detail/pop_options.hpp>
0236 
0237 #endif // BOOST_ASIO_ASSOCIATED_EXECUTOR_HPP