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

source code of boost/libs/asio/include/boost/asio/associated_cancellation_slot.hpp