]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/boost/asio/execution/bulk_execute.hpp
update ceph source to reef 18.1.2
[ceph.git] / ceph / src / boost / boost / asio / execution / bulk_execute.hpp
1 //
2 // execution/bulk_execute.hpp
3 // ~~~~~~~~~~~~~~~~~~~~~~~~~~
4 //
5 // Copyright (c) 2003-2022 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_EXECUTION_BULK_EXECUTE_HPP
12 #define BOOST_ASIO_EXECUTION_BULK_EXECUTE_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/detail/type_traits.hpp>
20 #include <boost/asio/execution/bulk_guarantee.hpp>
21 #include <boost/asio/execution/detail/bulk_sender.hpp>
22 #include <boost/asio/execution/executor.hpp>
23 #include <boost/asio/execution/sender.hpp>
24 #include <boost/asio/traits/bulk_execute_member.hpp>
25 #include <boost/asio/traits/bulk_execute_free.hpp>
26
27 #include <boost/asio/detail/push_options.hpp>
28
29 #if defined(GENERATING_DOCUMENTATION)
30
31 namespace boost {
32 namespace asio {
33 namespace execution {
34
35 /// A customisation point that creates a bulk sender.
36 /**
37 * The name <tt>execution::bulk_execute</tt> denotes a customisation point
38 * object. If <tt>is_convertible_v<N, size_t></tt> is true, then the expression
39 * <tt>execution::bulk_execute(S, F, N)</tt> for some subexpressions
40 * <tt>S</tt>, <tt>F</tt>, and <tt>N</tt> is expression-equivalent to:
41 *
42 * @li <tt>S.bulk_execute(F, N)</tt>, if that expression is valid. If the
43 * function selected does not execute <tt>N</tt> invocations of the function
44 * object <tt>F</tt> on the executor <tt>S</tt> in bulk with forward progress
45 * guarantee <tt>boost::asio::query(S, execution::bulk_guarantee)</tt>, and
46 * the result of that function does not model <tt>sender<void></tt>, the
47 * program is ill-formed with no diagnostic required.
48 *
49 * @li Otherwise, <tt>bulk_execute(S, F, N)</tt>, if that expression is valid,
50 * with overload resolution performed in a context that includes the
51 * declaration <tt>void bulk_execute();</tt> and that does not include a
52 * declaration of <tt>execution::bulk_execute</tt>. If the function selected
53 * by overload resolution does not execute <tt>N</tt> invocations of the
54 * function object <tt>F</tt> on the executor <tt>S</tt> in bulk with forward
55 * progress guarantee <tt>boost::asio::query(E,
56 * execution::bulk_guarantee)</tt>, and the result of that function does not
57 * model <tt>sender<void></tt>, the program is ill-formed with no diagnostic
58 * required.
59 *
60 * @li Otherwise, if the types <tt>F</tt> and
61 * <tt>executor_index_t<remove_cvref_t<S>></tt> model <tt>invocable</tt> and
62 * if <tt>boost::asio::query(S, execution::bulk_guarantee)</tt> equals
63 * <tt>execution::bulk_guarantee.unsequenced</tt>, then
64 *
65 * - Evaluates <tt>DECAY_COPY(std::forward<decltype(F)>(F))</tt> on the
66 * calling thread to create a function object <tt>cf</tt>. [Note:
67 * Additional copies of <tt>cf</tt> may subsequently be created. --end
68 * note.]
69 *
70 * - For each value of <tt>i</tt> in <tt>N</tt>, <tt>cf(i)</tt> (or copy of
71 * <tt>cf</tt>)) will be invoked at most once by an execution agent that is
72 * unique for each value of <tt>i</tt>.
73 *
74 * - May block pending completion of one or more invocations of <tt>cf</tt>.
75 *
76 * - Synchronizes with (C++Std [intro.multithread]) the invocations of
77 * <tt>cf</tt>.
78 *
79 * @li Otherwise, <tt>execution::bulk_execute(S, F, N)</tt> is ill-formed.
80 */
81 inline constexpr unspecified bulk_execute = unspecified;
82
83 /// A type trait that determines whether a @c bulk_execute expression is
84 /// well-formed.
85 /**
86 * Class template @c can_bulk_execute is a trait that is derived from @c
87 * true_type if the expression <tt>execution::bulk_execute(std::declval<S>(),
88 * std::declval<F>(), std::declval<N>)</tt> is well formed; otherwise @c
89 * false_type.
90 */
91 template <typename S, typename F, typename N>
92 struct can_bulk_execute :
93 integral_constant<bool, automatically_determined>
94 {
95 };
96
97 } // namespace execution
98 } // namespace asio
99 } // namespace boost
100
101 #else // defined(GENERATING_DOCUMENTATION)
102
103 namespace boost_asio_execution_bulk_execute_fn {
104
105 using boost::asio::declval;
106 using boost::asio::enable_if;
107 using boost::asio::execution::bulk_guarantee_t;
108 using boost::asio::execution::detail::bulk_sender;
109 using boost::asio::execution::executor_index;
110 using boost::asio::execution::is_sender;
111 using boost::asio::is_convertible;
112 using boost::asio::is_same;
113 using boost::asio::remove_cvref;
114 using boost::asio::result_of;
115 using boost::asio::traits::bulk_execute_free;
116 using boost::asio::traits::bulk_execute_member;
117 using boost::asio::traits::static_require;
118
119 void bulk_execute();
120
121 enum overload_type
122 {
123 call_member,
124 call_free,
125 adapter,
126 ill_formed
127 };
128
129 template <typename S, typename Args, typename = void, typename = void,
130 typename = void, typename = void, typename = void, typename = void>
131 struct call_traits
132 {
133 BOOST_ASIO_STATIC_CONSTEXPR(overload_type, overload = ill_formed);
134 BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);
135 typedef void result_type;
136 };
137
138 template <typename S, typename F, typename N>
139 struct call_traits<S, void(F, N),
140 typename enable_if<
141 is_convertible<N, std::size_t>::value
142 >::type,
143 typename enable_if<
144 bulk_execute_member<S, F, N>::is_valid
145 >::type,
146 typename enable_if<
147 is_sender<
148 typename bulk_execute_member<S, F, N>::result_type
149 >::value
150 >::type> :
151 bulk_execute_member<S, F, N>
152 {
153 BOOST_ASIO_STATIC_CONSTEXPR(overload_type, overload = call_member);
154 };
155
156 template <typename S, typename F, typename N>
157 struct call_traits<S, void(F, N),
158 typename enable_if<
159 is_convertible<N, std::size_t>::value
160 >::type,
161 typename enable_if<
162 !bulk_execute_member<S, F, N>::is_valid
163 >::type,
164 typename enable_if<
165 bulk_execute_free<S, F, N>::is_valid
166 >::type,
167 typename enable_if<
168 is_sender<
169 typename bulk_execute_free<S, F, N>::result_type
170 >::value
171 >::type> :
172 bulk_execute_free<S, F, N>
173 {
174 BOOST_ASIO_STATIC_CONSTEXPR(overload_type, overload = call_free);
175 };
176
177 template <typename S, typename F, typename N>
178 struct call_traits<S, void(F, N),
179 typename enable_if<
180 is_convertible<N, std::size_t>::value
181 >::type,
182 typename enable_if<
183 !bulk_execute_member<S, F, N>::is_valid
184 >::type,
185 typename enable_if<
186 !bulk_execute_free<S, F, N>::is_valid
187 >::type,
188 typename enable_if<
189 is_sender<S>::value
190 >::type,
191 typename enable_if<
192 is_same<
193 typename result_of<
194 F(typename executor_index<typename remove_cvref<S>::type>::type)
195 >::type,
196 typename result_of<
197 F(typename executor_index<typename remove_cvref<S>::type>::type)
198 >::type
199 >::value
200 >::type,
201 typename enable_if<
202 static_require<S, bulk_guarantee_t::unsequenced_t>::is_valid
203 >::type>
204 {
205 BOOST_ASIO_STATIC_CONSTEXPR(overload_type, overload = adapter);
206 BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);
207 typedef bulk_sender<S, F, N> result_type;
208 };
209
210 struct impl
211 {
212 #if defined(BOOST_ASIO_HAS_MOVE)
213 template <typename S, typename F, typename N>
214 BOOST_ASIO_CONSTEXPR typename enable_if<
215 call_traits<S, void(F, N)>::overload == call_member,
216 typename call_traits<S, void(F, N)>::result_type
217 >::type
218 operator()(S&& s, F&& f, N&& n) const
219 BOOST_ASIO_NOEXCEPT_IF((
220 call_traits<S, void(F, N)>::is_noexcept))
221 {
222 return BOOST_ASIO_MOVE_CAST(S)(s).bulk_execute(
223 BOOST_ASIO_MOVE_CAST(F)(f), BOOST_ASIO_MOVE_CAST(N)(n));
224 }
225
226 template <typename S, typename F, typename N>
227 BOOST_ASIO_CONSTEXPR typename enable_if<
228 call_traits<S, void(F, N)>::overload == call_free,
229 typename call_traits<S, void(F, N)>::result_type
230 >::type
231 operator()(S&& s, F&& f, N&& n) const
232 BOOST_ASIO_NOEXCEPT_IF((
233 call_traits<S, void(F, N)>::is_noexcept))
234 {
235 return bulk_execute(BOOST_ASIO_MOVE_CAST(S)(s),
236 BOOST_ASIO_MOVE_CAST(F)(f), BOOST_ASIO_MOVE_CAST(N)(n));
237 }
238
239 template <typename S, typename F, typename N>
240 BOOST_ASIO_CONSTEXPR typename enable_if<
241 call_traits<S, void(F, N)>::overload == adapter,
242 typename call_traits<S, void(F, N)>::result_type
243 >::type
244 operator()(S&& s, F&& f, N&& n) const
245 BOOST_ASIO_NOEXCEPT_IF((
246 call_traits<S, void(F, N)>::is_noexcept))
247 {
248 return typename call_traits<S, void(F, N)>::result_type(
249 BOOST_ASIO_MOVE_CAST(S)(s), BOOST_ASIO_MOVE_CAST(F)(f),
250 BOOST_ASIO_MOVE_CAST(N)(n));
251 }
252 #else // defined(BOOST_ASIO_HAS_MOVE)
253 template <typename S, typename F, typename N>
254 BOOST_ASIO_CONSTEXPR typename enable_if<
255 call_traits<S, void(const F&, const N&)>::overload == call_member,
256 typename call_traits<S, void(const F&, const N&)>::result_type
257 >::type
258 operator()(S& s, const F& f, const N& n) const
259 BOOST_ASIO_NOEXCEPT_IF((
260 call_traits<S, void(const F&, const N&)>::is_noexcept))
261 {
262 return s.bulk_execute(BOOST_ASIO_MOVE_CAST(F)(f),
263 BOOST_ASIO_MOVE_CAST(N)(n));
264 }
265
266 template <typename S, typename F, typename N>
267 BOOST_ASIO_CONSTEXPR typename enable_if<
268 call_traits<S, void(const F&, const N&)>::overload == call_member,
269 typename call_traits<S, void(const F&, const N&)>::result_type
270 >::type
271 operator()(const S& s, const F& f, const N& n) const
272 BOOST_ASIO_NOEXCEPT_IF((
273 call_traits<S, void(const F&, const N&)>::is_noexcept))
274 {
275 return s.bulk_execute(BOOST_ASIO_MOVE_CAST(F)(f),
276 BOOST_ASIO_MOVE_CAST(N)(n));
277 }
278
279 template <typename S, typename F, typename N>
280 BOOST_ASIO_CONSTEXPR typename enable_if<
281 call_traits<S, void(const F&, const N&)>::overload == call_free,
282 typename call_traits<S, void(const F&, const N&)>::result_type
283 >::type
284 operator()(S& s, const F& f, const N& n) const
285 BOOST_ASIO_NOEXCEPT_IF((
286 call_traits<S, void(const F&, const N&)>::is_noexcept))
287 {
288 return bulk_execute(s, BOOST_ASIO_MOVE_CAST(F)(f),
289 BOOST_ASIO_MOVE_CAST(N)(n));
290 }
291
292 template <typename S, typename F, typename N>
293 BOOST_ASIO_CONSTEXPR typename enable_if<
294 call_traits<S, void(const F&, const N&)>::overload == call_free,
295 typename call_traits<S, void(const F&, const N&)>::result_type
296 >::type
297 operator()(const S& s, const F& f, const N& n) const
298 BOOST_ASIO_NOEXCEPT_IF((
299 call_traits<S, void(const F&, const N&)>::is_noexcept))
300 {
301 return bulk_execute(s, BOOST_ASIO_MOVE_CAST(F)(f),
302 BOOST_ASIO_MOVE_CAST(N)(n));
303 }
304
305 template <typename S, typename F, typename N>
306 BOOST_ASIO_CONSTEXPR typename enable_if<
307 call_traits<S, void(const F&, const N&)>::overload == adapter,
308 typename call_traits<S, void(const F&, const N&)>::result_type
309 >::type
310 operator()(S& s, const F& f, const N& n) const
311 BOOST_ASIO_NOEXCEPT_IF((
312 call_traits<S, void(const F&, const N&)>::is_noexcept))
313 {
314 return typename call_traits<S, void(const F&, const N&)>::result_type(
315 s, BOOST_ASIO_MOVE_CAST(F)(f), BOOST_ASIO_MOVE_CAST(N)(n));
316 }
317
318 template <typename S, typename F, typename N>
319 BOOST_ASIO_CONSTEXPR typename enable_if<
320 call_traits<S, void(const F&, const N&)>::overload == adapter,
321 typename call_traits<S, void(const F&, const N&)>::result_type
322 >::type
323 operator()(const S& s, const F& f, const N& n) const
324 BOOST_ASIO_NOEXCEPT_IF((
325 call_traits<S, void(const F&, const N&)>::is_noexcept))
326 {
327 return typename call_traits<S, void(const F&, const N&)>::result_type(
328 s, BOOST_ASIO_MOVE_CAST(F)(f), BOOST_ASIO_MOVE_CAST(N)(n));
329 }
330 #endif // defined(BOOST_ASIO_HAS_MOVE)
331 };
332
333 template <typename T = impl>
334 struct static_instance
335 {
336 static const T instance;
337 };
338
339 template <typename T>
340 const T static_instance<T>::instance = {};
341
342 } // namespace boost_asio_execution_bulk_execute_fn
343 namespace boost {
344 namespace asio {
345 namespace execution {
346 namespace {
347
348 static BOOST_ASIO_CONSTEXPR
349 const boost_asio_execution_bulk_execute_fn::impl& bulk_execute =
350 boost_asio_execution_bulk_execute_fn::static_instance<>::instance;
351
352 } // namespace
353
354 template <typename S, typename F, typename N>
355 struct can_bulk_execute :
356 integral_constant<bool,
357 boost_asio_execution_bulk_execute_fn::call_traits<
358 S, void(F, N)>::overload !=
359 boost_asio_execution_bulk_execute_fn::ill_formed>
360 {
361 };
362
363 #if defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES)
364
365 template <typename S, typename F, typename N>
366 constexpr bool can_bulk_execute_v = can_bulk_execute<S, F, N>::value;
367
368 #endif // defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES)
369
370 template <typename S, typename F, typename N>
371 struct is_nothrow_bulk_execute :
372 integral_constant<bool,
373 boost_asio_execution_bulk_execute_fn::call_traits<
374 S, void(F, N)>::is_noexcept>
375 {
376 };
377
378 #if defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES)
379
380 template <typename S, typename F, typename N>
381 constexpr bool is_nothrow_bulk_execute_v
382 = is_nothrow_bulk_execute<S, F, N>::value;
383
384 #endif // defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES)
385
386 template <typename S, typename F, typename N>
387 struct bulk_execute_result
388 {
389 typedef typename boost_asio_execution_bulk_execute_fn::call_traits<
390 S, void(F, N)>::result_type type;
391 };
392
393 } // namespace execution
394 } // namespace asio
395 } // namespace boost
396
397 #endif // defined(GENERATING_DOCUMENTATION)
398
399 #include <boost/asio/detail/pop_options.hpp>
400
401 #endif // BOOST_ASIO_EXECUTION_BULK_EXECUTE_HPP