associated_cancellation_slot.hpp 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221
  1. //
  2. // associated_cancellation_slot.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_ASSOCIATED_CANCELLATION_SLOT_HPP
  11. #define ASIO_ASSOCIATED_CANCELLATION_SLOT_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/associator.hpp"
  17. #include "asio/cancellation_signal.hpp"
  18. #include "asio/detail/functional.hpp"
  19. #include "asio/detail/type_traits.hpp"
  20. #include "asio/detail/push_options.hpp"
  21. namespace asio {
  22. template <typename T, typename CancellationSlot>
  23. struct associated_cancellation_slot;
  24. namespace detail {
  25. template <typename T, typename = void>
  26. struct has_cancellation_slot_type : false_type
  27. {
  28. };
  29. template <typename T>
  30. struct has_cancellation_slot_type<T, void_t<typename T::cancellation_slot_type>>
  31. : true_type
  32. {
  33. };
  34. template <typename T, typename S, typename = void, typename = void>
  35. struct associated_cancellation_slot_impl
  36. {
  37. typedef void asio_associated_cancellation_slot_is_unspecialised;
  38. typedef S type;
  39. static type get(const T&) noexcept
  40. {
  41. return type();
  42. }
  43. static const type& get(const T&, const S& s) noexcept
  44. {
  45. return s;
  46. }
  47. };
  48. template <typename T, typename S>
  49. struct associated_cancellation_slot_impl<T, S,
  50. void_t<typename T::cancellation_slot_type>>
  51. {
  52. typedef typename T::cancellation_slot_type type;
  53. static auto get(const T& t) noexcept
  54. -> decltype(t.get_cancellation_slot())
  55. {
  56. return t.get_cancellation_slot();
  57. }
  58. static auto get(const T& t, const S&) noexcept
  59. -> decltype(t.get_cancellation_slot())
  60. {
  61. return t.get_cancellation_slot();
  62. }
  63. };
  64. template <typename T, typename S>
  65. struct associated_cancellation_slot_impl<T, S,
  66. enable_if_t<
  67. !has_cancellation_slot_type<T>::value
  68. >,
  69. void_t<
  70. typename associator<associated_cancellation_slot, T, S>::type
  71. >> : associator<associated_cancellation_slot, T, S>
  72. {
  73. };
  74. } // namespace detail
  75. /// Traits type used to obtain the cancellation_slot associated with an object.
  76. /**
  77. * A program may specialise this traits type if the @c T template parameter in
  78. * the specialisation is a user-defined type. The template parameter @c
  79. * CancellationSlot shall be a type meeting the CancellationSlot requirements.
  80. *
  81. * Specialisations shall meet the following requirements, where @c t is a const
  82. * reference to an object of type @c T, and @c s is an object of type @c
  83. * CancellationSlot.
  84. *
  85. * @li Provide a nested typedef @c type that identifies a type meeting the
  86. * CancellationSlot requirements.
  87. *
  88. * @li Provide a noexcept static member function named @c get, callable as @c
  89. * get(t) and with return type @c type or a (possibly const) reference to @c
  90. * type.
  91. *
  92. * @li Provide a noexcept static member function named @c get, callable as @c
  93. * get(t,s) and with return type @c type or a (possibly const) reference to @c
  94. * type.
  95. */
  96. template <typename T, typename CancellationSlot = cancellation_slot>
  97. struct associated_cancellation_slot
  98. #if !defined(GENERATING_DOCUMENTATION)
  99. : detail::associated_cancellation_slot_impl<T, CancellationSlot>
  100. #endif // !defined(GENERATING_DOCUMENTATION)
  101. {
  102. #if defined(GENERATING_DOCUMENTATION)
  103. /// If @c T has a nested type @c cancellation_slot_type,
  104. /// <tt>T::cancellation_slot_type</tt>. Otherwise
  105. /// @c CancellationSlot.
  106. typedef see_below type;
  107. /// If @c T has a nested type @c cancellation_slot_type, returns
  108. /// <tt>t.get_cancellation_slot()</tt>. Otherwise returns @c type().
  109. static decltype(auto) get(const T& t) noexcept;
  110. /// If @c T has a nested type @c cancellation_slot_type, returns
  111. /// <tt>t.get_cancellation_slot()</tt>. Otherwise returns @c s.
  112. static decltype(auto) get(const T& t,
  113. const CancellationSlot& s) noexcept;
  114. #endif // defined(GENERATING_DOCUMENTATION)
  115. };
  116. /// Helper function to obtain an object's associated cancellation_slot.
  117. /**
  118. * @returns <tt>associated_cancellation_slot<T>::get(t)</tt>
  119. */
  120. template <typename T>
  121. ASIO_NODISCARD inline typename associated_cancellation_slot<T>::type
  122. get_associated_cancellation_slot(const T& t) noexcept
  123. {
  124. return associated_cancellation_slot<T>::get(t);
  125. }
  126. /// Helper function to obtain an object's associated cancellation_slot.
  127. /**
  128. * @returns <tt>associated_cancellation_slot<T,
  129. * CancellationSlot>::get(t, st)</tt>
  130. */
  131. template <typename T, typename CancellationSlot>
  132. ASIO_NODISCARD inline auto get_associated_cancellation_slot(
  133. const T& t, const CancellationSlot& st) noexcept
  134. -> decltype(associated_cancellation_slot<T, CancellationSlot>::get(t, st))
  135. {
  136. return associated_cancellation_slot<T, CancellationSlot>::get(t, st);
  137. }
  138. template <typename T, typename CancellationSlot = cancellation_slot>
  139. using associated_cancellation_slot_t =
  140. typename associated_cancellation_slot<T, CancellationSlot>::type;
  141. namespace detail {
  142. template <typename T, typename S, typename = void>
  143. struct associated_cancellation_slot_forwarding_base
  144. {
  145. };
  146. template <typename T, typename S>
  147. struct associated_cancellation_slot_forwarding_base<T, S,
  148. enable_if_t<
  149. is_same<
  150. typename associated_cancellation_slot<T,
  151. S>::asio_associated_cancellation_slot_is_unspecialised,
  152. void
  153. >::value
  154. >>
  155. {
  156. typedef void asio_associated_cancellation_slot_is_unspecialised;
  157. };
  158. } // namespace detail
  159. /// Specialisation of associated_cancellation_slot for @c
  160. /// std::reference_wrapper.
  161. template <typename T, typename CancellationSlot>
  162. struct associated_cancellation_slot<reference_wrapper<T>, CancellationSlot>
  163. #if !defined(GENERATING_DOCUMENTATION)
  164. : detail::associated_cancellation_slot_forwarding_base<T, CancellationSlot>
  165. #endif // !defined(GENERATING_DOCUMENTATION)
  166. {
  167. /// Forwards @c type to the associator specialisation for the unwrapped type
  168. /// @c T.
  169. typedef typename associated_cancellation_slot<T, CancellationSlot>::type type;
  170. /// Forwards the request to get the cancellation slot to the associator
  171. /// specialisation for the unwrapped type @c T.
  172. static type get(reference_wrapper<T> t) noexcept
  173. {
  174. return associated_cancellation_slot<T, CancellationSlot>::get(t.get());
  175. }
  176. /// Forwards the request to get the cancellation slot to the associator
  177. /// specialisation for the unwrapped type @c T.
  178. static auto get(reference_wrapper<T> t, const CancellationSlot& s) noexcept
  179. -> decltype(
  180. associated_cancellation_slot<T, CancellationSlot>::get(t.get(), s))
  181. {
  182. return associated_cancellation_slot<T, CancellationSlot>::get(t.get(), s);
  183. }
  184. };
  185. } // namespace asio
  186. #include "asio/detail/pop_options.hpp"
  187. #endif // ASIO_ASSOCIATED_CANCELLATION_SLOT_HPP