use_future.hpp 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  1. //
  2. // use_future.hpp
  3. // ~~~~~~~~~~~~~~
  4. //
  5. // Copyright (c) 2003-2023 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_USE_FUTURE_HPP
  11. #define ASIO_USE_FUTURE_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/future.hpp"
  17. #if defined(ASIO_HAS_STD_FUTURE_CLASS) \
  18. || defined(GENERATING_DOCUMENTATION)
  19. #include <memory>
  20. #include "asio/detail/type_traits.hpp"
  21. #include "asio/detail/push_options.hpp"
  22. namespace asio {
  23. namespace detail {
  24. template <typename Function, typename Allocator>
  25. class packaged_token;
  26. template <typename Function, typename Allocator, typename Result>
  27. class packaged_handler;
  28. } // namespace detail
  29. /// A @ref completion_token type that causes an asynchronous operation to return
  30. /// a future.
  31. /**
  32. * The use_future_t class is a completion token type that is used to indicate
  33. * that an asynchronous operation should return a std::future object. A
  34. * use_future_t object may be passed as a completion token to an asynchronous
  35. * operation, typically using the special value @c asio::use_future. For
  36. * example:
  37. *
  38. * @code std::future<std::size_t> my_future
  39. * = my_socket.async_read_some(my_buffer, asio::use_future); @endcode
  40. *
  41. * The initiating function (async_read_some in the above example) returns a
  42. * future that will receive the result of the operation. If the operation
  43. * completes with an error_code indicating failure, it is converted into a
  44. * system_error and passed back to the caller via the future.
  45. */
  46. template <typename Allocator = std::allocator<void>>
  47. class use_future_t
  48. {
  49. public:
  50. /// The allocator type. The allocator is used when constructing the
  51. /// @c std::promise object for a given asynchronous operation.
  52. typedef Allocator allocator_type;
  53. /// Construct using default-constructed allocator.
  54. constexpr use_future_t()
  55. {
  56. }
  57. /// Construct using specified allocator.
  58. explicit use_future_t(const Allocator& allocator)
  59. : allocator_(allocator)
  60. {
  61. }
  62. #if !defined(ASIO_NO_DEPRECATED)
  63. /// (Deprecated: Use rebind().) Specify an alternate allocator.
  64. template <typename OtherAllocator>
  65. use_future_t<OtherAllocator> operator[](const OtherAllocator& allocator) const
  66. {
  67. return use_future_t<OtherAllocator>(allocator);
  68. }
  69. #endif // !defined(ASIO_NO_DEPRECATED)
  70. /// Specify an alternate allocator.
  71. template <typename OtherAllocator>
  72. use_future_t<OtherAllocator> rebind(const OtherAllocator& allocator) const
  73. {
  74. return use_future_t<OtherAllocator>(allocator);
  75. }
  76. /// Obtain allocator.
  77. allocator_type get_allocator() const
  78. {
  79. return allocator_;
  80. }
  81. /// Wrap a function object in a packaged task.
  82. /**
  83. * The @c package function is used to adapt a function object as a packaged
  84. * task. When this adapter is passed as a completion token to an asynchronous
  85. * operation, the result of the function object is retuned via a std::future.
  86. *
  87. * @par Example
  88. *
  89. * @code std::future<std::size_t> fut =
  90. * my_socket.async_read_some(buffer,
  91. * use_future([](asio::error_code ec, std::size_t n)
  92. * {
  93. * return ec ? 0 : n;
  94. * }));
  95. * ...
  96. * std::size_t n = fut.get(); @endcode
  97. */
  98. template <typename Function>
  99. #if defined(GENERATING_DOCUMENTATION)
  100. unspecified
  101. #else // defined(GENERATING_DOCUMENTATION)
  102. detail::packaged_token<decay_t<Function>, Allocator>
  103. #endif // defined(GENERATING_DOCUMENTATION)
  104. operator()(Function&& f) const;
  105. private:
  106. // Helper type to ensure that use_future can be constexpr default-constructed
  107. // even when std::allocator<void> can't be.
  108. struct std_allocator_void
  109. {
  110. constexpr std_allocator_void()
  111. {
  112. }
  113. operator std::allocator<void>() const
  114. {
  115. return std::allocator<void>();
  116. }
  117. };
  118. conditional_t<
  119. is_same<std::allocator<void>, Allocator>::value,
  120. std_allocator_void, Allocator> allocator_;
  121. };
  122. /// A @ref completion_token object that causes an asynchronous operation to
  123. /// return a future.
  124. /**
  125. * See the documentation for asio::use_future_t for a usage example.
  126. */
  127. constexpr use_future_t<> use_future;
  128. } // namespace asio
  129. #include "asio/detail/pop_options.hpp"
  130. #include "asio/impl/use_future.hpp"
  131. #endif // defined(ASIO_HAS_STD_FUTURE_CLASS)
  132. // || defined(GENERATING_DOCUMENTATION)
  133. #endif // ASIO_USE_FUTURE_HPP