1//
2// execution/blocking_adaptation.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_EXECUTION_BLOCKING_ADAPTATION_HPP
12#define BOOST_ASIO_EXECUTION_BLOCKING_ADAPTATION_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/event.hpp>
20#include <boost/asio/detail/mutex.hpp>
21#include <boost/asio/detail/type_traits.hpp>
22#include <boost/asio/execution/executor.hpp>
23#include <boost/asio/is_applicable_property.hpp>
24#include <boost/asio/prefer.hpp>
25#include <boost/asio/query.hpp>
26#include <boost/asio/require.hpp>
27#include <boost/asio/traits/prefer_member.hpp>
28#include <boost/asio/traits/query_free.hpp>
29#include <boost/asio/traits/query_member.hpp>
30#include <boost/asio/traits/query_static_constexpr_member.hpp>
31#include <boost/asio/traits/require_member.hpp>
32#include <boost/asio/traits/static_query.hpp>
33#include <boost/asio/traits/static_require.hpp>
34
35#include <boost/asio/detail/push_options.hpp>
36
37namespace boost {
38namespace asio {
39
40#if defined(GENERATING_DOCUMENTATION)
41
42namespace execution {
43
44/// A property to describe whether automatic adaptation of an executor is
45/// allowed in order to apply the blocking_adaptation_t::allowed_t property.
46struct blocking_adaptation_t
47{
48 /// The blocking_adaptation_t property applies to executors.
49 template <typename T>
50 static constexpr bool is_applicable_property_v = is_executor_v<T>;
51
52 /// The top-level blocking_adaptation_t property cannot be required.
53 static constexpr bool is_requirable = false;
54
55 /// The top-level blocking_adaptation_t property cannot be preferred.
56 static constexpr bool is_preferable = false;
57
58 /// The type returned by queries against an @c any_executor.
59 typedef blocking_adaptation_t polymorphic_query_result_type;
60
61 /// A sub-property that indicates that automatic adaptation is not allowed.
62 struct disallowed_t
63 {
64 /// The blocking_adaptation_t::disallowed_t property applies to executors.
65 template <typename T>
66 static constexpr bool is_applicable_property_v = is_executor_v<T>;
67
68 /// The blocking_adaptation_t::disallowed_t property can be required.
69 static constexpr bool is_requirable = true;
70
71 /// The blocking_adaptation_t::disallowed_t property can be preferred.
72 static constexpr bool is_preferable = true;
73
74 /// The type returned by queries against an @c any_executor.
75 typedef blocking_adaptation_t polymorphic_query_result_type;
76
77 /// Default constructor.
78 constexpr disallowed_t();
79
80 /// Get the value associated with a property object.
81 /**
82 * @returns disallowed_t();
83 */
84 static constexpr blocking_adaptation_t value();
85 };
86
87 /// A sub-property that indicates that automatic adaptation is allowed.
88 struct allowed_t
89 {
90 /// The blocking_adaptation_t::allowed_t property applies to executors.
91 template <typename T>
92 static constexpr bool is_applicable_property_v = is_executor_v<T>;
93
94 /// The blocking_adaptation_t::allowed_t property can be required.
95 static constexpr bool is_requirable = true;
96
97 /// The blocking_adaptation_t::allowed_t property can be preferred.
98 static constexpr bool is_preferable = false;
99
100 /// The type returned by queries against an @c any_executor.
101 typedef blocking_adaptation_t polymorphic_query_result_type;
102
103 /// Default constructor.
104 constexpr allowed_t();
105
106 /// Get the value associated with a property object.
107 /**
108 * @returns allowed_t();
109 */
110 static constexpr blocking_adaptation_t value();
111 };
112
113 /// A special value used for accessing the blocking_adaptation_t::disallowed_t
114 /// property.
115 static constexpr disallowed_t disallowed;
116
117 /// A special value used for accessing the blocking_adaptation_t::allowed_t
118 /// property.
119 static constexpr allowed_t allowed;
120
121 /// Default constructor.
122 constexpr blocking_adaptation_t();
123
124 /// Construct from a sub-property value.
125 constexpr blocking_adaptation_t(disallowed_t);
126
127 /// Construct from a sub-property value.
128 constexpr blocking_adaptation_t(allowed_t);
129
130 /// Compare property values for equality.
131 friend constexpr bool operator==(
132 const blocking_adaptation_t& a, const blocking_adaptation_t& b) noexcept;
133
134 /// Compare property values for inequality.
135 friend constexpr bool operator!=(
136 const blocking_adaptation_t& a, const blocking_adaptation_t& b) noexcept;
137};
138
139/// A special value used for accessing the blocking_adaptation_t property.
140constexpr blocking_adaptation_t blocking_adaptation;
141
142} // namespace execution
143
144#else // defined(GENERATING_DOCUMENTATION)
145
146namespace execution {
147namespace detail {
148namespace blocking_adaptation {
149
150template <int I> struct disallowed_t;
151template <int I> struct allowed_t;
152
153} // namespace blocking_adaptation
154
155template <int I = 0>
156struct blocking_adaptation_t
157{
158#if defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES)
159 template <typename T>
160 static constexpr bool is_applicable_property_v = is_executor<T>::value;
161#endif // defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES)
162
163 static constexpr bool is_requirable = false;
164 static constexpr bool is_preferable = false;
165 typedef blocking_adaptation_t polymorphic_query_result_type;
166
167 typedef detail::blocking_adaptation::disallowed_t<I> disallowed_t;
168 typedef detail::blocking_adaptation::allowed_t<I> allowed_t;
169
170 constexpr blocking_adaptation_t()
171 : value_(-1)
172 {
173 }
174
175 constexpr blocking_adaptation_t(disallowed_t)
176 : value_(0)
177 {
178 }
179
180 constexpr blocking_adaptation_t(allowed_t)
181 : value_(1)
182 {
183 }
184
185 template <typename T>
186 struct proxy
187 {
188#if defined(BOOST_ASIO_HAS_DEDUCED_QUERY_MEMBER_TRAIT)
189 struct type
190 {
191 template <typename P>
192 auto query(P&& p) const
193 noexcept(
194 noexcept(
195 declval<conditional_t<true, T, P>>().query(static_cast<P&&>(p))
196 )
197 )
198 -> decltype(
199 declval<conditional_t<true, T, P>>().query(static_cast<P&&>(p))
200 );
201 };
202#else // defined(BOOST_ASIO_HAS_DEDUCED_QUERY_MEMBER_TRAIT)
203 typedef T type;
204#endif // defined(BOOST_ASIO_HAS_DEDUCED_QUERY_MEMBER_TRAIT)
205 };
206
207 template <typename T>
208 struct static_proxy
209 {
210#if defined(BOOST_ASIO_HAS_DEDUCED_QUERY_STATIC_CONSTEXPR_MEMBER_TRAIT)
211 struct type
212 {
213 template <typename P>
214 static constexpr auto query(P&& p)
215 noexcept(
216 noexcept(
217 conditional_t<true, T, P>::query(static_cast<P&&>(p))
218 )
219 )
220 -> decltype(
221 conditional_t<true, T, P>::query(static_cast<P&&>(p))
222 )
223 {
224 return T::query(static_cast<P&&>(p));
225 }
226 };
227#else // defined(BOOST_ASIO_HAS_DEDUCED_QUERY_STATIC_CONSTEXPR_MEMBER_TRAIT)
228 typedef T type;
229#endif // defined(BOOST_ASIO_HAS_DEDUCED_QUERY_STATIC_CONSTEXPR_MEMBER_TRAIT)
230 };
231
232 template <typename T>
233 struct query_member :
234 traits::query_member<typename proxy<T>::type, blocking_adaptation_t> {};
235
236 template <typename T>
237 struct query_static_constexpr_member :
238 traits::query_static_constexpr_member<
239 typename static_proxy<T>::type, blocking_adaptation_t> {};
240
241#if defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \
242 && defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)
243 template <typename T>
244 static constexpr typename query_static_constexpr_member<T>::result_type
245 static_query()
246 noexcept(query_static_constexpr_member<T>::is_noexcept)
247 {
248 return query_static_constexpr_member<T>::value();
249 }
250
251 template <typename T>
252 static constexpr
253 typename traits::static_query<T, disallowed_t>::result_type
254 static_query(
255 enable_if_t<
256 !query_static_constexpr_member<T>::is_valid
257 >* = 0,
258 enable_if_t<
259 !query_member<T>::is_valid
260 >* = 0,
261 enable_if_t<
262 traits::static_query<T, disallowed_t>::is_valid
263 >* = 0) noexcept
264 {
265 return traits::static_query<T, disallowed_t>::value();
266 }
267
268 template <typename T>
269 static constexpr
270 typename traits::static_query<T, allowed_t>::result_type
271 static_query(
272 enable_if_t<
273 !query_static_constexpr_member<T>::is_valid
274 >* = 0,
275 enable_if_t<
276 !query_member<T>::is_valid
277 >* = 0,
278 enable_if_t<
279 !traits::static_query<T, disallowed_t>::is_valid
280 >* = 0,
281 enable_if_t<
282 traits::static_query<T, allowed_t>::is_valid
283 >* = 0) noexcept
284 {
285 return traits::static_query<T, allowed_t>::value();
286 }
287
288 template <typename E,
289 typename T = decltype(blocking_adaptation_t::static_query<E>())>
290 static constexpr const T static_query_v
291 = blocking_adaptation_t::static_query<E>();
292#endif // defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT)
293 // && defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)
294
295 friend constexpr bool operator==(
296 const blocking_adaptation_t& a, const blocking_adaptation_t& b)
297 {
298 return a.value_ == b.value_;
299 }
300
301 friend constexpr bool operator!=(
302 const blocking_adaptation_t& a, const blocking_adaptation_t& b)
303 {
304 return a.value_ != b.value_;
305 }
306
307 struct convertible_from_blocking_adaptation_t
308 {
309 constexpr convertible_from_blocking_adaptation_t(
310 blocking_adaptation_t)
311 {
312 }
313 };
314
315 template <typename Executor>
316 friend constexpr blocking_adaptation_t query(
317 const Executor& ex, convertible_from_blocking_adaptation_t,
318 enable_if_t<
319 can_query<const Executor&, disallowed_t>::value
320 >* = 0)
321#if !defined(__clang__) // Clang crashes if noexcept is used here.
322#if defined(BOOST_ASIO_MSVC) // Visual C++ wants the type to be qualified.
323 noexcept(is_nothrow_query<const Executor&,
324 blocking_adaptation_t<>::disallowed_t>::value)
325#else // defined(BOOST_ASIO_MSVC)
326 noexcept(is_nothrow_query<const Executor&, disallowed_t>::value)
327#endif // defined(BOOST_ASIO_MSVC)
328#endif // !defined(__clang__)
329 {
330 return boost::asio::query(ex, disallowed_t());
331 }
332
333 template <typename Executor>
334 friend constexpr blocking_adaptation_t query(
335 const Executor& ex, convertible_from_blocking_adaptation_t,
336 enable_if_t<
337 !can_query<const Executor&, disallowed_t>::value
338 >* = 0,
339 enable_if_t<
340 can_query<const Executor&, allowed_t>::value
341 >* = 0)
342#if !defined(__clang__) // Clang crashes if noexcept is used here.
343#if defined(BOOST_ASIO_MSVC) // Visual C++ wants the type to be qualified.
344 noexcept(is_nothrow_query<const Executor&,
345 blocking_adaptation_t<>::allowed_t>::value)
346#else // defined(BOOST_ASIO_MSVC)
347 noexcept(is_nothrow_query<const Executor&, allowed_t>::value)
348#endif // defined(BOOST_ASIO_MSVC)
349#endif // !defined(__clang__)
350 {
351 return boost::asio::query(ex, allowed_t());
352 }
353
354 BOOST_ASIO_STATIC_CONSTEXPR_DEFAULT_INIT(disallowed_t, disallowed);
355 BOOST_ASIO_STATIC_CONSTEXPR_DEFAULT_INIT(allowed_t, allowed);
356
357private:
358 int value_;
359};
360
361#if defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \
362 && defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)
363template <int I> template <typename E, typename T>
364const T blocking_adaptation_t<I>::static_query_v;
365#endif // defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT)
366 // && defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)
367
368template <int I>
369const typename blocking_adaptation_t<I>::disallowed_t
370blocking_adaptation_t<I>::disallowed;
371
372template <int I>
373const typename blocking_adaptation_t<I>::allowed_t
374blocking_adaptation_t<I>::allowed;
375
376namespace blocking_adaptation {
377
378template <int I = 0>
379struct disallowed_t
380{
381#if defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES)
382 template <typename T>
383 static constexpr bool is_applicable_property_v = is_executor<T>::value;
384#endif // defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES)
385
386 static constexpr bool is_requirable = true;
387 static constexpr bool is_preferable = true;
388 typedef blocking_adaptation_t<I> polymorphic_query_result_type;
389
390 constexpr disallowed_t()
391 {
392 }
393
394 template <typename T>
395 struct query_member :
396 traits::query_member<
397 typename blocking_adaptation_t<I>::template proxy<T>::type,
398 disallowed_t> {};
399
400 template <typename T>
401 struct query_static_constexpr_member :
402 traits::query_static_constexpr_member<
403 typename blocking_adaptation_t<I>::template static_proxy<T>::type,
404 disallowed_t> {};
405
406#if defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \
407 && defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)
408 template <typename T>
409 static constexpr
410 typename query_static_constexpr_member<T>::result_type
411 static_query()
412 noexcept(query_static_constexpr_member<T>::is_noexcept)
413 {
414 return query_static_constexpr_member<T>::value();
415 }
416
417 template <typename T>
418 static constexpr disallowed_t static_query(
419 enable_if_t<
420 !query_static_constexpr_member<T>::is_valid
421 >* = 0,
422 enable_if_t<
423 !query_member<T>::is_valid
424 >* = 0,
425 enable_if_t<
426 !traits::query_free<T, disallowed_t>::is_valid
427 >* = 0,
428 enable_if_t<
429 !can_query<T, allowed_t<I>>::value
430 >* = 0) noexcept
431 {
432 return disallowed_t();
433 }
434
435 template <typename E, typename T = decltype(disallowed_t::static_query<E>())>
436 static constexpr const T static_query_v
437 = disallowed_t::static_query<E>();
438#endif // defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT)
439 // && defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)
440
441 static constexpr blocking_adaptation_t<I> value()
442 {
443 return disallowed_t();
444 }
445
446 friend constexpr bool operator==(const disallowed_t&, const disallowed_t&)
447 {
448 return true;
449 }
450
451 friend constexpr bool operator!=(const disallowed_t&, const disallowed_t&)
452 {
453 return false;
454 }
455
456 friend constexpr bool operator==(const disallowed_t&, const allowed_t<I>&)
457 {
458 return false;
459 }
460
461 friend constexpr bool operator!=(const disallowed_t&, const allowed_t<I>&)
462 {
463 return true;
464 }
465};
466
467#if defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \
468 && defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)
469template <int I> template <typename E, typename T>
470const T disallowed_t<I>::static_query_v;
471#endif // defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT)
472 // && defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)
473
474template <typename Executor>
475class adapter
476{
477public:
478 adapter(int, const Executor& e) noexcept
479 : executor_(e)
480 {
481 }
482
483 adapter(const adapter& other) noexcept
484 : executor_(other.executor_)
485 {
486 }
487
488 adapter(adapter&& other) noexcept
489 : executor_(static_cast<Executor&&>(other.executor_))
490 {
491 }
492
493 template <int I>
494 static constexpr allowed_t<I> query(blocking_adaptation_t<I>) noexcept
495 {
496 return allowed_t<I>();
497 }
498
499 template <int I>
500 static constexpr allowed_t<I> query(allowed_t<I>) noexcept
501 {
502 return allowed_t<I>();
503 }
504
505 template <int I>
506 static constexpr allowed_t<I> query(disallowed_t<I>) noexcept
507 {
508 return allowed_t<I>();
509 }
510
511 template <typename Property>
512 enable_if_t<
513 can_query<const Executor&, Property>::value,
514 query_result_t<const Executor&, Property>
515 > query(const Property& p) const
516 noexcept(is_nothrow_query<const Executor&, Property>::value)
517 {
518 return boost::asio::query(executor_, p);
519 }
520
521 template <int I>
522 Executor require(disallowed_t<I>) const noexcept
523 {
524 return executor_;
525 }
526
527 template <typename Property>
528 enable_if_t<
529 can_require<const Executor&, Property>::value,
530 adapter<decay_t<require_result_t<const Executor&, Property>>>
531 > require(const Property& p) const
532 noexcept(is_nothrow_require<const Executor&, Property>::value)
533 {
534 return adapter<decay_t<require_result_t<const Executor&, Property>>>(
535 0, boost::asio::require(executor_, p));
536 }
537
538 template <typename Property>
539 enable_if_t<
540 can_prefer<const Executor&, Property>::value,
541 adapter<decay_t<prefer_result_t<const Executor&, Property>>>
542 > prefer(const Property& p) const
543 noexcept(is_nothrow_prefer<const Executor&, Property>::value)
544 {
545 return adapter<decay_t<prefer_result_t<const Executor&, Property>>>(
546 0, boost::asio::prefer(executor_, p));
547 }
548
549 template <typename Function>
550 enable_if_t<
551 traits::execute_member<const Executor&, Function>::is_valid
552 > execute(Function&& f) const
553 {
554 executor_.execute(static_cast<Function&&>(f));
555 }
556
557 friend bool operator==(const adapter& a, const adapter& b) noexcept
558 {
559 return a.executor_ == b.executor_;
560 }
561
562 friend bool operator!=(const adapter& a, const adapter& b) noexcept
563 {
564 return a.executor_ != b.executor_;
565 }
566
567private:
568 Executor executor_;
569};
570
571template <int I = 0>
572struct allowed_t
573{
574#if defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES)
575 template <typename T>
576 static constexpr bool is_applicable_property_v = is_executor<T>::value;
577#endif // defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES)
578
579 static constexpr bool is_requirable = true;
580 static constexpr bool is_preferable = false;
581 typedef blocking_adaptation_t<I> polymorphic_query_result_type;
582
583 constexpr allowed_t()
584 {
585 }
586
587 template <typename T>
588 struct query_member :
589 traits::query_member<
590 typename blocking_adaptation_t<I>::template proxy<T>::type,
591 allowed_t> {};
592
593 template <typename T>
594 struct query_static_constexpr_member :
595 traits::query_static_constexpr_member<
596 typename blocking_adaptation_t<I>::template static_proxy<T>::type,
597 allowed_t> {};
598
599#if defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \
600 && defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)
601 template <typename T>
602 static constexpr typename query_static_constexpr_member<T>::result_type
603 static_query()
604 noexcept(query_static_constexpr_member<T>::is_noexcept)
605 {
606 return query_static_constexpr_member<T>::value();
607 }
608
609 template <typename E, typename T = decltype(allowed_t::static_query<E>())>
610 static constexpr const T static_query_v = allowed_t::static_query<E>();
611#endif // defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT)
612 // && defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)
613
614 static constexpr blocking_adaptation_t<I> value()
615 {
616 return allowed_t();
617 }
618
619 friend constexpr bool operator==(const allowed_t&, const allowed_t&)
620 {
621 return true;
622 }
623
624 friend constexpr bool operator!=(const allowed_t&, const allowed_t&)
625 {
626 return false;
627 }
628
629 friend constexpr bool operator==(const allowed_t&, const disallowed_t<I>&)
630 {
631 return false;
632 }
633
634 friend constexpr bool operator!=(const allowed_t&, const disallowed_t<I>&)
635 {
636 return true;
637 }
638
639 template <typename Executor>
640 friend adapter<Executor> require(
641 const Executor& e, const allowed_t&,
642 enable_if_t<
643 is_executor<Executor>::value
644 >* = 0)
645 {
646 return adapter<Executor>(0, e);
647 }
648};
649
650#if defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \
651 && defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)
652template <int I> template <typename E, typename T>
653const T allowed_t<I>::static_query_v;
654#endif // defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT)
655 // && defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)
656
657template <typename Function>
658class blocking_execute_state
659{
660public:
661 template <typename F>
662 blocking_execute_state(F&& f)
663 : func_(static_cast<F&&>(f)),
664 is_complete_(false)
665 {
666 }
667
668 template <typename Executor>
669 void execute_and_wait(Executor&& ex)
670 {
671 handler h = { this };
672 ex.execute(h);
673 boost::asio::detail::mutex::scoped_lock lock(mutex_);
674 while (!is_complete_)
675 event_.wait(lock);
676 }
677
678 struct cleanup
679 {
680 ~cleanup()
681 {
682 boost::asio::detail::mutex::scoped_lock lock(state_->mutex_);
683 state_->is_complete_ = true;
684 state_->event_.unlock_and_signal_one_for_destruction(lock);
685 }
686
687 blocking_execute_state* state_;
688 };
689
690 struct handler
691 {
692 void operator()()
693 {
694 cleanup c = { state_ };
695 state_->func_();
696 }
697
698 blocking_execute_state* state_;
699 };
700
701 Function func_;
702 boost::asio::detail::mutex mutex_;
703 boost::asio::detail::event event_;
704 bool is_complete_;
705};
706
707template <typename Executor, typename Function>
708void blocking_execute(
709 Executor&& ex,
710 Function&& func)
711{
712 typedef decay_t<Function> func_t;
713 blocking_execute_state<func_t> state(static_cast<Function&&>(func));
714 state.execute_and_wait(ex);
715}
716
717} // namespace blocking_adaptation
718} // namespace detail
719
720typedef detail::blocking_adaptation_t<> blocking_adaptation_t;
721
722constexpr blocking_adaptation_t blocking_adaptation;
723
724} // namespace execution
725
726#if !defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES)
727
728template <typename T>
729struct is_applicable_property<T, execution::blocking_adaptation_t>
730 : integral_constant<bool, execution::is_executor<T>::value>
731{
732};
733
734template <typename T>
735struct is_applicable_property<T, execution::blocking_adaptation_t::disallowed_t>
736 : integral_constant<bool, execution::is_executor<T>::value>
737{
738};
739
740template <typename T>
741struct is_applicable_property<T, execution::blocking_adaptation_t::allowed_t>
742 : integral_constant<bool, execution::is_executor<T>::value>
743{
744};
745
746#endif // !defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES)
747
748namespace traits {
749
750#if !defined(BOOST_ASIO_HAS_DEDUCED_QUERY_FREE_TRAIT)
751
752template <typename T>
753struct query_free_default<T, execution::blocking_adaptation_t,
754 enable_if_t<
755 can_query<T, execution::blocking_adaptation_t::disallowed_t>::value
756 >>
757{
758 static constexpr bool is_valid = true;
759 static constexpr bool is_noexcept =
760 is_nothrow_query<T, execution::blocking_adaptation_t::disallowed_t>::value;
761
762 typedef execution::blocking_adaptation_t result_type;
763};
764
765template <typename T>
766struct query_free_default<T, execution::blocking_adaptation_t,
767 enable_if_t<
768 !can_query<T, execution::blocking_adaptation_t::disallowed_t>::value
769 && can_query<T, execution::blocking_adaptation_t::allowed_t>::value
770 >>
771{
772 static constexpr bool is_valid = true;
773 static constexpr bool is_noexcept =
774 is_nothrow_query<T, execution::blocking_adaptation_t::allowed_t>::value;
775
776 typedef execution::blocking_adaptation_t result_type;
777};
778
779#endif // !defined(BOOST_ASIO_HAS_DEDUCED_QUERY_FREE_TRAIT)
780
781#if !defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \
782 || !defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)
783
784template <typename T>
785struct static_query<T, execution::blocking_adaptation_t,
786 enable_if_t<
787 execution::detail::blocking_adaptation_t<0>::
788 query_static_constexpr_member<T>::is_valid
789 >>
790{
791 static constexpr bool is_valid = true;
792 static constexpr bool is_noexcept = true;
793
794 typedef typename execution::detail::blocking_adaptation_t<0>::
795 query_static_constexpr_member<T>::result_type result_type;
796
797 static constexpr result_type value()
798 {
799 return execution::detail::blocking_adaptation_t<0>::
800 query_static_constexpr_member<T>::value();
801 }
802};
803
804template <typename T>
805struct static_query<T, execution::blocking_adaptation_t,
806 enable_if_t<
807 !execution::detail::blocking_adaptation_t<0>::
808 query_static_constexpr_member<T>::is_valid
809 && !execution::detail::blocking_adaptation_t<0>::
810 query_member<T>::is_valid
811 && traits::static_query<T,
812 execution::blocking_adaptation_t::disallowed_t>::is_valid
813 >>
814{
815 static constexpr bool is_valid = true;
816 static constexpr bool is_noexcept = true;
817
818 typedef typename traits::static_query<T,
819 execution::blocking_adaptation_t::disallowed_t>::result_type result_type;
820
821 static constexpr result_type value()
822 {
823 return traits::static_query<T,
824 execution::blocking_adaptation_t::disallowed_t>::value();
825 }
826};
827
828template <typename T>
829struct static_query<T, execution::blocking_adaptation_t,
830 enable_if_t<
831 !execution::detail::blocking_adaptation_t<0>::
832 query_static_constexpr_member<T>::is_valid
833 && !execution::detail::blocking_adaptation_t<0>::
834 query_member<T>::is_valid
835 && !traits::static_query<T,
836 execution::blocking_adaptation_t::disallowed_t>::is_valid
837 && traits::static_query<T,
838 execution::blocking_adaptation_t::allowed_t>::is_valid
839 >>
840{
841 static constexpr bool is_valid = true;
842 static constexpr bool is_noexcept = true;
843
844 typedef typename traits::static_query<T,
845 execution::blocking_adaptation_t::allowed_t>::result_type result_type;
846
847 static constexpr result_type value()
848 {
849 return traits::static_query<T,
850 execution::blocking_adaptation_t::allowed_t>::value();
851 }
852};
853
854template <typename T>
855struct static_query<T, execution::blocking_adaptation_t::disallowed_t,
856 enable_if_t<
857 execution::detail::blocking_adaptation::disallowed_t<0>::
858 query_static_constexpr_member<T>::is_valid
859 >>
860{
861 static constexpr bool is_valid = true;
862 static constexpr bool is_noexcept = true;
863
864 typedef typename execution::detail::blocking_adaptation::disallowed_t<0>::
865 query_static_constexpr_member<T>::result_type result_type;
866
867 static constexpr result_type value()
868 {
869 return execution::detail::blocking_adaptation::disallowed_t<0>::
870 query_static_constexpr_member<T>::value();
871 }
872};
873
874template <typename T>
875struct static_query<T, execution::blocking_adaptation_t::disallowed_t,
876 enable_if_t<
877 !execution::detail::blocking_adaptation::disallowed_t<0>::
878 query_static_constexpr_member<T>::is_valid
879 && !execution::detail::blocking_adaptation::disallowed_t<0>::
880 query_member<T>::is_valid
881 && !traits::query_free<T,
882 execution::blocking_adaptation_t::disallowed_t>::is_valid
883 && !can_query<T, execution::blocking_adaptation_t::allowed_t>::value
884 >>
885{
886 static constexpr bool is_valid = true;
887 static constexpr bool is_noexcept = true;
888
889 typedef execution::blocking_adaptation_t::disallowed_t result_type;
890
891 static constexpr result_type value()
892 {
893 return result_type();
894 }
895};
896
897template <typename T>
898struct static_query<T, execution::blocking_adaptation_t::allowed_t,
899 enable_if_t<
900 execution::detail::blocking_adaptation::allowed_t<0>::
901 query_static_constexpr_member<T>::is_valid
902 >>
903{
904 static constexpr bool is_valid = true;
905 static constexpr bool is_noexcept = true;
906
907 typedef typename execution::detail::blocking_adaptation::allowed_t<0>::
908 query_static_constexpr_member<T>::result_type result_type;
909
910 static constexpr result_type value()
911 {
912 return execution::detail::blocking_adaptation::allowed_t<0>::
913 query_static_constexpr_member<T>::value();
914 }
915};
916
917#endif // !defined(BOOST_ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT)
918 // || !defined(BOOST_ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)
919
920#if !defined(BOOST_ASIO_HAS_DEDUCED_REQUIRE_FREE_TRAIT)
921
922template <typename T>
923struct require_free_default<T, execution::blocking_adaptation_t::allowed_t,
924 enable_if_t<
925 is_same<T, decay_t<T>>::value
926 && execution::is_executor<T>::value
927 >>
928{
929 static constexpr bool is_valid = true;
930 static constexpr bool is_noexcept = false;
931 typedef execution::detail::blocking_adaptation::adapter<T> result_type;
932};
933
934#endif // !defined(BOOST_ASIO_HAS_DEDUCED_REQUIRE_FREE_TRAIT)
935
936#if !defined(BOOST_ASIO_HAS_DEDUCED_EQUALITY_COMPARABLE_TRAIT)
937
938template <typename Executor>
939struct equality_comparable<
940 execution::detail::blocking_adaptation::adapter<Executor>>
941{
942 static constexpr bool is_valid = true;
943 static constexpr bool is_noexcept = true;
944};
945
946#endif // !defined(BOOST_ASIO_HAS_DEDUCED_EQUALITY_COMPARABLE_TRAIT)
947
948#if !defined(BOOST_ASIO_HAS_DEDUCED_EXECUTE_MEMBER_TRAIT)
949
950template <typename Executor, typename Function>
951struct execute_member<
952 execution::detail::blocking_adaptation::adapter<Executor>, Function>
953{
954 static constexpr bool is_valid = true;
955 static constexpr bool is_noexcept = false;
956 typedef void result_type;
957};
958
959#endif // !defined(BOOST_ASIO_HAS_DEDUCED_EXECUTE_MEMBER_TRAIT)
960
961#if !defined(BOOST_ASIO_HAS_DEDUCED_QUERY_STATIC_CONSTEXPR_MEMBER_TRAIT)
962
963template <typename Executor, int I>
964struct query_static_constexpr_member<
965 execution::detail::blocking_adaptation::adapter<Executor>,
966 execution::detail::blocking_adaptation_t<I>>
967{
968 static constexpr bool is_valid = true;
969 static constexpr bool is_noexcept = true;
970 typedef execution::blocking_adaptation_t::allowed_t result_type;
971
972 static constexpr result_type value() noexcept
973 {
974 return result_type();
975 }
976};
977
978template <typename Executor, int I>
979struct query_static_constexpr_member<
980 execution::detail::blocking_adaptation::adapter<Executor>,
981 execution::detail::blocking_adaptation::allowed_t<I>>
982{
983 static constexpr bool is_valid = true;
984 static constexpr bool is_noexcept = true;
985 typedef execution::blocking_adaptation_t::allowed_t result_type;
986
987 static constexpr result_type value() noexcept
988 {
989 return result_type();
990 }
991};
992
993template <typename Executor, int I>
994struct query_static_constexpr_member<
995 execution::detail::blocking_adaptation::adapter<Executor>,
996 execution::detail::blocking_adaptation::disallowed_t<I>>
997{
998 static constexpr bool is_valid = true;
999 static constexpr bool is_noexcept = true;
1000 typedef execution::blocking_adaptation_t::allowed_t result_type;
1001
1002 static constexpr result_type value() noexcept
1003 {
1004 return result_type();
1005 }
1006};
1007
1008#endif // !defined(BOOST_ASIO_HAS_DEDUCED_QUERY_STATIC_CONSTEXPR_MEMBER_TRAIT)
1009
1010#if !defined(BOOST_ASIO_HAS_DEDUCED_QUERY_MEMBER_TRAIT)
1011
1012template <typename Executor, typename Property>
1013struct query_member<
1014 execution::detail::blocking_adaptation::adapter<Executor>, Property,
1015 enable_if_t<
1016 can_query<const Executor&, Property>::value
1017 >>
1018{
1019 static constexpr bool is_valid = true;
1020 static constexpr bool is_noexcept =
1021 is_nothrow_query<Executor, Property>::value;
1022 typedef query_result_t<Executor, Property> result_type;
1023};
1024
1025#endif // !defined(BOOST_ASIO_HAS_DEDUCED_QUERY_MEMBER_TRAIT)
1026
1027#if !defined(BOOST_ASIO_HAS_DEDUCED_REQUIRE_MEMBER_TRAIT)
1028
1029template <typename Executor, int I>
1030struct require_member<
1031 execution::detail::blocking_adaptation::adapter<Executor>,
1032 execution::detail::blocking_adaptation::disallowed_t<I>>
1033{
1034 static constexpr bool is_valid = true;
1035 static constexpr bool is_noexcept = true;
1036 typedef Executor result_type;
1037};
1038
1039template <typename Executor, typename Property>
1040struct require_member<
1041 execution::detail::blocking_adaptation::adapter<Executor>, Property,
1042 enable_if_t<
1043 can_require<const Executor&, Property>::value
1044 >>
1045{
1046 static constexpr bool is_valid = true;
1047 static constexpr bool is_noexcept =
1048 is_nothrow_require<Executor, Property>::value;
1049 typedef execution::detail::blocking_adaptation::adapter<
1050 decay_t<require_result_t<Executor, Property>>> result_type;
1051};
1052
1053#endif // !defined(BOOST_ASIO_HAS_DEDUCED_REQUIRE_MEMBER_TRAIT)
1054
1055#if !defined(BOOST_ASIO_HAS_DEDUCED_PREFER_MEMBER_TRAIT)
1056
1057template <typename Executor, typename Property>
1058struct prefer_member<
1059 execution::detail::blocking_adaptation::adapter<Executor>, Property,
1060 enable_if_t<
1061 can_prefer<const Executor&, Property>::value
1062 >>
1063{
1064 static constexpr bool is_valid = true;
1065 static constexpr bool is_noexcept =
1066 is_nothrow_prefer<Executor, Property>::value;
1067 typedef execution::detail::blocking_adaptation::adapter<
1068 decay_t<prefer_result_t<Executor, Property>>> result_type;
1069};
1070
1071#endif // !defined(BOOST_ASIO_HAS_DEDUCED_PREFER_MEMBER_TRAIT)
1072
1073} // namespace traits
1074
1075#endif // defined(GENERATING_DOCUMENTATION)
1076
1077} // namespace asio
1078} // namespace boost
1079
1080#include <boost/asio/detail/pop_options.hpp>
1081
1082#endif // BOOST_ASIO_EXECUTION_BLOCKING_ADAPTATION_HPP
1083

source code of boost/libs/asio/include/boost/asio/execution/blocking_adaptation.hpp