| 468 | |
| 469 | template <typename Signatures, typename Receiver, typename Executor> |
| 470 | class executor |
| 471 | { |
| 472 | operation_state_base<Signatures, Receiver>& self_; |
| 473 | Executor ex_; |
| 474 | |
| 475 | template <typename F> |
| 476 | constexpr auto wrap_(F f) const noexcept(std::is_nothrow_move_constructible_v<F>) |
| 477 | { |
| 478 | return [&self = self_, f = std::move(f)]() mutable noexcept |
| 479 | { |
| 480 | self.run_(std::move(f)); |
| 481 | }; |
| 482 | } |
| 483 | public: |
| 484 | constexpr explicit executor(operation_state_base<Signatures, Receiver>& self, |
| 485 | Executor const & ex) noexcept |
| 486 | : self_(self) |
| 487 | , ex_(ex) |
| 488 | {} |
| 489 | |
| 490 | template <typename Query> |
| 491 | requires requires { |
| 492 | asio_impl::query(std::declval<Executor const &>(), std::declval<Query const &>()); |
| 493 | } |
| 494 | constexpr decltype(auto) query(Query const & q) const noexcept |
| 495 | { |
| 496 | return asio_impl::query(ex_, q); |
| 497 | } |
| 498 | |
| 499 | template <typename... Args> |
| 500 | requires requires { |
| 501 | asio_impl::prefer(std::declval<Executor const &>(), std::declval<Args>()...); |
| 502 | } |
| 503 | constexpr decltype(auto) prefer(Args&&... args) const noexcept |
| 504 | { |
| 505 | auto const ex = asio_impl::prefer(ex_, static_cast<Args&&>(args)...); |
| 506 | return executor<Signatures, Receiver, std::remove_cvref_t<decltype(ex)>>(self_, ex); |
| 507 | } |
| 508 | |
| 509 | template <typename... Args> |
| 510 | requires requires { |
| 511 | asio_impl::require(std::declval<Executor const &>(), std::declval<Args>()...); |
| 512 | } |
| 513 | constexpr decltype(auto) require(Args&&... args) const noexcept |
| 514 | { |
| 515 | auto const ex = asio_impl::require(ex_, static_cast<Args&&>(args)...); |
| 516 | return executor<Signatures, Receiver, std::remove_cvref_t<decltype(ex)>>(self_, ex); |
| 517 | } |
| 518 | |
| 519 | template <typename T> |
| 520 | void execute(T&& t) const noexcept |
| 521 | { |
| 522 | self_.run_([&]() { ex_.execute(wrap_(static_cast<T&&>(t))); }); |
| 523 | } |
| 524 | |
| 525 | constexpr void on_work_started() const noexcept |
| 526 | requires requires { std::declval<Executor const &>().on_work_started(); } |
| 527 | { |