defer.hpp 2.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. //
  2. // impl/defer.hpp
  3. // ~~~~~~~~~~~~~~
  4. //
  5. // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
  6. //
  7. // Distributed under the Boost Software License, Version 1.0. (See accompanying
  8. // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  9. //
  10. #ifndef BOOST_ASIO_IMPL_DEFER_HPP
  11. #define BOOST_ASIO_IMPL_DEFER_HPP
  12. #if defined(_MSC_VER) && (_MSC_VER >= 1200)
  13. # pragma once
  14. #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
  15. #include <boost/asio/detail/config.hpp>
  16. #include <boost/asio/associated_allocator.hpp>
  17. #include <boost/asio/associated_executor.hpp>
  18. #include <boost/asio/detail/work_dispatcher.hpp>
  19. #include <boost/asio/detail/push_options.hpp>
  20. namespace boost {
  21. namespace asio {
  22. namespace detail {
  23. struct initiate_defer
  24. {
  25. template <typename CompletionHandler>
  26. void operator()(BOOST_ASIO_MOVE_ARG(CompletionHandler) handler) const
  27. {
  28. typedef typename decay<CompletionHandler>::type DecayedHandler;
  29. typename associated_executor<DecayedHandler>::type ex(
  30. (get_associated_executor)(handler));
  31. typename associated_allocator<DecayedHandler>::type alloc(
  32. (get_associated_allocator)(handler));
  33. ex.defer(BOOST_ASIO_MOVE_CAST(CompletionHandler)(handler), alloc);
  34. }
  35. template <typename CompletionHandler, typename Executor>
  36. void operator()(BOOST_ASIO_MOVE_ARG(CompletionHandler) handler,
  37. BOOST_ASIO_MOVE_ARG(Executor) ex) const
  38. {
  39. typedef typename decay<CompletionHandler>::type DecayedHandler;
  40. typename associated_allocator<DecayedHandler>::type alloc(
  41. (get_associated_allocator)(handler));
  42. ex.defer(detail::work_dispatcher<DecayedHandler>(
  43. BOOST_ASIO_MOVE_CAST(CompletionHandler)(handler)), alloc);
  44. }
  45. };
  46. } // namespace detail
  47. template <typename CompletionToken>
  48. BOOST_ASIO_INITFN_RESULT_TYPE(CompletionToken, void()) defer(
  49. BOOST_ASIO_MOVE_ARG(CompletionToken) token)
  50. {
  51. return async_initiate<CompletionToken, void()>(
  52. detail::initiate_defer(), token);
  53. }
  54. template <typename Executor, typename CompletionToken>
  55. BOOST_ASIO_INITFN_RESULT_TYPE(CompletionToken, void()) defer(
  56. const Executor& ex, BOOST_ASIO_MOVE_ARG(CompletionToken) token,
  57. typename enable_if<is_executor<Executor>::value>::type*)
  58. {
  59. return async_initiate<CompletionToken, void()>(
  60. detail::initiate_defer(), token, ex);
  61. }
  62. template <typename ExecutionContext, typename CompletionToken>
  63. inline BOOST_ASIO_INITFN_RESULT_TYPE(CompletionToken, void()) defer(
  64. ExecutionContext& ctx, BOOST_ASIO_MOVE_ARG(CompletionToken) token,
  65. typename enable_if<is_convertible<
  66. ExecutionContext&, execution_context&>::value>::type*)
  67. {
  68. return (defer)(ctx.get_executor(),
  69. BOOST_ASIO_MOVE_CAST(CompletionToken)(token));
  70. }
  71. } // namespace asio
  72. } // namespace boost
  73. #include <boost/asio/detail/pop_options.hpp>
  74. #endif // BOOST_ASIO_IMPL_DEFER_HPP