Files
2025-10-25 03:02:53 +03:00

5.2 KiB
Raw Permalink Blame History

[exec.counting.scopes.general]

33 Execution control library [exec]

33.14 Execution scope utilities [exec.scope]

33.14.2 Counting Scopes [exec.counting.scopes]

33.14.2.1 General [exec.counting.scopes.general]

1

#

Scopes of type simple_counting_scope and counting_scope maintain counts of associations.

Let:

Scope be either simple_counting_scope or counting_scope,

scope be an object of type Scope,

tkn be an object of type Scope::token obtained from scope.get_token(),

jsndr be a sender obtained from scope.join(), and

op be an operation state obtained from connecting jsndr to a receiver.

During its lifetime scope goes through different states which govern what operations are allowed and the result of these operations:

  • (1.6)

    unused: a newly constructed object starts in the unused state.

  • (1.7)

    open: when tkn.try_associate() is called while scope is in the unused state,scope moves to the open state.

  • (1.8)

    open-and-joining: when the operation state op is started while scope is in the unused or open state,scope moves to the open-and-joining state.

  • (1.9)

    closed: when scope.close() is called while scope is in the open state,scope moves to the closed state.

  • (1.10)

    unused-and-closed: when scope.close() is called while scope is in the unused state,scope moves to the unused-and-closed state.

  • (1.11)

    closed-and-joining: when scope.close() is called while scope is in the open-and-joining state or the operation state op is started while scope is in the closed or unused-and-closed state,scope moves to the closed-and-joining state.

  • (1.12)

    joined: when the count of associations drops to zero while scope is in the open-and-joining or closed-and-joining state,scope moves to the joined state.

2

#

Recommended practice: For simple_counting_scope and counting_scope, implementations should store the state and the count of associations in a single member of type size_t.

3

#

Subclause [exec.counting.scopes] makes use of the following exposition-only entities:

struct scope-join-t {}; // exposition onlyenum scope-state-type { // exposition only**unused, // exposition only**open, // exposition only**closed, // exposition only**open-and-joining, // exposition only**closed-and-joining, // exposition only**unused-and-closed, // exposition only**joined, // exposition only};

4

#

The exposition-only class template impls-for ([exec.snd.expos]) is specialized for scope-join-t as follows:

namespace std::execution {template<>struct impls-for<scope-join-t> : default-impls {template<class Scope, class Rcvr>struct state { // exposition onlystruct rcvr-t { // exposition onlyusing receiver_concept = receiver_t;

Rcvr& rcvr; // exposition onlyvoid set_value() && noexcept { execution::set_value(std::move(rcvr)); }templatevoid set_error(E&& e) && noexcept { execution::set_error(std::move(rcvr), std::forward(e)); }void set_stopped() && noexcept { execution::set_stopped(std::move(rcvr)); }decltype(auto) get_env() const noexcept {return execution::get_env(rcvr); }}; using sched-sender = // exposition onlydecltype(schedule(get_scheduler(get_env(declval<Rcvr&>())))); using op-t = // exposition only connect_result_t<sched-sender, rcvr-t>;

Scope* scope; // exposition only Rcvr& receiver; // exposition only**op-t op; // exposition only**state(Scope* scope, Rcvr& rcvr) // exposition onlynoexcept(nothrow-callable<connect_t, sched-sender, rcvr-t>): scope(scope), receiver(rcvr), op(connect(schedule(get_scheduler(get_env(rcvr))), rcvr-t(rcvr))) {}void complete() noexcept { // exposition only start(op); }void complete-inline() noexcept { // exposition only set_value(std::move(receiver)); }}; static constexpr auto get-state = // exposition only[](auto&& sender, Rcvr& receiver)noexcept(is_nothrow_constructible_v<state, data-type<decltype(sender)>, Rcvr&>) {auto[_, self] = sender; return state(self, receiver); }; static constexpr auto start = // exposition only[](auto& s, auto&) noexcept {if (s.scope->start-join-sender(s)) s.complete-inline(); }; };}