From Jason Turner

[exec.spawn]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmp5eo7qjgt/{from.md → to.md} +139 -0
tmp/tmp5eo7qjgt/{from.md → to.md} RENAMED
@@ -0,0 +1,139 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #### `execution::spawn` <a id="exec.spawn">[[exec.spawn]]</a>
2
+
3
+ `spawn` attempts to associate the given input sender with the given
4
+ token’s async scope and, on success, eagerly starts the input sender.
5
+
6
+ The name `spawn` denotes a customization point object. For
7
+ subexpressions `sndr`, `token`, and `env`,
8
+
9
+ - let `Sndr` be `decltype((sndr))`,
10
+ - let `Token` be `remove_cvref_t<decltype((token))>`, and
11
+ - let `Env` be `remove_cvref_t<decltype((env))>`.
12
+
13
+ If any of `sender<Sndr>`, `scope_token<Token>`, or `queryable<Env>` are
14
+ not satisfied, the expression `spawn({}sndr, token, env)` is ill-formed.
15
+
16
+ Let *`spawn-state-base`* be the exposition-only class:
17
+
18
+ ``` cpp
19
+ namespace std::execution {
20
+ struct spawn-state-base { // exposition only
21
+ virtual void complete() noexcept = 0; // exposition only
22
+ };
23
+ }
24
+ ```
25
+
26
+ Let *`spawn-receiver`* be the exposition-only class:
27
+
28
+ ``` cpp
29
+ namespace std::execution {
30
+ struct spawn-receiver { // exposition only
31
+ using receiver_concept = receiver_t;
32
+
33
+ spawn-state-base* state; // exposition only
34
+ void set_value() && noexcept { state->complete(); }
35
+ void set_stopped() && noexcept { state->complete(); }
36
+ };
37
+ }
38
+ ```
39
+
40
+ Let *`spawn-state`* be the exposition-only class template:
41
+
42
+ ``` cpp
43
+ namespace std::execution {
44
+ template<class Alloc, scope_token Token, sender Sender>
45
+ struct spawn-state : spawn-state-base { // exposition only
46
+ using op-t = connect_result_t<Sender, spawn-receiver>; // exposition only
47
+
48
+ spawn-state(Alloc alloc, Sender&& sndr, Token token); // exposition only
49
+ void complete() noexcept override; // exposition only
50
+ void run(); // exposition only
51
+
52
+ private:
53
+ using alloc-t = // exposition only
54
+ allocator_traits<Alloc>::template rebind_alloc<spawn-state>;
55
+
56
+ alloc-t alloc; // exposition only
57
+ op-t op; // exposition only
58
+ Token token; // exposition only
59
+
60
+ void destroy() noexcept; // exposition only
61
+ };
62
+ }
63
+ ```
64
+
65
+ ``` cpp
66
+ spawn-state(Alloc alloc, Sender&& sndr, Token token);
67
+ ```
68
+
69
+ *Effects:* Initializes *alloc* with `alloc`, *token* with `token`, and
70
+ *op* with:
71
+
72
+ ``` cpp
73
+ connect(std::move(sndr), spawn-receiver(this))
74
+ ```
75
+
76
+ ``` cpp
77
+ void run();
78
+ ```
79
+
80
+ *Effects:* Equivalent to:
81
+
82
+ ``` cpp
83
+ if (token.try_associate())
84
+ start(op);
85
+ else
86
+ destroy();
87
+ ```
88
+
89
+ ``` cpp
90
+ void complete() noexcept override;
91
+ ```
92
+
93
+ *Effects:* Equivalent to:
94
+
95
+ ``` cpp
96
+ auto token = std::move(this->token);
97
+
98
+ destroy();
99
+ token.disassociate();
100
+ ```
101
+
102
+ ``` cpp
103
+ void destroy() noexcept;
104
+ ```
105
+
106
+ *Effects:* Equivalent to:
107
+
108
+ ``` cpp
109
+ auto alloc = std::move(this->alloc);
110
+
111
+ allocator_traits<alloc-t>::destroy(alloc, this);
112
+ allocator_traits<alloc-t>::deallocate(alloc, this, 1);
113
+ ```
114
+
115
+ For the expression `spawn(sndr, token, env)` let `new_sender` be the
116
+ expression `token.wrap(sndr)` and let `alloc` and `senv` be defined as
117
+ follows:
118
+
119
+ - if the expression `get_allocator(env)` is well-formed, then `alloc` is
120
+ the result of `get_allocator(env)` and `senv` is the expression `env`,
121
+ - otherwise if the expression `get_allocator(get_env(new_sender))` is
122
+ well-formed, then `alloc` is the result of
123
+ `get_allocator(get_env(new_sender))` and `senv` is the expression
124
+ `JOIN-ENV(prop(get_allocator, alloc), env)`,
125
+ - otherwise `alloc` is `allocator<void>()` and `senv` is the expression
126
+ `env`.
127
+
128
+ The expression `spawn(sndr, token, env)` is of type `void` and has the
129
+ following effects:
130
+
131
+ - Uses `alloc` to allocate and construct an object `o` of type that is a
132
+ specialization of `spawn-state` from `alloc`,
133
+ `write_env(token.wrap(sndr), senv)`, and `token` and then invokes
134
+ `o.run()`. If an exception is thrown then any constructed objects are
135
+ destroyed and any allocated memory is deallocated.
136
+
137
+ The expression `spawn(sndr, token)` is expression-equivalent to
138
+ `spawn(sndr, token, execution::env<>({}))`.
139
+