[exec.scope.simple.counting] # 33 Execution control library [[exec]](./#exec) ## 33.14 Execution scope utilities [[exec.scope]](exec.scope#simple.counting) ### 33.14.2 Counting Scopes [[exec.counting.scopes]](exec.counting.scopes#exec.scope.simple.counting) #### 33.14.2.2 Simple Counting Scope [exec.scope.simple.counting] #### [33.14.2.2.1](#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*templatebool *start-join-sender*(State& state) noexcept; // *exposition only*};} [1](#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"))[.](#general-1.sentence-1) These operations on a single object of type simple_counting_scope appear to occur in a single total order[.](#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 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(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)