associated_cancellation_slot.hpp 7.6 KB

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