use_promise.hpp 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. //
  2. // experimental/use_promise.hpp
  3. // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  4. //
  5. // Copyright (c) 2021-2023 Klemens D. Morgenstern
  6. // (klemens dot morgenstern at gmx dot net)
  7. //
  8. // Distributed under the Boost Software License, Version 1.0. (See accompanying
  9. // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  10. //
  11. #ifndef ASIO_EXPERIMENTAL_USE_PROMISE_HPP
  12. #define ASIO_EXPERIMENTAL_USE_PROMISE_HPP
  13. #if defined(_MSC_VER) && (_MSC_VER >= 1200)
  14. # pragma once
  15. #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
  16. #include "asio/detail/config.hpp"
  17. #include <memory>
  18. #include "asio/detail/type_traits.hpp"
  19. #include "asio/detail/push_options.hpp"
  20. namespace asio {
  21. namespace experimental {
  22. template <typename Allocator = std::allocator<void>>
  23. struct use_promise_t
  24. {
  25. /// The allocator type. The allocator is used when constructing the
  26. /// @c promise object for a given asynchronous operation.
  27. typedef Allocator allocator_type;
  28. /// Construct using default-constructed allocator.
  29. constexpr use_promise_t()
  30. {
  31. }
  32. /// Construct using specified allocator.
  33. explicit use_promise_t(const Allocator& allocator)
  34. : allocator_(allocator)
  35. {
  36. }
  37. /// Obtain allocator.
  38. allocator_type get_allocator() const noexcept
  39. {
  40. return allocator_;
  41. }
  42. /// Adapts an executor to add the @c use_promise_t completion token as the
  43. /// default.
  44. template <typename InnerExecutor>
  45. struct executor_with_default : InnerExecutor
  46. {
  47. /// Specify @c use_promise_t as the default completion token type.
  48. typedef use_promise_t<Allocator> default_completion_token_type;
  49. /// Construct the adapted executor from the inner executor type.
  50. executor_with_default(const InnerExecutor& ex) noexcept
  51. : InnerExecutor(ex)
  52. {
  53. }
  54. /// Convert the specified executor to the inner executor type, then use
  55. /// that to construct the adapted executor.
  56. template <typename OtherExecutor>
  57. executor_with_default(const OtherExecutor& ex,
  58. constraint_t<
  59. is_convertible<OtherExecutor, InnerExecutor>::value
  60. > = 0) noexcept
  61. : InnerExecutor(ex)
  62. {
  63. }
  64. };
  65. /// Function helper to adapt an I/O object to use @c use_promise_t as its
  66. /// default completion token type.
  67. template <typename T>
  68. static typename decay_t<T>::template rebind_executor<
  69. executor_with_default<typename decay_t<T>::executor_type>
  70. >::other
  71. as_default_on(T&& object)
  72. {
  73. return typename decay_t<T>::template rebind_executor<
  74. executor_with_default<typename decay_t<T>::executor_type>
  75. >::other(static_cast<T&&>(object));
  76. }
  77. /// Specify an alternate allocator.
  78. template <typename OtherAllocator>
  79. use_promise_t<OtherAllocator> rebind(const OtherAllocator& allocator) const
  80. {
  81. return use_promise_t<OtherAllocator>(allocator);
  82. }
  83. private:
  84. Allocator allocator_;
  85. };
  86. constexpr use_promise_t<> use_promise;
  87. } // namespace experimental
  88. } // namespace asio
  89. #include "asio/detail/pop_options.hpp"
  90. #include "asio/experimental/impl/use_promise.hpp"
  91. #endif // ASIO_EXPERIMENTAL_USE_CORO_HPP