namespace std::execution {
struct schedule_from_t { unspecified };
inline constexpr schedule_from_t schedule_from{};
}
概要
schedule_from
は、Senderの完了に依存する作業をSchedulerに関連付けられた実行リソースにスケジュールするSenderアダプタである。
schedule_from
はユーザコードで利用されるものではなく、continues_on
Senderアルゴリズムの実装において利用される。
効果
説明用の式sch
とsndr
に対して、decltype((sch))
がscheduler
を満たさない、もしくはdecltype((sndr))
がsender
を満たさないとき、呼び出し式schedule_from(sch, sndr)
は不適格となる。
そうでなければ、呼び出し式schedule_from(sch, sndr)
はsch
が1回だけ評価されることを除いて、下記と等価。
transform_sender(
query-with-default(get_domain, sch, default_domain()),
make-sender(schedule_from, sch, sndr))
Senderアルゴリズムタグ schedule_from
Senderアルゴリズム動作説明用のクラステンプレートimpls-for
に対して、下記の特殊化が定義される。
namespace std::execution {
template<>
struct impls-for<schedule_from_t> : default-impls {
static constexpr auto get-attrs = see below;
static constexpr auto get-state = see below;
static constexpr auto complete = see below;
};
}
impls-for<schedule_from_t>::get-attrs
メンバは、下記ラムダ式と等価な関数呼び出し可能なオブジェクトで初期化される。
[](const auto& data, const auto& child) noexcept -> decltype(auto) {
return JOIN-ENV(SCHED-ATTRS(data), FWD-ENV(get_env(child)));
}
impls-for<schedule_from_t>::get-state
メンバは、下記ラムダ式と等価な関数呼び出し可能なオブジェクトで初期化される。
[]<class Sndr, class Rcvr>(Sndr&& sndr, Rcvr& rcvr) noexcept(see below)
requires sender_in<child-type<Sndr>, env_of_t<Rcvr>> {
auto& [_, sch, child] = sndr;
using sched_t = decltype(auto(sch));
using variant_t = see below;
using receiver_t = see below;
using operation_t = connect_result_t<schedule_result_t<sched_t>, receiver_t>;
constexpr bool nothrow = noexcept(connect(schedule(sch), receiver_t{nullptr}));
struct state-type {
Rcvr& rcvr; // exposition only
variant_t async-result; // exposition only
operation_t op-state; // exposition only
explicit state-type(sched_t sch, Rcvr& rcvr) noexcept(nothrow)
: rcvr(rcvr), op-state(connect(schedule(sch), receiver_t{this})) {}
};
return state-type{sch, rcvr};
}
- ローカルクラス
state-type
のオブジェクトは構造化束縛における初期化子として利用できる。 -
説明用のパック
Sigs
をcompletion_signatures_of_t<child-type<Sndr>, env_of_t<Rcvr>>
によるcompletion_signatures
特殊化のテンプレートパラメータと定義する。説明用のエイリアステンプレートas-tuple<Tag(Args...)>
をdecayed-tuple<Args...>
と定義する。型variant_t
は下記定義において重複削除した型となる。 -
receiver_t
は説明専用クラスreceiver-type
のエイリアスとする。
impls-for<schedule_from_t>::complete
メンバは、下記ラムダ式と等価な関数呼び出し可能なオブジェクトで初期化される。
[]<class Tag, class... Args>(auto, auto& state, auto& rcvr, Tag, Args&&... args) noexcept
-> void {
using result_t = decayed-tuple<Tag, Args...>;
constexpr bool nothrow = is_nothrow_constructible_v<result_t, Tag, Args...>;
try {
state.async-result.template emplace<result_t>(Tag(), std::forward<Args>(args)...);
} catch (...) {
if constexpr (!nothrow) {
set_error(std::move(rcvr), current_exception());
return;
}
}
start(state.op-state);
};
説明専用エンティティ
説明専用のクラスreceiver-type
を下記の通り定義する。
namespace std::execution {
struct receiver-type {
using receiver_concept = receiver_t;
state-type* state; // exposition only
void set_value() && noexcept {
visit(
[this]<class Tuple>(Tuple& result) noexcept -> void {
if constexpr (!same_as<monostate, Tuple>) {
auto& [tag, ...args] = result;
tag(std::move(state->rcvr), std::move(args)...);
}
},
state->async-result);
}
template<class Error>
void set_error(Error&& err) && noexcept {
execution::set_error(std::move(state->rcvr), std::forward<Error>(err));
}
void set_stopped() && noexcept {
execution::set_stopped(std::move(state->rcvr));
}
decltype(auto) get_env() const noexcept {
return FWD-ENV(execution::get_env(state->rcvr));
}
};
}
カスタマイゼーションポイント
Senderアルゴリズム構築時およびReceiver接続時に、関連付けられた実行ドメインに対してexecution::transform_sender
経由でSender変換が行われる。
デフォルト実行ドメインでは無変換。
説明用の式out_sndr
をschedule_from(sndr, sch)
の戻り値Senderとし、型OutSndr
をdecltype((out_sndr))
とする。式out_rcvr
をsender_in<OutSndr, Env> == true
となる環境Env
に関連付けられたReceiverとする。out_sndr
とout_rcvr
との接続(connect)結果Operation Stateへの左辺値参照をop
としたとき、
- 呼び出し
start(op)
は、現在の実行エージェント上で入力Sendersndr
を開始し、Schedulersch
に関連付けられた実行リソースに属する実行エージェント上でout_rcvr
の完了操作を実行すべき。 sch
上でのスケジューリングが失敗した場合、未規定の実行エージェント上でout_rcvr
のエラー完了が行われるべき。
バージョン
言語
- C++26
処理系
- Clang: ??
- GCC: ??
- ICC: ??
- Visual C++: ??