Init
This commit is contained in:
460
cppdraft/exec/scope.md
Normal file
460
cppdraft/exec/scope.md
Normal file
@@ -0,0 +1,460 @@
|
||||
[exec.scope]
|
||||
|
||||
# 33 Execution control library [[exec]](./#exec)
|
||||
|
||||
## 33.14 Execution scope utilities [exec.scope]
|
||||
|
||||
### [33.14.1](#concepts) Execution scope concepts [[exec.scope.concepts]](exec.scope.concepts)
|
||||
|
||||
[1](#concepts-1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/exec.tex#L7711)
|
||||
|
||||
The [scope_token](#concept:scope_token "33.14.1 Execution scope concepts [exec.scope.concepts]") concept defines the requirements on
|
||||
a type Token that can be used to create associations
|
||||
between senders and an async scope[.](#concepts-1.sentence-1)
|
||||
|
||||
[2](#concepts-2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/exec.tex#L7716)
|
||||
|
||||
Let *test-sender* and *test-env* be unspecified types such that[sender_in](exec.snd.concepts#concept:sender_in "33.9.3 Sender concepts [exec.snd.concepts]")<*test-sender*, *test-env*> is modeled[.](#concepts-2.sentence-1)
|
||||
|
||||
namespace std::execution {template<class Token>concept [scope_token](#concept:scope_token "33.14.1 Execution scope concepts [exec.scope.concepts]") =[copyable](concepts.object#concept:copyable "18.6 Object concepts [concepts.object]")<Token> &&requires(const Token token) {{ token.try_associate() } -> [same_as](concept.same#concept:same_as "18.4.2 Concept same_as [concept.same]")<bool>; { token.disassociate() } noexcept -> [same_as](concept.same#concept:same_as "18.4.2 Concept same_as [concept.same]")<void>; { token.wrap(declval<*test-sender*>()) } -> [sender_in](exec.snd.concepts#concept:sender_in "33.9.3 Sender concepts [exec.snd.concepts]")<*test-env*>; };}
|
||||
|
||||
[3](#concepts-3)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/exec.tex#L7735)
|
||||
|
||||
A type Token models [scope_token](#concept:scope_token "33.14.1 Execution scope concepts [exec.scope.concepts]") only if:
|
||||
|
||||
- [(3.1)](#concepts-3.1)
|
||||
|
||||
no exceptions are thrown from
|
||||
copy construction,
|
||||
move construction,
|
||||
copy assignment, or
|
||||
move assignment
|
||||
of objects of type Token; and
|
||||
|
||||
- [(3.2)](#concepts-3.2)
|
||||
|
||||
given an lvalue token of type (possibly const) Token,
|
||||
for all expressions sndr such thatdecltype((
|
||||
sndr)) models [sender](exec.snd.concepts#concept:sender "33.9.3 Sender concepts [exec.snd.concepts]"):
|
||||
* [(3.2.1)](#concepts-3.2.1)
|
||||
|
||||
token.wrap(sndr) is a valid expression,
|
||||
|
||||
* [(3.2.2)](#concepts-3.2.2)
|
||||
|
||||
decltype(token.wrap(sndr)) models [sender](exec.snd.concepts#concept:sender "33.9.3 Sender concepts [exec.snd.concepts]"), and
|
||||
|
||||
* [(3.2.3)](#concepts-3.2.3)
|
||||
|
||||
completion_signatures_of_t<decltype(token.wrap(sndr)), E> contains the same completion signatures as completion_signatures_of_t<decltype((sndr)), E> for all types E such that [sender_in](exec.snd.concepts#concept:sender_in "33.9.3 Sender concepts [exec.snd.concepts]")<decltype((sndr)), E> is modeled.
|
||||
|
||||
### [33.14.2](#exec.counting.scopes) Counting Scopes [[exec.counting.scopes]](exec.counting.scopes)
|
||||
|
||||
#### [33.14.2.1](#exec.counting.scopes.general) General [[exec.counting.scopes.general]](exec.counting.scopes.general)
|
||||
|
||||
[1](#exec.counting.scopes.general-1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/exec.tex#L7769)
|
||||
|
||||
Scopes of type simple_counting_scope and counting_scope maintain counts of associations[.](#exec.counting.scopes.general-1.sentence-1)
|
||||
|
||||
Let:
|
||||
|
||||
- [(1.1)](#exec.counting.scopes.general-1.1)
|
||||
|
||||
Scope be either simple_counting_scope or counting_scope,
|
||||
|
||||
- [(1.2)](#exec.counting.scopes.general-1.2)
|
||||
|
||||
scope be an object of type Scope,
|
||||
|
||||
- [(1.3)](#exec.counting.scopes.general-1.3)
|
||||
|
||||
tkn be an object of type Scope::token obtained from scope.get_token(),
|
||||
|
||||
- [(1.4)](#exec.counting.scopes.general-1.4)
|
||||
|
||||
jsndr be a sender obtained from scope.join(), and
|
||||
|
||||
- [(1.5)](#exec.counting.scopes.general-1.5)
|
||||
|
||||
op be an operation state obtained from
|
||||
connecting jsndr to a receiver[.](#exec.counting.scopes.general-1.sentence-2)
|
||||
|
||||
During its lifetime scope goes through different states
|
||||
which govern what operations are allowed and the result of these operations:
|
||||
|
||||
- [(1.6)](#exec.counting.scopes.general-1.6)
|
||||
|
||||
*unused*:
|
||||
a newly constructed object starts in the *unused* state[.](#exec.counting.scopes.general-1.6.sentence-1)
|
||||
|
||||
- [(1.7)](#exec.counting.scopes.general-1.7)
|
||||
|
||||
*open*:
|
||||
when tkn.try_associate() is called
|
||||
while scope is in the *unused* state,scope moves to the *open* state[.](#exec.counting.scopes.general-1.7.sentence-1)
|
||||
|
||||
- [(1.8)](#exec.counting.scopes.general-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[.](#exec.counting.scopes.general-1.8.sentence-1)
|
||||
|
||||
- [(1.9)](#exec.counting.scopes.general-1.9)
|
||||
|
||||
*closed*:
|
||||
when scope.close() is called
|
||||
while scope is in the *open* state,scope moves to the *closed* state[.](#exec.counting.scopes.general-1.9.sentence-1)
|
||||
|
||||
- [(1.10)](#exec.counting.scopes.general-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[.](#exec.counting.scopes.general-1.10.sentence-1)
|
||||
|
||||
- [(1.11)](#exec.counting.scopes.general-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[.](#exec.counting.scopes.general-1.11.sentence-1)
|
||||
|
||||
- [(1.12)](#exec.counting.scopes.general-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[.](#exec.counting.scopes.general-1.12.sentence-1)
|
||||
|
||||
[2](#exec.counting.scopes.general-2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/exec.tex#L7836)
|
||||
|
||||
*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[.](#exec.counting.scopes.general-2.sentence-1)
|
||||
|
||||
[3](#exec.counting.scopes.general-3)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/exec.tex#L7842)
|
||||
|
||||
Subclause [[exec.counting.scopes]](#exec.counting.scopes "33.14.2 Counting Scopes") makes use of
|
||||
the following exposition-only entities:
|
||||
|
||||
struct *scope-join-t* {}; // *exposition only*enum *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](#exec.counting.scopes.general-4)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/exec.tex#L7860)
|
||||
|
||||
The exposition-only class template *impls-for* ([[exec.snd.expos]](exec.snd.expos "33.9.2 Exposition-only entities"))
|
||||
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 only*struct *rcvr-t* { // *exposition only*using receiver_concept = receiver_t;
|
||||
|
||||
Rcvr& *rcvr*; // *exposition only*void set_value() && noexcept { execution::set_value(std::move(*rcvr*)); }template<class E>void set_error(E&& e) && noexcept { execution::set_error(std::move(*rcvr*), std::forward<E>(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 only*decltype(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 only*noexcept([*nothrow-callable*](functional.syn#concept:nothrow-callable "22.10.2 Header <functional> synopsis [functional.syn]")<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*[]<class Rcvr>(auto&& sender, Rcvr& receiver)noexcept(is_nothrow_constructible_v<*state*<Rcvr>, *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*(); }; };}
|
||||
|
||||
#### [33.14.2.2](#simple.counting) Simple Counting Scope [[exec.scope.simple.counting]](exec.scope.simple.counting)
|
||||
|
||||
#### [33.14.2.2.1](#simple.counting.general) General [[exec.scope.simple.counting.general]](exec.scope.simple.counting.general)
|
||||
|
||||
[ð](#lib:execution::simple_counting_scope)
|
||||
|
||||
namespace std::execution {class simple_counting_scope {public:// [[exec.simple.counting.token]](#exec.simple.counting.token "33.14.2.2.4 Token"), tokenstruct token; static constexpr size_t max_associations = *implementation-defined*; // [[exec.simple.counting.ctor]](#exec.simple.counting.ctor "33.14.2.2.2 Constructor and Destructor"), constructor and destructor simple_counting_scope() noexcept;
|
||||
simple_counting_scope(simple_counting_scope&&) = delete; ~simple_counting_scope(); // [[exec.simple.counting.mem]](#exec.simple.counting.mem "33.14.2.2.3 Members"), members token get_token() noexcept; void close() noexcept; [sender](exec.snd.concepts#concept:sender "33.9.3 Sender concepts [exec.snd.concepts]") auto join() noexcept; private: size_t *count*; // *exposition only**scope-state-type* *state*; // *exposition only*bool *try-associate*() noexcept; // *exposition only*void *disassociate*() noexcept; // *exposition only*template<class State>bool *start-join-sender*(State& state) noexcept; // *exposition only*};}
|
||||
|
||||
[1](#simple.counting.general-1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/exec.tex#L7971)
|
||||
|
||||
For purposes of determining the existence of a data race,get_token,close,join,*try-associate*,*disassociate*, and*start-join-sender* behave as atomic operations ([[intro.multithread]](intro.multithread "6.10.2 Multi-threaded executions and data races"))[.](#simple.counting.general-1.sentence-1)
|
||||
|
||||
These operations on a single object of
|
||||
type simple_counting_scope appear to occur in a single total order[.](#simple.counting.general-1.sentence-2)
|
||||
|
||||
#### [33.14.2.2.2](#exec.simple.counting.ctor) Constructor and Destructor [[exec.simple.counting.ctor]](exec.simple.counting.ctor)
|
||||
|
||||
[ð](#lib:execution::simple_counting_scope,constructor)
|
||||
|
||||
`simple_counting_scope() noexcept;
|
||||
`
|
||||
|
||||
[1](#exec.simple.counting.ctor-1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/exec.tex#L7991)
|
||||
|
||||
*Postconditions*: *count* is 0 and *state* is *unused*[.](#exec.simple.counting.ctor-1.sentence-1)
|
||||
|
||||
[ð](#lib:execution::simple_counting_scope,destructor)
|
||||
|
||||
`~simple_counting_scope();
|
||||
`
|
||||
|
||||
[2](#exec.simple.counting.ctor-2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/exec.tex#L8002)
|
||||
|
||||
*Effects*: If *state* is not one of*joined*, *unused*, or *unused-and-closed*,
|
||||
invokes terminate ([[except.terminate]](except.terminate "14.6.2 The std::terminate function"))[.](#exec.simple.counting.ctor-2.sentence-1)
|
||||
|
||||
Otherwise, has no effects[.](#exec.simple.counting.ctor-2.sentence-2)
|
||||
|
||||
#### [33.14.2.2.3](#exec.simple.counting.mem) Members [[exec.simple.counting.mem]](exec.simple.counting.mem)
|
||||
|
||||
[ð](#lib:get_token,execution::simple_counting_scope)
|
||||
|
||||
`token get_token() noexcept;
|
||||
`
|
||||
|
||||
[1](#exec.simple.counting.mem-1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/exec.tex#L8018)
|
||||
|
||||
*Returns*: An object t of type simple_counting_scope::token such thatt.*scope* == this is true[.](#exec.simple.counting.mem-1.sentence-1)
|
||||
|
||||
[ð](#lib:close,execution::simple_counting_scope)
|
||||
|
||||
`void close() noexcept;
|
||||
`
|
||||
|
||||
[2](#exec.simple.counting.mem-2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/exec.tex#L8030)
|
||||
|
||||
*Effects*: If *state* is
|
||||
|
||||
- [(2.1)](#exec.simple.counting.mem-2.1)
|
||||
|
||||
*unused*, then changes *state* to *unused-and-closed*;
|
||||
|
||||
- [(2.2)](#exec.simple.counting.mem-2.2)
|
||||
|
||||
*open*, then changes *state* to *closed*;
|
||||
|
||||
- [(2.3)](#exec.simple.counting.mem-2.3)
|
||||
|
||||
*open-and-joining*,
|
||||
then changes *state* to *closed-and-joining*;
|
||||
|
||||
- [(2.4)](#exec.simple.counting.mem-2.4)
|
||||
|
||||
otherwise, no effects[.](#exec.simple.counting.mem-2.sentence-1)
|
||||
|
||||
[3](#exec.simple.counting.mem-3)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/exec.tex#L8045)
|
||||
|
||||
*Postconditions*: Any subsequent call to *try-associate*() on *this returns false[.](#exec.simple.counting.mem-3.sentence-1)
|
||||
|
||||
[ð](#lib:join,execution::simple_counting_scope)
|
||||
|
||||
`[sender](exec.snd.concepts#concept:sender "33.9.3 Sender concepts [exec.snd.concepts]") auto join() noexcept;
|
||||
`
|
||||
|
||||
[4](#exec.simple.counting.mem-4)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/exec.tex#L8057)
|
||||
|
||||
*Returns*: *make-sender*(*scope-join-t*(), this)[.](#exec.simple.counting.mem-4.sentence-1)
|
||||
|
||||
[ð](#lib:try-associate,execution::simple_counting_scope)
|
||||
|
||||
`bool try-associate() noexcept;
|
||||
`
|
||||
|
||||
[5](#exec.simple.counting.mem-5)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/exec.tex#L8068)
|
||||
|
||||
*Effects*: If *count* is equal to max_associations, then no effects[.](#exec.simple.counting.mem-5.sentence-1)
|
||||
|
||||
Otherwise, if *state* is
|
||||
|
||||
- [(5.1)](#exec.simple.counting.mem-5.1)
|
||||
|
||||
*unused*,
|
||||
then increments *count* and changes *state* to *open*;
|
||||
|
||||
- [(5.2)](#exec.simple.counting.mem-5.2)
|
||||
|
||||
*open* or *open-and-joining*,
|
||||
then increments *count*;
|
||||
|
||||
- [(5.3)](#exec.simple.counting.mem-5.3)
|
||||
|
||||
otherwise, no effects[.](#exec.simple.counting.mem-5.sentence-2)
|
||||
|
||||
[6](#exec.simple.counting.mem-6)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/exec.tex#L8083)
|
||||
|
||||
*Returns*: true if *count* was incremented, false otherwise[.](#exec.simple.counting.mem-6.sentence-1)
|
||||
|
||||
[ð](#lib:disassociate,execution::simple_counting_scope)
|
||||
|
||||
`void disassociate() noexcept;
|
||||
`
|
||||
|
||||
[7](#exec.simple.counting.mem-7)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/exec.tex#L8094)
|
||||
|
||||
*Preconditions*: *count* is greater than zero[.](#exec.simple.counting.mem-7.sentence-1)
|
||||
|
||||
[8](#exec.simple.counting.mem-8)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/exec.tex#L8098)
|
||||
|
||||
*Effects*: Decrements *count*[.](#exec.simple.counting.mem-8.sentence-1)
|
||||
|
||||
If *count* is zero after decrementing and*state* is *open-and-joining* or *closed-and-joining*,
|
||||
changes *state* to *joined* and
|
||||
calls *complete*() on all objects registered with *this[.](#exec.simple.counting.mem-8.sentence-2)
|
||||
|
||||
[*Note [1](#exec.simple.counting.mem-note-1)*:
|
||||
|
||||
Calling *complete*() on any registered object
|
||||
can cause *this to be destroyed[.](#exec.simple.counting.mem-8.sentence-3)
|
||||
|
||||
â *end note*]
|
||||
|
||||
[ð](#lib:start-join-sender,execution::simple_counting_scope)
|
||||
|
||||
`template<class State>
|
||||
bool start-join-sender(State& st) noexcept;
|
||||
`
|
||||
|
||||
[9](#exec.simple.counting.mem-9)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/exec.tex#L8118)
|
||||
|
||||
*Effects*: If *state* is
|
||||
|
||||
- [(9.1)](#exec.simple.counting.mem-9.1)
|
||||
|
||||
*unused*, *unused-and-closed*, or *joined*, then
|
||||
changes *state* to *joined* and returns true;
|
||||
|
||||
- [(9.2)](#exec.simple.counting.mem-9.2)
|
||||
|
||||
*open* or *open-and-joining*, then
|
||||
changes *state* to *open-and-joining*,
|
||||
registers st with *this and returns false;
|
||||
|
||||
- [(9.3)](#exec.simple.counting.mem-9.3)
|
||||
|
||||
*closed* or *closed-and-joining*, then
|
||||
changes *state* to *closed-and-joining*,
|
||||
registers st with *this and returns false[.](#exec.simple.counting.mem-9.sentence-1)
|
||||
|
||||
#### [33.14.2.2.4](#exec.simple.counting.token) Token [[exec.simple.counting.token]](exec.simple.counting.token)
|
||||
|
||||
[ð](#lib:execution::simple_counting_scope::token)
|
||||
|
||||
namespace std::execution {struct simple_counting_scope::token {template<[sender](exec.snd.concepts#concept:sender "33.9.3 Sender concepts [exec.snd.concepts]") Sender> Sender&& wrap(Sender&& snd) const noexcept; bool try_associate() const noexcept; void disassociate() const noexcept; private: simple_counting_scope* *scope*; // *exposition only*};}
|
||||
|
||||
[ð](#lib:wrap,execution::simple_counting_scope::token)
|
||||
|
||||
`template<[sender](exec.snd.concepts#concept:sender "33.9.3 Sender concepts [exec.snd.concepts]") Sender>
|
||||
Sender&& wrap(Sender&& snd) const noexcept;
|
||||
`
|
||||
|
||||
[1](#exec.simple.counting.token-1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/exec.tex#L8160)
|
||||
|
||||
*Returns*: std::forward<Sender>(snd)[.](#exec.simple.counting.token-1.sentence-1)
|
||||
|
||||
[ð](#lib:try_associate,execution::simple_counting_scope::token)
|
||||
|
||||
`bool try_associate() const noexcept;
|
||||
`
|
||||
|
||||
[2](#exec.simple.counting.token-2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/exec.tex#L8171)
|
||||
|
||||
*Effects*: Equivalent to: return *scope*->*try-associate*();
|
||||
|
||||
[ð](#lib:disassociate,execution::simple_counting_scope::token)
|
||||
|
||||
`void disassociate() const noexcept;
|
||||
`
|
||||
|
||||
[3](#exec.simple.counting.token-3)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/exec.tex#L8182)
|
||||
|
||||
*Effects*: Equivalent to *scope*->*disassociate*()[.](#exec.simple.counting.token-3.sentence-1)
|
||||
|
||||
#### [33.14.2.3](#counting) Counting Scope [[exec.scope.counting]](exec.scope.counting)
|
||||
|
||||
[ð](#lib:execution::counting_scope)
|
||||
|
||||
namespace std::execution {class counting_scope {public:struct token {template<[sender](exec.snd.concepts#concept:sender "33.9.3 Sender concepts [exec.snd.concepts]") Sender>[sender](exec.snd.concepts#concept:sender "33.9.3 Sender concepts [exec.snd.concepts]") auto wrap(Sender&& snd) const noexcept(*see below*); bool try_associate() const noexcept; void disassociate() const noexcept; private: counting_scope* *scope*; // *exposition only*}; static constexpr size_t max_associations = *implementation-defined*;
|
||||
|
||||
counting_scope() noexcept;
|
||||
counting_scope(counting_scope&&) = delete; ~counting_scope();
|
||||
|
||||
token get_token() noexcept; void close() noexcept; [sender](exec.snd.concepts#concept:sender "33.9.3 Sender concepts [exec.snd.concepts]") auto join() noexcept; void request_stop() noexcept; private: size_t *count*; // *exposition only**scope-state-type* *state*; // *exposition only* inplace_stop_source *s_source*; // *exposition only*bool *try-associate*() noexcept; // *exposition only*void *disassociate*() noexcept; // *exposition only*template<class State>bool *start-join-sender*(State& state) noexcept; // *exposition only*};}
|
||||
|
||||
[1](#counting-1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/exec.tex#L8230)
|
||||
|
||||
counting_scope differs from simple_counting_scope by
|
||||
adding support for cancellation[.](#counting-1.sentence-1)
|
||||
|
||||
Unless specified below, the semantics of members of counting_scope are the same as the corresponding members of simple_counting_scope[.](#counting-1.sentence-2)
|
||||
|
||||
[ð](#lib:get_token,execution::counting_scope)
|
||||
|
||||
`token get_token() noexcept;
|
||||
`
|
||||
|
||||
[2](#counting-2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/exec.tex#L8242)
|
||||
|
||||
*Returns*: An object t of type counting_scope::token such thatt.*scope* == this is true[.](#counting-2.sentence-1)
|
||||
|
||||
[ð](#lib:request_stop,execution::counting_scope)
|
||||
|
||||
`void request_stop() noexcept;
|
||||
`
|
||||
|
||||
[3](#counting-3)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/exec.tex#L8254)
|
||||
|
||||
*Effects*: Equivalent to *s_source*.request_stop()[.](#counting-3.sentence-1)
|
||||
|
||||
[4](#counting-4)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/exec.tex#L8258)
|
||||
|
||||
*Remarks*: Calls to request_stop do not introduce data races[.](#counting-4.sentence-1)
|
||||
|
||||
[ð](#lib:wrap,execution::counting_scope::token)
|
||||
|
||||
`template<[sender](exec.snd.concepts#concept:sender "33.9.3 Sender concepts [exec.snd.concepts]") Sender>
|
||||
[sender](exec.snd.concepts#concept:sender "33.9.3 Sender concepts [exec.snd.concepts]") auto counting_scope::token::wrap(Sender&& snd) const
|
||||
noexcept(is_nothrow_constructible_v<remove_cvref_t<Sender>, Sender>);
|
||||
`
|
||||
|
||||
[5](#counting-5)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/exec.tex#L8271)
|
||||
|
||||
*Effects*: Equivalent to:return *stop-when*(std::forward<Sender>(snd), *scope*->*s_source*.get_token());
|
||||
Reference in New Issue
Block a user