Skip to content

Commit 36c1cc9

Browse files
committed
added query and customization point documentation
1 parent ab7abd8 commit 36c1cc9

File tree

1 file changed

+111
-21
lines changed

1 file changed

+111
-21
lines changed

docs/overview.md

Lines changed: 111 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -352,8 +352,8 @@ static_assert(not std::execution::unstoppable_token<std::execution::inline_stop_
352352
</details>
353353

354354
## Queries
355-
The queries are used to obtain properties associated with an object. Except <code><a href=‘#forwarding-query’>forwarding_query</a></code>, <code><a href=‘#get-env’>get_env</a></code>, and <code><a href=‘#get-completion-signatures’>get_completion_signatures</a></code> the queries work on <a href=‘#environment’>environments</a>. The
356-
<a href=‘#environment’>environment</a> queries are defined by providing a member <code>query(<i>query_t</i>, <i>a...</i>) const</code> on the <a href=‘#environment’>environment</a> object.
355+
The queries are used to obtain properties associated with an object.
356+
357357
<details>
358358
<summary>Example defining a query on an environment</summary>
359359
This example shows how to define an environment class which provides a <a href=‘#get-allocator’><code>get_allocator</code></a> query. The objects stores a `std::pmr::memory_resource*` and returns a correspondingly initialized `std::pmr::polymorphic_allocator<>`.
@@ -372,7 +372,14 @@ struct alloc_env {
372372
<summary><code>forwarding_query(<i>query</i>) -> bool</code></summary>
373373
**Default**: `false`
374374
<br/>
375-
<code>forwarding_query(<i>query</i>)</code> is a `constexpr` query used to determine if the query <code><i>query</i></code> should be forwarded when wrapping an environment.
375+
The expression <code>forwarding_query(<i>query</i>)</code> is a `constexpr` query used to determine if the query <code><i>query</i></code> should be forwarded when wrapping an environment. The expression is required to be a core constant expression if <code><i>query</i></code> is a core constant expression.
376+
377+
The result of the expression is determined as follows:
378+
<ol>
379+
<li>The result is the value of the expression <code><i>query</i>.query(forwarding_query)</code> if this expression is valid and `noexcept`.</li>
380+
<li>The result is <code>true</code> if the type of <code><i>query</i></code> is <code>public</code>ly derived from <code>forwarding_query</code>.</li>
381+
<li>Otherwise the result is <code>false</code>.
382+
</ol>
376383
<blockquote>
377384
<details>
378385
<summary>Example</summary>
@@ -402,7 +409,11 @@ struct custom_t: forwarding_query_t {
402409
<summary><code>get_env(<i>queryable</i>) -> <i>env</i></code></summary>
403410
**Default**: <a href='#empty_env'>`empty_env`</a>
404411
<br/>
405-
<code>get_env(<i>queryable</i>)</code> is used to get the environment <code><i>env</i></code> associated with <code><i>queryable</i></code>. To provide a non-default environment for a <code><i>queryable</i></code> a `get_env` member needs to be defined. If <code><i>queryable</i></code> doesn’t provide the <code>get_env</code> query an object of type <code><a href=‘#empty_env’>empty_env</a></code> is returned.
412+
The expresion <code>get_env(<i>queryable</i>)</code> is used to get the environment <code><i>env</i></code> associated with <code><i>queryable</i></code>. To provide a non-default environment for a <code><i>queryable</i></code> a `get_env` member needs to be defined. If <code><i>queryable</i></code> doesn’t provide the <code>get_env</code> query an object of type <code><a href=‘#empty_env’>empty_env</a></code> is returned.
413+
The value of the expression is <ol>
414+
<li>the result of <code>as_const(<i>queryable</i>).get_env()</code> if this expression is valid and <code>noexcept</code>.</li>
415+
<li><code>empty_env</code> otherwise.
416+
</ol>
406417
<div>
407418
<details>
408419
<summary>Example</summary>
@@ -428,7 +439,14 @@ Note that the `get_env` member is both `const` and `noexcept`.
428439
<summary><code>get_allocator(<i>env</i>) -> <i>allocator</i></code></summary>
429440
**Default**: <i>none</i>
430441
<br/>
431-
<code>get_allocator(<i>env</i>)</code> returns an <code><i>allocator</i></code> for any memory allocations in the respective context. If <code><i>env</i></code> doesn’t support this query any attempt to access it will result in a compilation error.
442+
The expression <code>get_allocator(<i>env</i>)</code> returns an <code><i>allocator</i></code> for any memory allocations in the respective context. If <code><i>env</i></code> doesn’t support this query any attempt to access it will result in a compilation error. The value of the expression <code>get_allocator(<i>env</i>)</code> is the result of <code>as_const(<i>env</i>).query(get_allocator)</code> if
443+
<ul>
444+
<li>the expression is valid</code>;</li>
445+
<li>the expression is <code>noexcept</code>;</li>
446+
<li>the result of the expression satisfies <code><i>simple-allocator</i></code>.</li>
447+
</ul>
448+
Otherwise the expression is ill-formed.
449+
</details>
432450
<div>
433451
<details>
434452
<summary>Example</summary>
@@ -447,47 +465,119 @@ struct alloc_env {
447465
</div>
448466
</details>
449467
<details>
450-
<summary><code>get_completion_scheduler&lt;<i>tag</i>&gt;(<i>env</i>) -> <i>scheduler</i></code></summary>
468+
<summary><code>get_completion_scheduler&lt;<iTtag</i>&gt;(<i>env</i>) -> <i>scheduler</i></code></summary>
451469
**Default**: <i>none</i>
452470
<br/>
453-
If the expression <code>get_completion_scheduler&lt;tag&gt;(get_env(<i>sender</i>))</code> is well-formed and returns a scheduler it defines the scheduler on which the completion <code><i>tag</i></code> executes. In particular <code>get_completion_scheduler&lt;set_value_t&gt;(schedule(<i>sched</i>))</code> returns <code><i>sched</i></code>.
471+
The expression <code>get_complet_scheduler&lt;Tag&gt;(<i>env</i>)</code> yields the completion scheduler for the completion signal <code>Tag</code> associated with <code><i>env</i></code>. This query can be used to determine the scheduler a sender <code><i>sender</i></code> completes on for a given completion signal <code>Tag</code> by using <code>get_completion_scheduler&lt;Tag&gt;(get_env(<i>sender</i>))</code>. The value of the expression is equivalent to <code>as_const(<i>env</i>).query(get_completion_scheduler&lt;Tag&gt;)</code> if
472+
<ol>
473+
<li><code>Tag</code> is one of the types <code>set_value_t</code>, <code>set_error_t</code>, or <code>set_stopped_t</code>;
474+
<li>this expression is valid;</li>
475+
<li>this expression is <code>noexcept</code>;</li>
476+
<li>the expression’s type satisfies <code>scheduler</code>.
477+
</ol>
478+
Otherwise the expression is invalid.
454479
</details>
455480
<details>
456481
<summary><code>get_completion_signatures(<i>sender</i>, <i>env</i>)</code></summary>
457482
The expression <code>get_completion_signatures(<i>sender</i>, <i>env</i>)</code> returns an object whose type is a specialization of <a href=‘#completion-signatures’><code>completion_signatures</code></a> defining the possible completion signatures of <code><i>sender</i></code> when connected to a <a href=‘#receiver’><code><i>receiver</i></code></a> whose <a href=‘#environment'>environment</a> <code>get_env(<i>receiver</i>)</code> is <code><i>env</i></code>. A <a href=‘#sender’><code>sender</code></a> can define the result of this query either by defining a member function <code>get_completion_signatures</code> or using a type alias <code>completion_signatures</code>.
483+
484+
To determine the result the <code><i>sender</i></code> is first transformed using <code>transform_sender(<i>domain</i>, <i>sender</i>, <i>env</i>)</code> to get <code><i>new-sender</i></code> with type <code><i>New-Sender-Type</i></code>. With that the result type is
485+
<ol>
486+
<li>the type of <code><i>new-sender</i>.get_completion_signatures(<i>env</i>)</code> if this expression is valid;</li>
487+
<li>the type <code>remove_cvref_t&lt;<i>New-Sender-Type</i>&gt;::completion_signatures</code> if this type exists;</li>
488+
<li><code>completion_signatures&lt;set_value_t(<i>T</i>), set_error_t(exception_ptr), set_stopped_t()&gt;</code> if <code><i>New-Sender-Type</i></code> is an awaitable type which would yield an object of type <code><i>T</i></code> when it is <code>co_await</code>ed;</li>
489+
<li>invalid otherwise.</code>
490+
</ol>
458491
<div>
459492
<details>
460493
<summary>Example</summary>
461-
When a <a href=‘#sender’><code>sender</code></a> doesn’t need to compute the completion signatures based on an <a href=‘#environment’>environment</a> it is easiest to use a the type alias:
462-
463-
494+
When a <a href=‘#sender’><code>sender</code></a> doesn’t need to compute the completion signatures based on an <a href=‘#environment’>environment</a> it is easiest to use a the type alias, e.g.:
495+
```c++
496+
struct sender {
497+
using sender_concept = std::execution::sender_t;
498+
using completion_signatures = std::completion_signatures<
499+
std::execution::set_value_t(int),
500+
std::execution::set_error_t(std::error_code),
501+
std::execution::set_stopped()
502+
>;
503+
// ...
504+
};
505+
```
464506
</details>
465507
</div>
466508
</details>
467509
<details>
468-
<summary><code>get_delegation_scheduler(<i>env</i>)</code></summary>
510+
<summary><code>get_delegation_scheduler(<i>env</i>) -> <i>scheduler</i></code></summary>
511+
The expression <code>get_delegation_scheduler(<i>env</i>)</code> yields the scheduler associated with <code><i>env</i></code> which is used for forward progress delegation. The value of the expression is equivalent to <code>as_const(<i>env</i>).query(get_delegation_scheduler) -> <i>scheduler</i></code> if
512+
<ol>
513+
<li>this expression is valid;</li>
514+
<li>this expression is <code>noexcept</code>;</li>
515+
<li>the expression’s type satisfies <code>scheduler</code>.
516+
</ol>
517+
Otherwise the expression is invalid.
469518
</details>
470519
<details>
471-
<summary><code>get_domain(<i>env</i>)</code>
520+
<summary><code>get_domain(<i>env</i>) -> <i>domain</i></code>
472521
</summary>
522+
The expression <code>get_domain(<i>env</i>)</code> yields the domain associated with <code><i>env</i></code>. The value of the expression is equivalent to <code>as_const(<i>env</i>).query(get_domain)</code> if
523+
<ol>
524+
<li>this expression is valid;</li>
525+
<li>this expression is <code>noexcept</code>.</li>
526+
</ol>
527+
Otherwise the expression is invalid.
473528
</details>
474529
<details>
475-
<summary><code>get_forward_progress_guarantee(<i>env</i>)</code></summary>
530+
<summary><code>get_forward_progress_guarantee(<i>scheduler</i>) -> forward_progress_guarantee</code></summary>
531+
The expression <code>get_forward_progress_guarantee(<i>scheduler</i>)</code> yields the forward progress guarantee of the <i>scheduler</i>’s execution agent. The value of the expression is equivalent to <code>as_const(<i>env</i>).query(get_scheduler)</code> if
532+
<ol>
533+
<li>this expression is valid;</li>
534+
<li>this expression is <code>noexcept</code>;</li>
535+
<li>the expression’s type is <code>forward_progress_guarantee</code>.
536+
</ol>
537+
Otherwise the expression is invalid.
476538
</details>
477539
<details>
478-
<summary><code>get_scheduler(<i>env</i>)</code></summary>
540+
<summary><code>get_scheduler(<i>env</i>) -> <i>scheduler</i></code></summary>
541+
The expression <code>get_scheduler(<i>env</i>)</code> yields the scheduler associated with <code><i>env</i></code>. The value of the expression is equivalent to <code>as_const(<i>env</i>).query(get_scheduler)</code> if
542+
<ol>
543+
<li>this expression is valid;</li>
544+
<li>this expression is <code>noexcept</code>;</li>
545+
<li>the expression’s type satisfies <code>scheduler</code>.
546+
</ol>
547+
Otherwise the expression is invalid.
479548
</details>
480549
<details>
481-
<summary><code>get_stop_token(<i>env</i>)</code></summary>
550+
<summary><code>get_stop_token(<i>env</i>) -> <i>stoppable_token</i></code></summary>
551+
The expression <code>get_stop_token(<i>env</i>)</code> yields the stop token associated with <code><i>env</i></code>. The value is the result of the expression <code>as_const(<i>env</i>).query(get_stop_token)</code> if
552+
<ul>
553+
<li>the expression is valid;</li>
554+
<li>the expression is <code>noexcept</code>;</li>
555+
<li>the expression satisfies <code>stoppable_token</code>.</li>
556+
</ul>
557+
Otherwise the value is <code>never_stop_token{}</code>.
482558
</details>
483559

484-
### Customization Point Objects
560+
## Customization Point Objects
485561

486-
- <code>connect(<i>sender, receiver</i>) -> <i>operation_state</i></code>
487-
- <code>set_error(<i>error</i>) noexcept -> void</code>
488-
- <code>set_stopped(<i>receiver</i>) noexcept -> void</code>
489-
- <code>set_value(<i>receiver, value...</i>) noexcept -> void</code>
490-
- <code>start(<i>state&amp;</i>) noexcept -> void</code>
562+
<details>
563+
<summary><code>connect(<i>sender, receiver</i>) -> <i>operation_state</i></code></summary>
564+
</details>
565+
<details>
566+
<summary><code>set_error(<i>receiver</i>, <i>error</i>) noexcept -> void</code></summary>
567+
The expression <code>set_error(<i>receiver</i>, <i>error</i>)</code> invokes the <code>set_error</code> completion signal on <code><i>receiver</i></code> with the argument <code><i>error</i></code>, i.e., it invokes <code><i>receiver</i>.set_error(<i>error</i>)</code>.
568+
</details>
569+
<details>
570+
<summary><code>set_stopped(<i>receiver</i>) noexcept -> void</code></summary>
571+
The expression <code>set_stopped(<i>receiver</i>)</code> invokes the <code>set_stopped</code> completion signal on <code><i>receiver</i></code>, i.e., it invokes <code><i>receiver</i>.set_stopped()</code>.
572+
</details>
573+
<details>
574+
<summary><code>set_value(<i>receiver</i>, <i>value</i>...) noexcept -> void</code></summary>
575+
The expression <code>set_value(<i>receiver</i>, <i>value</i>...)</code> invokes the <code>set_value</code> completion signal on <code><i>receiver</i></code> with the argument(s) <code><i>value</i>...</code>, i.e., it invokes <code><i>receiver</i>.set_value(<i>value</i>...)</code>.
576+
</details>
577+
<details>
578+
<summary><code>start(<i>state</i>) noexcept -> void</code></summary>
579+
The expression <code>start(<i>state</i>)</code> starts the execution of the <code>operation_state</code> object <code><i>state</i></code>. Once this expression started executing the object <code><i>state</i></code> is required to stay valid at least until one of the completion signals of <code><i>state</i></code>’s <code>receiver</code> is invoked. Once started exactly one of the completion signals is eventually called.
580+
</details>
491581

492582
## Senders
493583

0 commit comments

Comments
 (0)