as_operation.hpp 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. //
  2. // execution/detail/as_operation.hpp
  3. // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  4. //
  5. // Copyright (c) 2003-2022 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 ASIO_EXECUTION_DETAIL_AS_OPERATION_HPP
  11. #define ASIO_EXECUTION_DETAIL_AS_OPERATION_HPP
  12. #if defined(_MSC_VER) && (_MSC_VER >= 1200)
  13. # pragma once
  14. #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
  15. #include "asio/detail/config.hpp"
  16. #include "asio/detail/memory.hpp"
  17. #include "asio/detail/type_traits.hpp"
  18. #include "asio/execution/detail/as_invocable.hpp"
  19. #include "asio/execution/execute.hpp"
  20. #include "asio/execution/set_error.hpp"
  21. #include "asio/traits/start_member.hpp"
  22. #include "asio/detail/push_options.hpp"
  23. namespace asio {
  24. namespace execution {
  25. namespace detail {
  26. template <typename Executor, typename Receiver>
  27. struct as_operation
  28. {
  29. typename remove_cvref<Executor>::type ex_;
  30. typename remove_cvref<Receiver>::type receiver_;
  31. #if !defined(ASIO_HAS_MOVE)
  32. asio::detail::shared_ptr<asio::detail::atomic_count> ref_count_;
  33. #endif // !defined(ASIO_HAS_MOVE)
  34. template <typename E, typename R>
  35. explicit as_operation(ASIO_MOVE_ARG(E) e, ASIO_MOVE_ARG(R) r)
  36. : ex_(ASIO_MOVE_CAST(E)(e)),
  37. receiver_(ASIO_MOVE_CAST(R)(r))
  38. #if !defined(ASIO_HAS_MOVE)
  39. , ref_count_(new asio::detail::atomic_count(1))
  40. #endif // !defined(ASIO_HAS_MOVE)
  41. {
  42. }
  43. void start() ASIO_NOEXCEPT
  44. {
  45. #if !defined(ASIO_NO_EXCEPTIONS)
  46. try
  47. {
  48. #endif // !defined(ASIO_NO_EXCEPTIONS)
  49. execution::execute(
  50. ASIO_MOVE_CAST(typename remove_cvref<Executor>::type)(ex_),
  51. as_invocable<typename remove_cvref<Receiver>::type,
  52. Executor>(receiver_
  53. #if !defined(ASIO_HAS_MOVE)
  54. , ref_count_
  55. #endif // !defined(ASIO_HAS_MOVE)
  56. ));
  57. #if !defined(ASIO_NO_EXCEPTIONS)
  58. }
  59. catch (...)
  60. {
  61. #if defined(ASIO_HAS_STD_EXCEPTION_PTR)
  62. execution::set_error(
  63. ASIO_MOVE_OR_LVALUE(
  64. typename remove_cvref<Receiver>::type)(
  65. receiver_),
  66. std::current_exception());
  67. #else // defined(ASIO_HAS_STD_EXCEPTION_PTR)
  68. std::terminate();
  69. #endif // defined(ASIO_HAS_STD_EXCEPTION_PTR)
  70. }
  71. #endif // !defined(ASIO_NO_EXCEPTIONS)
  72. }
  73. };
  74. } // namespace detail
  75. } // namespace execution
  76. namespace traits {
  77. #if !defined(ASIO_HAS_DEDUCED_START_MEMBER_TRAIT)
  78. template <typename Executor, typename Receiver>
  79. struct start_member<
  80. asio::execution::detail::as_operation<Executor, Receiver> >
  81. {
  82. ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
  83. ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);
  84. typedef void result_type;
  85. };
  86. #endif // !defined(ASIO_HAS_DEDUCED_START_MEMBER_TRAIT)
  87. } // namespace traits
  88. } // namespace asio
  89. #include "asio/detail/pop_options.hpp"
  90. #endif // ASIO_EXECUTION_DETAIL_AS_OPERATION_HPP