namespace std::execution {
template<class CPO>
struct get_completion_scheduler_t { unspecified };
template<class CPO>
constexpr get_completion_scheduler_t<CPO> get_completion_scheduler{};
}
概要
get_completion_scheduler<completion-tag>は、Senderの属性から指定完了タグに関連付けられた完了Schedulerを取得するクエリオブジェクトである。
コア定数式forwarding_query(get_completion_scheduler<completion-tag>)はtrue値を返す。
完了Scheduler
完了Scheduler(completion scheduler)は、非同期操作の完了操作を実行するための実行リソース(例:CPUスレッド)と関連付けられたSchedulerである。
非同期操作の完了操作は、下記いずれかの完了関数呼び出しが該当する。
- 値完了関数
execution::set_value - エラー完了関数
execution::set_error - 停止完了関数
execution::set_stopped
効果
completion-fnを完了関数、completion-tagを完了関数に関連付けられた完了タグ、argsとenvsを部分式のパック、式sndrをsender<decltype((sndr))>がtrueかつget_completion_scheduler<completion-tag>(get_env(sndr), envs...)となる式、schをSchedulerとする。
式sch1とパックenvsに対して、式sch2をTRY-QUERY(sch, get_completion_scheduler<completion-tag>, envs...)とする。sch2が不適格もしくはsch1とsch2が同一型かつ等しいとき、式RECURSE-QUERY(sch1, envs...)をsch1と等価な式とする。そうでなければ、式RECURSE-QUERY(sch2, envs...)と透過な式とする。
式qとパックenvsに対して、完了タグcompletion-tagがset_value_t/set_error_t/ set_stopped_tのいずれでもなければ、呼び出し式get_completion_scheduler<completion-tag>(q, envs...)は不適格となる。
そうでなければ、呼び出し式は下記と等価。
-
envs...が1回だけ評価されることを除いて、適格ならば下記の式MANDATE-NOTHROW(RECURSE-QUERY( TRY-QUERY(q, get_completion_scheduler<completion-tag>, envs...), envs...)) -
そうではなく、
envs...が1回だけ評価されることを除いて、型qがschedeulerを満たしかつenvsが空のパックでないとき、auto(q) - そうでなければ、呼び出し式
get_completion_scheduler<completion-tag>(q, envs...)は不適格となる。
get_completion_scheduler<completion-tag>(q, envs...)が適格ならば、その型はSchedulerを満たすべき。
例外
投げない
カスタマイゼーションポイント
const修飾クエリ可能オブジェクトcqに対して式cq.query(get_completion_scheduler<completion-tag>)が呼び出される。
このとき、noexcept(cq.query(get_completion_scheduler<completion-tag>)) == trueであること。
型Tag、式sndr、パックenvsに対して、CSをcompletion_signatures_of_t<decay_t<decltype((sndr))>, decltype((envs))...>とする。get_completion_scheduler<Tag>(get_env(sndr), envs...)とCSが両者とも適格、かつCS().count-of(Tag()) == 0がtrueのとき、プログラムは不適格となる。
sndrとReceiverrcvrを接続して作成された非同期操作が完了関数completion-fn(rcvr, args...)を評価するとき、その評価がschと関連付けられた実行リソースの実行エージェント上で行われない場合、動作は未定義となる。
例
#include <execution>
namespace ex = std::execution;
int main()
{
ex::run_loop loop;
ex::scheduler auto loop_sch = loop.get_scheduler();
// schedule(loop_sch)の完了Schedulerはloop_schに等しい
ex::sender auto snd0 = ex::schedule(loop_sch);
auto sch0 = ex::get_completion_scheduler<ex::set_value_t>(ex::get_env(snd0));
assert(sch0 == loop_sch);
// 完了Schedulerは接続されたSenderへと引き継がれる
ex::sender auto snd1 = snd0 | ex::then([]{ return 42; });
auto sch1 = ex::get_completion_scheduler<ex::set_value_t>(ex::get_env(snd1));
assert(sch1 == loop_sch);
#if 0
// just Senderは完了Schedulerを持たない
ex::sender auto snd2 = ex::just(42);
auto sch2 = ex::get_completion_scheduler<ex::set_value_t>(ex::get_env(snd2));
#endif
}
出力
バージョン
言語
- C++26
処理系
- Clang: ??
- GCC: ??
- ICC: ??
- Visual C++: ??
関連項目
execution::schedulerexecution::scheduleexecution::set_valueexecution::set_errorexecution::set_stopped