Back to home page

EIC code displayed by LXR

 
 

    


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

0001 //
0002 // detail/initiate_defer.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_DETAIL_INITIATE_DEFER_HPP
0012 #define BOOST_ASIO_DETAIL_INITIATE_DEFER_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/associated_allocator.hpp>
0020 #include <boost/asio/associated_executor.hpp>
0021 #include <boost/asio/detail/work_dispatcher.hpp>
0022 #include <boost/asio/execution/allocator.hpp>
0023 #include <boost/asio/execution/blocking.hpp>
0024 #include <boost/asio/execution/relationship.hpp>
0025 #include <boost/asio/prefer.hpp>
0026 #include <boost/asio/require.hpp>
0027 
0028 #include <boost/asio/detail/push_options.hpp>
0029 
0030 namespace boost {
0031 namespace asio {
0032 namespace detail {
0033 
0034 class initiate_defer
0035 {
0036 public:
0037   template <typename CompletionHandler>
0038   void operator()(CompletionHandler&& handler,
0039       enable_if_t<
0040         execution::is_executor<
0041           associated_executor_t<decay_t<CompletionHandler>>
0042         >::value
0043       >* = 0) const
0044   {
0045     associated_executor_t<decay_t<CompletionHandler>> ex(
0046         (get_associated_executor)(handler));
0047 
0048     associated_allocator_t<decay_t<CompletionHandler>> alloc(
0049         (get_associated_allocator)(handler));
0050 
0051     boost::asio::prefer(
0052         boost::asio::require(ex, execution::blocking.never),
0053         execution::relationship.continuation,
0054         execution::allocator(alloc)
0055       ).execute(
0056         boost::asio::detail::bind_handler(
0057           static_cast<CompletionHandler&&>(handler)));
0058   }
0059 
0060   template <typename CompletionHandler>
0061   void operator()(CompletionHandler&& handler,
0062       enable_if_t<
0063         !execution::is_executor<
0064           associated_executor_t<decay_t<CompletionHandler>>
0065         >::value
0066       >* = 0) const
0067   {
0068     associated_executor_t<decay_t<CompletionHandler>> ex(
0069         (get_associated_executor)(handler));
0070 
0071     associated_allocator_t<decay_t<CompletionHandler>> alloc(
0072         (get_associated_allocator)(handler));
0073 
0074     ex.defer(boost::asio::detail::bind_handler(
0075           static_cast<CompletionHandler&&>(handler)), alloc);
0076   }
0077 };
0078 
0079 template <typename Executor>
0080 class initiate_defer_with_executor
0081 {
0082 public:
0083   typedef Executor executor_type;
0084 
0085   explicit initiate_defer_with_executor(const Executor& ex)
0086     : ex_(ex)
0087   {
0088   }
0089 
0090   executor_type get_executor() const noexcept
0091   {
0092     return ex_;
0093   }
0094 
0095   template <typename CompletionHandler>
0096   void operator()(CompletionHandler&& handler,
0097       enable_if_t<
0098         execution::is_executor<
0099           conditional_t<true, executor_type, CompletionHandler>
0100         >::value
0101       >* = 0,
0102       enable_if_t<
0103         !detail::is_work_dispatcher_required<
0104           decay_t<CompletionHandler>,
0105           Executor
0106         >::value
0107       >* = 0) const
0108   {
0109     associated_allocator_t<decay_t<CompletionHandler>> alloc(
0110         (get_associated_allocator)(handler));
0111 
0112     boost::asio::prefer(
0113         boost::asio::require(ex_, execution::blocking.never),
0114         execution::relationship.continuation,
0115         execution::allocator(alloc)
0116       ).execute(
0117         boost::asio::detail::bind_handler(
0118           static_cast<CompletionHandler&&>(handler)));
0119   }
0120 
0121   template <typename CompletionHandler>
0122   void operator()(CompletionHandler&& handler,
0123       enable_if_t<
0124         execution::is_executor<
0125           conditional_t<true, executor_type, CompletionHandler>
0126         >::value
0127       >* = 0,
0128       enable_if_t<
0129         detail::is_work_dispatcher_required<
0130           decay_t<CompletionHandler>,
0131           Executor
0132         >::value
0133       >* = 0) const
0134   {
0135     typedef decay_t<CompletionHandler> handler_t;
0136 
0137     typedef associated_executor_t<handler_t, Executor> handler_ex_t;
0138     handler_ex_t handler_ex((get_associated_executor)(handler, ex_));
0139 
0140     associated_allocator_t<handler_t> alloc(
0141         (get_associated_allocator)(handler));
0142 
0143     boost::asio::prefer(
0144         boost::asio::require(ex_, execution::blocking.never),
0145         execution::relationship.continuation,
0146         execution::allocator(alloc)
0147       ).execute(
0148         detail::work_dispatcher<handler_t, handler_ex_t>(
0149           static_cast<CompletionHandler&&>(handler), handler_ex));
0150   }
0151 
0152   template <typename CompletionHandler>
0153   void operator()(CompletionHandler&& handler,
0154       enable_if_t<
0155         !execution::is_executor<
0156           conditional_t<true, executor_type, CompletionHandler>
0157         >::value
0158       >* = 0,
0159       enable_if_t<
0160         !detail::is_work_dispatcher_required<
0161           decay_t<CompletionHandler>,
0162           Executor
0163         >::value
0164       >* = 0) const
0165   {
0166     associated_allocator_t<decay_t<CompletionHandler>> alloc(
0167         (get_associated_allocator)(handler));
0168 
0169     ex_.defer(boost::asio::detail::bind_handler(
0170           static_cast<CompletionHandler&&>(handler)), alloc);
0171   }
0172 
0173   template <typename CompletionHandler>
0174   void operator()(CompletionHandler&& handler,
0175       enable_if_t<
0176         !execution::is_executor<
0177           conditional_t<true, executor_type, CompletionHandler>
0178         >::value
0179       >* = 0,
0180       enable_if_t<
0181         detail::is_work_dispatcher_required<
0182           decay_t<CompletionHandler>,
0183           Executor
0184         >::value
0185       >* = 0) const
0186   {
0187     typedef decay_t<CompletionHandler> handler_t;
0188 
0189     typedef associated_executor_t<handler_t, Executor> handler_ex_t;
0190     handler_ex_t handler_ex((get_associated_executor)(handler, ex_));
0191 
0192     associated_allocator_t<handler_t> alloc(
0193         (get_associated_allocator)(handler));
0194 
0195     ex_.defer(detail::work_dispatcher<handler_t, handler_ex_t>(
0196           static_cast<CompletionHandler&&>(handler), handler_ex), alloc);
0197   }
0198 
0199 private:
0200   Executor ex_;
0201 };
0202 
0203 } // namespace detail
0204 } // namespace asio
0205 } // namespace boost
0206 
0207 #include <boost/asio/detail/pop_options.hpp>
0208 
0209 #endif // BOOST_ASIO_DETAIL_INITIATE_DEFER_HPP