associated_cancellation_slot.hpp 6.8 KB

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