Clementine
blocking_adaptation.hpp
1 //
2 // execution/blocking_adaptation.hpp
3 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
4 //
5 // Copyright (c) 2003-2020 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 ASIO_EXECUTION_BLOCKING_ADAPTATION_HPP
12 #define 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 "asio/detail/config.hpp"
19 #include "asio/detail/event.hpp"
20 #include "asio/detail/mutex.hpp"
21 #include "asio/detail/type_traits.hpp"
22 #include "asio/execution/execute.hpp"
23 #include "asio/execution/executor.hpp"
24 #include "asio/execution/scheduler.hpp"
25 #include "asio/execution/sender.hpp"
26 #include "asio/is_applicable_property.hpp"
27 #include "asio/prefer.hpp"
28 #include "asio/query.hpp"
29 #include "asio/require.hpp"
30 #include "asio/traits/prefer_member.hpp"
31 #include "asio/traits/query_free.hpp"
32 #include "asio/traits/query_member.hpp"
33 #include "asio/traits/query_static_constexpr_member.hpp"
34 #include "asio/traits/require_member.hpp"
35 #include "asio/traits/static_query.hpp"
36 #include "asio/traits/static_require.hpp"
37 
38 #include "asio/detail/push_options.hpp"
39 
40 namespace asio {
41 
42 #if defined(GENERATING_DOCUMENTATION)
43 
44 namespace execution {
45 
48 struct blocking_adaptation_t
49 {
52  template <typename T>
53  static constexpr bool is_applicable_property_v =
54  is_executor_v<T> || is_sender_v<T> || is_scheduler_v<T>;
55 
57  static constexpr bool is_requirable = false;
58 
60  static constexpr bool is_preferable = false;
61 
63  typedef blocking_adaptation_t polymorphic_query_result_type;
64 
66  struct disallowed_t
67  {
70  template <typename T>
71  static constexpr bool is_applicable_property_v =
72  is_executor_v<T> || is_sender_v<T> || is_scheduler_v<T>;
73 
75  static constexpr bool is_requirable = true;
76 
78  static constexpr bool is_preferable = true;
79 
81  typedef blocking_adaptation_t polymorphic_query_result_type;
82 
84  constexpr disallowed_t();
85 
87 
90  static constexpr blocking_adaptation_t value();
91  };
92 
94  struct allowed_t
95  {
98  template <typename T>
99  static constexpr bool is_applicable_property_v =
100  is_executor_v<T> || is_sender_v<T> || is_scheduler_v<T>;
101 
103  static constexpr bool is_requirable = true;
104 
106  static constexpr bool is_preferable = false;
107 
109  typedef blocking_adaptation_t polymorphic_query_result_type;
110 
112  constexpr allowed_t();
113 
115 
118  static constexpr blocking_adaptation_t value();
119  };
120 
123  static constexpr disallowed_t disallowed;
124 
127  static constexpr allowed_t allowed;
128 
130  constexpr blocking_adaptation_t();
131 
133  constexpr blocking_adaptation_t(disallowed_t);
134 
136  constexpr blocking_adaptation_t(allowed_t);
137 
139  friend constexpr bool operator==(
140  const blocking_adaptation_t& a, const blocking_adaptation_t& b) noexcept;
141 
143  friend constexpr bool operator!=(
144  const blocking_adaptation_t& a, const blocking_adaptation_t& b) noexcept;
145 };
146 
148 constexpr blocking_adaptation_t blocking_adaptation;
149 
150 } // namespace execution
151 
152 #else // defined(GENERATING_DOCUMENTATION)
153 
154 namespace execution {
155 namespace detail {
156 namespace blocking_adaptation {
157 
158 template <int I> struct disallowed_t;
159 template <int I> struct allowed_t;
160 
161 } // namespace blocking_adaptation
162 
163 template <int I = 0>
165 {
166 #if defined(ASIO_HAS_VARIABLE_TEMPLATES)
167  template <typename T>
168  ASIO_STATIC_CONSTEXPR(bool,
169  is_applicable_property_v = is_executor<T>::value
171 #endif // defined(ASIO_HAS_VARIABLE_TEMPLATES)
172 
173  ASIO_STATIC_CONSTEXPR(bool, is_requirable = false);
174  ASIO_STATIC_CONSTEXPR(bool, is_preferable = false);
176 
179 
180  ASIO_CONSTEXPR blocking_adaptation_t()
181  : value_(-1)
182  {
183  }
184 
185  ASIO_CONSTEXPR blocking_adaptation_t(disallowed_t)
186  : value_(0)
187  {
188  }
189 
190  ASIO_CONSTEXPR blocking_adaptation_t(allowed_t)
191  : value_(1)
192  {
193  }
194 
195 #if defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \
196  && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)
197  template <typename T>
198  static ASIO_CONSTEXPR
200  T, blocking_adaptation_t>::result_type
201  static_query()
202  ASIO_NOEXCEPT_IF((
204  T, blocking_adaptation_t
205  >::is_noexcept))
206  {
208  T, blocking_adaptation_t>::value();
209  }
210 
211  template <typename T>
212  static ASIO_CONSTEXPR
214  static_query(
215  typename enable_if<
217  T, blocking_adaptation_t>::is_valid
220  >::type* = 0) ASIO_NOEXCEPT
221  {
223  }
224 
225  template <typename T>
226  static ASIO_CONSTEXPR
228  static_query(
229  typename enable_if<
231  T, blocking_adaptation_t>::is_valid
235  >::type* = 0) ASIO_NOEXCEPT
236  {
238  }
239 
240  template <typename E,
241  typename T = decltype(blocking_adaptation_t::static_query<E>())>
242  static ASIO_CONSTEXPR const T static_query_v
243  = blocking_adaptation_t::static_query<E>();
244 #endif // defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT)
245  // && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)
246 
247  friend ASIO_CONSTEXPR bool operator==(
248  const blocking_adaptation_t& a, const blocking_adaptation_t& b)
249  {
250  return a.value_ == b.value_;
251  }
252 
253  friend ASIO_CONSTEXPR bool operator!=(
254  const blocking_adaptation_t& a, const blocking_adaptation_t& b)
255  {
256  return a.value_ != b.value_;
257  }
258 
260  {
262  blocking_adaptation_t)
263  {
264  }
265  };
266 
267  template <typename Executor>
268  friend ASIO_CONSTEXPR blocking_adaptation_t query(
269  const Executor& ex, convertible_from_blocking_adaptation_t,
270  typename enable_if<
272  >::type* = 0)
273 #if !defined(__clang__) // Clang crashes if noexcept is used here.
274 #if defined(ASIO_MSVC) // Visual C++ wants the type to be qualified.
275  ASIO_NOEXCEPT_IF((
276  is_nothrow_query<const Executor&,
278 #else // defined(ASIO_MSVC)
279  ASIO_NOEXCEPT_IF((
281 #endif // defined(ASIO_MSVC)
282 #endif // !defined(__clang__)
283  {
284  return asio::query(ex, disallowed_t());
285  }
286 
287  template <typename Executor>
288  friend ASIO_CONSTEXPR blocking_adaptation_t query(
289  const Executor& ex, convertible_from_blocking_adaptation_t,
290  typename enable_if<
293  >::type* = 0)
294 #if !defined(__clang__) // Clang crashes if noexcept is used here.
295 #if defined(ASIO_MSVC) // Visual C++ wants the type to be qualified.
296  ASIO_NOEXCEPT_IF((
297  is_nothrow_query<const Executor&,
299 #else // defined(ASIO_MSVC)
300  ASIO_NOEXCEPT_IF((
302 #endif // defined(ASIO_MSVC)
303 #endif // !defined(__clang__)
304  {
305  return asio::query(ex, allowed_t());
306  }
307 
308  ASIO_STATIC_CONSTEXPR_DEFAULT_INIT(disallowed_t, disallowed);
309  ASIO_STATIC_CONSTEXPR_DEFAULT_INIT(allowed_t, allowed);
310 
311 #if !defined(ASIO_HAS_CONSTEXPR)
312  static const blocking_adaptation_t instance;
313 #endif // !defined(ASIO_HAS_CONSTEXPR)
314 
315 private:
316  int value_;
317 };
318 
319 #if defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \
320  && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)
321 template <int I> template <typename E, typename T>
323 #endif // defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT)
324  // && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)
325 
326 #if !defined(ASIO_HAS_CONSTEXPR)
327 template <int I>
329 #endif
330 
331 template <int I>
334 
335 template <int I>
338 
339 namespace blocking_adaptation {
340 
341 template <int I = 0>
342 struct disallowed_t
343 {
344 #if defined(ASIO_HAS_VARIABLE_TEMPLATES)
345  template <typename T>
346  ASIO_STATIC_CONSTEXPR(bool,
347  is_applicable_property_v = is_executor<T>::value
349 #endif // defined(ASIO_HAS_VARIABLE_TEMPLATES)
350 
351  ASIO_STATIC_CONSTEXPR(bool, is_requirable = true);
352  ASIO_STATIC_CONSTEXPR(bool, is_preferable = true);
354 
355  ASIO_CONSTEXPR disallowed_t()
356  {
357  }
358 
359 #if defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \
360  && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)
361  template <typename T>
362  static ASIO_CONSTEXPR
364  static_query()
365  ASIO_NOEXCEPT_IF((
367  {
369  }
370 
371  template <typename T>
372  static ASIO_CONSTEXPR disallowed_t static_query(
373  typename enable_if<
377  && !can_query<T, allowed_t<I> >::value
378  >::type* = 0) ASIO_NOEXCEPT
379  {
380  return disallowed_t();
381  }
382 
383  template <typename E, typename T = decltype(disallowed_t::static_query<E>())>
384  static ASIO_CONSTEXPR const T static_query_v
385  = disallowed_t::static_query<E>();
386 #endif // defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT)
387  // && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)
388 
389  static ASIO_CONSTEXPR blocking_adaptation_t<I> value()
390  {
391  return disallowed_t();
392  }
393 
394  friend ASIO_CONSTEXPR bool operator==(
395  const disallowed_t&, const disallowed_t&)
396  {
397  return true;
398  }
399 
400  friend ASIO_CONSTEXPR bool operator!=(
401  const disallowed_t&, const disallowed_t&)
402  {
403  return false;
404  }
405 };
406 
407 #if defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \
408  && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)
409 template <int I> template <typename E, typename T>
411 #endif // defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT)
412  // && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)
413 
414 template <typename Executor>
415 class adapter
416 {
417 public:
418  adapter(int, const Executor& e) ASIO_NOEXCEPT
419  : executor_(e)
420  {
421  }
422 
423  adapter(const adapter& other) ASIO_NOEXCEPT
424  : executor_(other.executor_)
425  {
426  }
427 
428 #if defined(ASIO_HAS_MOVE)
429  adapter(adapter&& other) ASIO_NOEXCEPT
430  : executor_(ASIO_MOVE_CAST(Executor)(other.executor_))
431  {
432  }
433 #endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
434 
435  template <int I>
436  static ASIO_CONSTEXPR allowed_t<I> query(
437  blocking_adaptation_t<I>) ASIO_NOEXCEPT
438  {
439  return allowed_t<I>();
440  }
441 
442  template <int I>
443  static ASIO_CONSTEXPR allowed_t<I> query(
444  allowed_t<I>) ASIO_NOEXCEPT
445  {
446  return allowed_t<I>();
447  }
448 
449  template <int I>
450  static ASIO_CONSTEXPR allowed_t<I> query(
451  disallowed_t<I>) ASIO_NOEXCEPT
452  {
453  return allowed_t<I>();
454  }
455 
456  template <typename Property>
457  typename enable_if<
459  typename query_result<const Executor&, Property>::type
460  >::type query(const Property& p) const
461  ASIO_NOEXCEPT_IF((
463  {
464  return asio::query(executor_, p);
465  }
466 
467  template <int I>
468  Executor require(disallowed_t<I>) const ASIO_NOEXCEPT
469  {
470  return executor_;
471  }
472 
473  template <typename Property>
474  typename enable_if<
476  adapter<typename decay<
477  typename require_result<const Executor&, Property>::type
478  >::type>
479  >::type require(const Property& p) const
480  ASIO_NOEXCEPT_IF((
482  {
483  return adapter<typename decay<
484  typename require_result<const Executor&, Property>::type
485  >::type>(0, asio::require(executor_, p));
486  }
487 
488  template <typename Property>
489  typename enable_if<
491  adapter<typename decay<
492  typename prefer_result<const Executor&, Property>::type
493  >::type>
494  >::type prefer(const Property& p) const
495  ASIO_NOEXCEPT_IF((
497  {
498  return adapter<typename decay<
499  typename prefer_result<const Executor&, Property>::type
500  >::type>(0, asio::prefer(executor_, p));
501  }
502 
503  template <typename Function>
504  typename enable_if<
506  >::type execute(ASIO_MOVE_ARG(Function) f) const
507  {
508  execution::execute(executor_, ASIO_MOVE_CAST(Function)(f));
509  }
510 
511  friend bool operator==(const adapter& a, const adapter& b) ASIO_NOEXCEPT
512  {
513  return a.executor_ == b.executor_;
514  }
515 
516  friend bool operator!=(const adapter& a, const adapter& b) ASIO_NOEXCEPT
517  {
518  return a.executor_ != b.executor_;
519  }
520 
521 private:
522  Executor executor_;
523 };
524 
525 template <int I = 0>
526 struct allowed_t
527 {
528 #if defined(ASIO_HAS_VARIABLE_TEMPLATES)
529  template <typename T>
530  ASIO_STATIC_CONSTEXPR(bool,
531  is_applicable_property_v = is_executor<T>::value
533 #endif // defined(ASIO_HAS_VARIABLE_TEMPLATES)
534 
535  ASIO_STATIC_CONSTEXPR(bool, is_requirable = true);
536  ASIO_STATIC_CONSTEXPR(bool, is_preferable = false);
537  typedef blocking_adaptation_t<I> polymorphic_query_result_type;
538 
539  ASIO_CONSTEXPR allowed_t()
540  {
541  }
542 
543 #if defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \
544  && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)
545  template <typename T>
546  static ASIO_CONSTEXPR
548  static_query()
549  ASIO_NOEXCEPT_IF((
551  {
553  }
554 
555  template <typename E, typename T = decltype(allowed_t::static_query<E>())>
556  static ASIO_CONSTEXPR const T static_query_v
557  = allowed_t::static_query<E>();
558 #endif // defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT)
559  // && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)
560 
561  static ASIO_CONSTEXPR blocking_adaptation_t<I> value()
562  {
563  return allowed_t();
564  }
565 
566  friend ASIO_CONSTEXPR bool operator==(
567  const allowed_t&, const allowed_t&)
568  {
569  return true;
570  }
571 
572  friend ASIO_CONSTEXPR bool operator!=(
573  const allowed_t&, const allowed_t&)
574  {
575  return false;
576  }
577 
578  template <typename Executor>
579  friend adapter<Executor> require(
580  const Executor& e, const allowed_t&,
581  typename enable_if<
583  >::type* = 0)
584  {
585  return adapter<Executor>(0, e);
586  }
587 };
588 
589 #if defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \
590  && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)
591 template <int I> template <typename E, typename T>
593 #endif // defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT)
594  // && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)
595 
596 template <typename Function>
598 {
599 public:
600  template <typename F>
601  blocking_execute_state(ASIO_MOVE_ARG(F) f)
602  : func_(ASIO_MOVE_CAST(F)(f)),
603  is_complete_(false)
604  {
605  }
606 
607  template <typename Executor>
608  void execute_and_wait(ASIO_MOVE_ARG(Executor) ex)
609  {
610  handler h = { this };
611  execution::execute(ASIO_MOVE_CAST(Executor)(ex), h);
613  while (!is_complete_)
614  event_.wait(lock);
615  }
616 
617  struct cleanup
618  {
619  ~cleanup()
620  {
621  asio::detail::mutex::scoped_lock lock(state_->mutex_);
622  state_->is_complete_ = true;
623  state_->event_.unlock_and_signal_one_for_destruction(lock);
624  }
625 
626  blocking_execute_state* state_;
627  };
628 
629  struct handler
630  {
631  void operator()()
632  {
633  cleanup c = { state_ };
634  state_->func_();
635  }
636 
637  blocking_execute_state* state_;
638  };
639 
640  Function func_;
641  asio::detail::mutex mutex_;
642  asio::detail::event event_;
643  bool is_complete_;
644 };
645 
646 template <typename Executor, typename Function>
647 void blocking_execute(
648  ASIO_MOVE_ARG(Executor) ex,
649  ASIO_MOVE_ARG(Function) func)
650 {
651  typedef typename decay<Function>::type func_t;
652  blocking_execute_state<func_t> state(ASIO_MOVE_CAST(Function)(func));
653  state.execute_and_wait(ex);
654 }
655 
656 } // namespace blocking_adaptation
657 } // namespace detail
658 
660 
661 #if defined(ASIO_HAS_CONSTEXPR) || defined(GENERATING_DOCUMENTATION)
662 constexpr blocking_adaptation_t blocking_adaptation;
663 #else // defined(ASIO_HAS_CONSTEXPR) || defined(GENERATING_DOCUMENTATION)
664 namespace { static const blocking_adaptation_t&
665  blocking_adaptation = blocking_adaptation_t::instance; }
666 #endif
667 
668 } // namespace execution
669 
670 #if !defined(ASIO_HAS_VARIABLE_TEMPLATES)
671 
672 template <typename T>
673 struct is_applicable_property<T, execution::blocking_adaptation_t>
674  : integral_constant<bool,
675  execution::is_executor<T>::value
676  || execution::is_sender<T>::value
677  || execution::is_scheduler<T>::value>
678 {
679 };
680 
681 template <typename T>
682 struct is_applicable_property<T, execution::blocking_adaptation_t::disallowed_t>
683  : integral_constant<bool,
684  execution::is_executor<T>::value
685  || execution::is_sender<T>::value
686  || execution::is_scheduler<T>::value>
687 {
688 };
689 
690 template <typename T>
691 struct is_applicable_property<T, execution::blocking_adaptation_t::allowed_t>
692  : integral_constant<bool,
693  execution::is_executor<T>::value
694  || execution::is_sender<T>::value
695  || execution::is_scheduler<T>::value>
696 {
697 };
698 
699 #endif // !defined(ASIO_HAS_VARIABLE_TEMPLATES)
700 
701 namespace traits {
702 
703 #if !defined(ASIO_HAS_DEDUCED_QUERY_FREE_TRAIT)
704 
705 template <typename T>
706 struct query_free_default<T, execution::blocking_adaptation_t,
707  typename enable_if<
708  can_query<T, execution::blocking_adaptation_t::disallowed_t>::value
709  >::type>
710 {
711  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
712  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = (is_nothrow_query<T,
714 
716 };
717 
718 template <typename T>
719 struct query_free_default<T, execution::blocking_adaptation_t,
720  typename enable_if<
721  !can_query<T, execution::blocking_adaptation_t::disallowed_t>::value
722  && can_query<T, execution::blocking_adaptation_t::allowed_t>::value
723  >::type>
724 {
725  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
726  ASIO_STATIC_CONSTEXPR(bool, is_noexcept =
728 
730 };
731 
732 #endif // !defined(ASIO_HAS_DEDUCED_QUERY_FREE_TRAIT)
733 
734 #if !defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \
735  || !defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)
736 
737 template <typename T>
738 struct static_query<T, execution::blocking_adaptation_t,
739  typename enable_if<
740  traits::query_static_constexpr_member<T,
741  execution::blocking_adaptation_t>::is_valid
742  >::type>
743 {
744  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
745  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);
746 
747  typedef typename traits::query_static_constexpr_member<T,
748  execution::blocking_adaptation_t>::result_type result_type;
749 
750  static ASIO_CONSTEXPR result_type value()
751  {
754  }
755 };
756 
757 template <typename T>
758 struct static_query<T, execution::blocking_adaptation_t,
759  typename enable_if<
760  !traits::query_static_constexpr_member<T,
761  execution::blocking_adaptation_t>::is_valid
762  && !traits::query_member<T,
763  execution::blocking_adaptation_t>::is_valid
764  && traits::static_query<T,
765  execution::blocking_adaptation_t::disallowed_t>::is_valid
766  >::type>
767 {
768  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
769  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);
770 
771  typedef typename traits::static_query<T,
772  execution::blocking_adaptation_t::disallowed_t>::result_type result_type;
773 
774  static ASIO_CONSTEXPR result_type value()
775  {
776  return traits::static_query<T,
778  }
779 };
780 
781 template <typename T>
782 struct static_query<T, execution::blocking_adaptation_t,
783  typename enable_if<
784  !traits::query_static_constexpr_member<T,
785  execution::blocking_adaptation_t>::is_valid
786  && !traits::query_member<T,
787  execution::blocking_adaptation_t>::is_valid
788  && !traits::static_query<T,
789  execution::blocking_adaptation_t::disallowed_t>::is_valid
790  && traits::static_query<T,
791  execution::blocking_adaptation_t::allowed_t>::is_valid
792  >::type>
793 {
794  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
795  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);
796 
797  typedef typename traits::static_query<T,
798  execution::blocking_adaptation_t::allowed_t>::result_type result_type;
799 
800  static ASIO_CONSTEXPR result_type value()
801  {
802  return traits::static_query<T,
804  }
805 };
806 
807 template <typename T>
808 struct static_query<T, execution::blocking_adaptation_t::disallowed_t,
809  typename enable_if<
810  traits::query_static_constexpr_member<T,
811  execution::blocking_adaptation_t::disallowed_t>::is_valid
812  >::type>
813 {
814  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
815  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);
816 
817  typedef typename traits::query_static_constexpr_member<T,
818  execution::blocking_adaptation_t::disallowed_t>::result_type result_type;
819 
820  static ASIO_CONSTEXPR result_type value()
821  {
824  }
825 };
826 
827 template <typename T>
828 struct static_query<T, execution::blocking_adaptation_t::disallowed_t,
829  typename enable_if<
830  !traits::query_static_constexpr_member<T,
831  execution::blocking_adaptation_t::disallowed_t>::is_valid
832  && !traits::query_member<T,
833  execution::blocking_adaptation_t::disallowed_t>::is_valid
834  && !traits::query_free<T,
835  execution::blocking_adaptation_t::disallowed_t>::is_valid
836  && !can_query<T, execution::blocking_adaptation_t::allowed_t>::value
837  >::type>
838 {
839  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
840  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);
841 
843 
844  static ASIO_CONSTEXPR result_type value()
845  {
846  return result_type();
847  }
848 };
849 
850 template <typename T>
851 struct static_query<T, execution::blocking_adaptation_t::allowed_t,
852  typename enable_if<
853  traits::query_static_constexpr_member<T,
854  execution::blocking_adaptation_t::allowed_t>::is_valid
855  >::type>
856 {
857  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
858  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);
859 
860  typedef typename traits::query_static_constexpr_member<T,
861  execution::blocking_adaptation_t::allowed_t>::result_type result_type;
862 
863  static ASIO_CONSTEXPR result_type value()
864  {
867  }
868 };
869 
870 #endif // !defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT)
871  // || !defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)
872 
873 #if !defined(ASIO_HAS_DEDUCED_STATIC_REQUIRE_TRAIT)
874 
875 template <typename T>
876 struct static_require<T, execution::blocking_adaptation_t::disallowed_t,
877  typename enable_if<
878  static_query<T, execution::blocking_adaptation_t::disallowed_t>::is_valid
879  >::type>
880 {
881  ASIO_STATIC_CONSTEXPR(bool, is_valid =
882  (is_same<typename static_query<T,
885 };
886 
887 template <typename T>
888 struct static_require<T, execution::blocking_adaptation_t::allowed_t,
889  typename enable_if<
890  static_query<T, execution::blocking_adaptation_t::allowed_t>::is_valid
891  >::type>
892 {
893  ASIO_STATIC_CONSTEXPR(bool, is_valid =
894  (is_same<typename static_query<T,
897 };
898 
899 #endif // !defined(ASIO_HAS_DEDUCED_STATIC_REQUIRE_TRAIT)
900 
901 #if !defined(ASIO_HAS_DEDUCED_REQUIRE_FREE_TRAIT)
902 
903 template <typename T>
904 struct require_free_default<T, execution::blocking_adaptation_t::allowed_t,
905  typename enable_if<
906  is_same<T, typename decay<T>::type>::value
907  && execution::is_executor<T>::value
908  >::type>
909 {
910  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
911  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);
913 };
914 
915 #endif // !defined(ASIO_HAS_DEDUCED_REQUIRE_FREE_TRAIT)
916 
917 #if !defined(ASIO_HAS_DEDUCED_EQUALITY_COMPARABLE_TRAIT)
918 
919 template <typename Executor>
921  execution::detail::blocking_adaptation::adapter<Executor> >
922 {
923  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
924  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);
925 };
926 
927 #endif // !defined(ASIO_HAS_DEDUCED_EQUALITY_COMPARABLE_TRAIT)
928 
929 #if !defined(ASIO_HAS_DEDUCED_EXECUTE_MEMBER_TRAIT)
930 
931 template <typename Executor, typename Function>
933  execution::detail::blocking_adaptation::adapter<Executor>, Function>
934 {
935  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
936  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);
937  typedef void result_type;
938 };
939 
940 #endif // !defined(ASIO_HAS_DEDUCED_EXECUTE_MEMBER_TRAIT)
941 
942 #if !defined(ASIO_HAS_DEDUCED_QUERY_STATIC_CONSTEXPR_MEMBER_TRAIT)
943 
944 template <typename Executor, int I>
946  execution::detail::blocking_adaptation::adapter<Executor>,
948 {
949  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
950  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);
952 
953  static ASIO_CONSTEXPR result_type value() ASIO_NOEXCEPT
954  {
955  return result_type();
956  }
957 };
958 
959 template <typename Executor, int I>
961  execution::detail::blocking_adaptation::adapter<Executor>,
963 {
964  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
965  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);
967 
968  static ASIO_CONSTEXPR result_type value() ASIO_NOEXCEPT
969  {
970  return result_type();
971  }
972 };
973 
974 template <typename Executor, int I>
976  execution::detail::blocking_adaptation::adapter<Executor>,
978 {
979  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
980  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);
982 
983  static ASIO_CONSTEXPR result_type value() ASIO_NOEXCEPT
984  {
985  return result_type();
986  }
987 };
988 
989 #endif // !defined(ASIO_HAS_DEDUCED_QUERY_STATIC_CONSTEXPR_MEMBER_TRAIT)
990 
991 #if !defined(ASIO_HAS_DEDUCED_QUERY_MEMBER_TRAIT)
992 
993 template <typename Executor, typename Property>
995  execution::detail::blocking_adaptation::adapter<Executor>, Property,
996  typename enable_if<
997  can_query<const Executor&, Property>::value
998  >::type>
999 {
1000  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
1001  ASIO_STATIC_CONSTEXPR(bool, is_noexcept =
1003  typedef typename query_result<Executor, Property>::type result_type;
1004 };
1005 
1006 #endif // !defined(ASIO_HAS_DEDUCED_QUERY_MEMBER_TRAIT)
1007 
1008 #if !defined(ASIO_HAS_DEDUCED_REQUIRE_MEMBER_TRAIT)
1009 
1010 template <typename Executor, int I>
1012  execution::detail::blocking_adaptation::adapter<Executor>,
1014 {
1015  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
1016  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);
1017  typedef Executor result_type;
1018 };
1019 
1020 template <typename Executor, typename Property>
1022  execution::detail::blocking_adaptation::adapter<Executor>, Property,
1023  typename enable_if<
1024  can_require<const Executor&, Property>::value
1025  >::type>
1026 {
1027  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
1028  ASIO_STATIC_CONSTEXPR(bool, is_noexcept =
1030  typedef execution::detail::blocking_adaptation::adapter<typename decay<
1031  typename require_result<Executor, Property>::type
1032  >::type> result_type;
1033 };
1034 
1035 #endif // !defined(ASIO_HAS_DEDUCED_REQUIRE_MEMBER_TRAIT)
1036 
1037 #if !defined(ASIO_HAS_DEDUCED_PREFER_MEMBER_TRAIT)
1038 
1039 template <typename Executor, typename Property>
1041  execution::detail::blocking_adaptation::adapter<Executor>, Property,
1042  typename enable_if<
1043  can_prefer<const Executor&, Property>::value
1044  >::type>
1045 {
1046  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
1047  ASIO_STATIC_CONSTEXPR(bool, is_noexcept =
1049  typedef execution::detail::blocking_adaptation::adapter<typename decay<
1050  typename prefer_result<Executor, Property>::type
1051  >::type> result_type;
1052 };
1053 
1054 #endif // !defined(ASIO_HAS_DEDUCED_PREFER_MEMBER_TRAIT)
1055 
1056 } // namespace traits
1057 
1058 #endif // defined(GENERATING_DOCUMENTATION)
1059 
1060 } // namespace asio
1061 
1062 #include "asio/detail/pop_options.hpp"
1063 
1064 #endif // ASIO_EXECUTION_BLOCKING_ADAPTATION_HPP
Definition: static_require.hpp:37
Definition: prefer.hpp:574
Definition: null_mutex.hpp:30
Definition: any_executor.hpp:249
Definition: scoped_lock.hpp:27
Definition: blocking_adaptation.hpp:415
Definition: prefer_member.hpp:38
Definition: blocking_adaptation.hpp:158
Definition: require_free.hpp:35
Definition: query.hpp:269
Definition: blocking_adaptation.hpp:164
The is_scheduler trait detects whether a type T satisfies the execution::scheduler concept...
Definition: scheduler.hpp:48
The is_sender trait detects whether a type T satisfies the execution::sender concept.
Definition: sender.hpp:183
Definition: execute.hpp:243
Definition: query_member.hpp:38
Definition: static_query.hpp:42
Definition: execute_member.hpp:38
Definition: chrono.h:284
Definition: require.hpp:442
Definition: type_traits.hpp:97
Definition: require_member.hpp:38
Definition: query.hpp:253
Definition: require.hpp:390
Definition: query_free.hpp:35
Definition: null_event.hpp:26
Definition: query_free.hpp:38
Definition: query_static_constexpr_member.hpp:42
Definition: any_executor.hpp:256
Definition: handler_work.hpp:37
Definition: prefer.hpp:522
Definition: is_applicable_property.hpp:46
Definition: any_io_executor.hpp:28
Definition: equality_comparable.hpp:36
The is_executor trait detects whether a type T satisfies the execution::executor concept.
Definition: executor.hpp:109