9.0 KiB
[exec.scope.simple.counting]
33 Execution control library [exec]
33.14 Execution scope utilities [exec.scope]
33.14.2 Counting Scopes [exec.counting.scopes]
33.14.2.2 Simple Counting Scope [exec.scope.simple.counting]
33.14.2.2.1 General [exec.scope.simple.counting.general]
namespace std::execution {class simple_counting_scope {public:// [exec.simple.counting.token], tokenstruct token; static constexpr size_t max_associations = implementation-defined; // [exec.simple.counting.ctor], constructor and destructor simple_counting_scope() noexcept; simple_counting_scope(simple_counting_scope&&) = delete; ~simple_counting_scope(); // [exec.simple.counting.mem], members token get_token() noexcept; void close() noexcept; sender auto join() noexcept; private: size_t count; // exposition only**scope-state-type state; // exposition onlybool try-associate() noexcept; // exposition onlyvoid disassociate() noexcept; // exposition onlytemplatebool start-join-sender(State& state) noexcept; // exposition only};}
For purposes of determining the existence of a data race,get_token,close,join,try-associate,disassociate, andstart-join-sender behave as atomic operations ([intro.multithread]).
These operations on a single object of type simple_counting_scope appear to occur in a single total order.
33.14.2.2.2 Constructor and Destructor [exec.simple.counting.ctor]
simple_counting_scope() noexcept;
Postconditions: count is 0 and state is unused.
~simple_counting_scope();
Effects: If state is not one ofjoined, unused, or unused-and-closed, invokes terminate ([except.terminate]).
Otherwise, has no effects.
33.14.2.2.3 Members [exec.simple.counting.mem]
token get_token() noexcept;
Returns: An object t of type simple_counting_scope::token such thatt.scope == this is true.
void close() noexcept;
Effects: If state is
unused, then changes state to unused-and-closed;
open, then changes state to closed;
open-and-joining, then changes state to closed-and-joining;
otherwise, no effects.
Postconditions: Any subsequent call to try-associate() on *this returns false.
[sender](exec.snd.concepts#concept:sender "33.9.3 Sender concepts [exec.snd.concepts]") auto join() noexcept;
Returns: make-sender(scope-join-t(), this).
bool try-associate() noexcept;
Effects: If count is equal to max_associations, then no effects.
Otherwise, if state is
unused, then increments count and changes state to open;
open or open-and-joining, then increments count;
otherwise, no effects.
Returns: true if count was incremented, false otherwise.
void disassociate() noexcept;
Preconditions: count is greater than zero.
Effects: Decrements count.
If count is zero after decrementing andstate is open-and-joining or closed-and-joining, changes state to joined and calls complete() on all objects registered with *this.
[Note 1:
Calling complete() on any registered object can cause *this to be destroyed.
â end note]
template<class State> bool start-join-sender(State& st) noexcept;
Effects: If state is
unused, unused-and-closed, or joined, then changes state to joined and returns true;
open or open-and-joining, then changes state to open-and-joining, registers st with *this and returns false;
closed or closed-and-joining, then changes state to closed-and-joining, registers st with *this and returns false.
33.14.2.2.4 Token [exec.simple.counting.token]
namespace std::execution {struct simple_counting_scope::token {template<sender Sender> Sender&& wrap(Sender&& snd) const noexcept; bool try_associate() const noexcept; void disassociate() const noexcept; private: simple_counting_scope* scope; // exposition only};}
template<[sender](exec.snd.concepts#concept:sender "33.9.3 Sender concepts [exec.snd.concepts]") Sender> Sender&& wrap(Sender&& snd) const noexcept;
Returns: std::forward(snd).
bool try_associate() const noexcept;
Effects: Equivalent to: return scope->try-associate();
void disassociate() const noexcept;
Effects: Equivalent to scope->disassociate().