From Jason Turner

[thread.thread.class]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmpy9hakkos/{from.md → to.md} +70 -94
tmp/tmpy9hakkos/{from.md → to.md} RENAMED
@@ -17,33 +17,33 @@ successful call to `detach` or `join`. — *end note*]
17
 
18
  ``` cpp
19
  namespace std {
20
  class thread {
21
  public:
22
- // types:
23
  class id;
24
- using native_handle_type = implementation-defined; // See~[thread.req.native]
25
 
26
- // construct/copy/destroy:
27
  thread() noexcept;
28
  template<class F, class... Args> explicit thread(F&& f, Args&&... args);
29
  ~thread();
30
  thread(const thread&) = delete;
31
  thread(thread&&) noexcept;
32
  thread& operator=(const thread&) = delete;
33
  thread& operator=(thread&&) noexcept;
34
 
35
- // members:
36
  void swap(thread&) noexcept;
37
  bool joinable() const noexcept;
38
  void join();
39
  void detach();
40
  id get_id() const noexcept;
41
- native_handle_type native_handle(); // See~[thread.req.native]
42
 
43
- // static members:
44
- static unsigned hardware_concurrency() noexcept;
45
  };
46
  }
47
  ```
48
 
49
  #### Class `thread::id` <a id="thread.thread.id">[[thread.thread.id]]</a>
@@ -54,150 +54,129 @@ namespace std {
54
  public:
55
  id() noexcept;
56
  };
57
 
58
  bool operator==(thread::id x, thread::id y) noexcept;
59
- bool operator!=(thread::id x, thread::id y) noexcept;
60
- bool operator<(thread::id x, thread::id y) noexcept;
61
- bool operator<=(thread::id x, thread::id y) noexcept;
62
- bool operator>(thread::id x, thread::id y) noexcept;
63
- bool operator>=(thread::id x, thread::id y) noexcept;
64
 
65
  template<class charT, class traits>
66
  basic_ostream<charT, traits>&
67
  operator<<(basic_ostream<charT, traits>& out, thread::id id);
68
 
69
- // Hash support
70
  template<class T> struct hash;
71
  template<> struct hash<thread::id>;
72
  }
73
  ```
74
 
75
  An object of type `thread::id` provides a unique identifier for each
76
  thread of execution and a single distinct value for all `thread` objects
77
- that do not represent a thread of execution ([[thread.thread.class]]).
78
  Each thread of execution has an associated `thread::id` object that is
79
  not equal to the `thread::id` object of any other thread of execution
80
  and that is not equal to the `thread::id` object of any `thread` object
81
  that does not represent threads of execution.
82
 
83
- `thread::id` shall be a trivially copyable class (Clause  [[class]]).
84
- The library may reuse the value of a `thread::id` of a terminated thread
85
- that can no longer be joined.
86
 
87
  [*Note 1*: Relational operators allow `thread::id` objects to be used
88
  as keys in associative containers. — *end note*]
89
 
90
  ``` cpp
91
  id() noexcept;
92
  ```
93
 
94
- *Effects:* Constructs an object of type `id`.
95
-
96
- *Postconditions:* The constructed object does not represent a thread of
97
  execution.
98
 
99
  ``` cpp
100
  bool operator==(thread::id x, thread::id y) noexcept;
101
  ```
102
 
103
  *Returns:* `true` only if `x` and `y` represent the same thread of
104
  execution or neither `x` nor `y` represents a thread of execution.
105
 
106
  ``` cpp
107
- bool operator!=(thread::id x, thread::id y) noexcept;
108
  ```
109
 
110
- *Returns:* `!(x == y)`
 
111
 
112
- ``` cpp
113
- bool operator<(thread::id x, thread::id y) noexcept;
114
- ```
115
-
116
- *Returns:* A value such that `operator<` is a total ordering as
117
- described in  [[alg.sorting]].
118
-
119
- ``` cpp
120
- bool operator<=(thread::id x, thread::id y) noexcept;
121
- ```
122
-
123
- *Returns:* `!(y < x)`.
124
-
125
- ``` cpp
126
- bool operator>(thread::id x, thread::id y) noexcept;
127
- ```
128
-
129
- *Returns:* `y < x`.
130
-
131
- ``` cpp
132
- bool operator>=(thread::id x, thread::id y) noexcept;
133
- ```
134
-
135
- *Returns:* `!(x < y)`.
136
 
137
  ``` cpp
138
  template<class charT, class traits>
139
  basic_ostream<charT, traits>&
140
  operator<< (basic_ostream<charT, traits>& out, thread::id id);
141
  ```
142
 
143
  *Effects:* Inserts an unspecified text representation of `id` into
144
  `out`. For two objects of type `thread::id` `x` and `y`, if `x == y` the
145
- `thread::id` objects shall have the same text representation and if
146
- `x != y` the `thread::id` objects shall have distinct text
147
- representations.
148
 
149
  *Returns:* `out`.
150
 
151
  ``` cpp
152
  template<> struct hash<thread::id>;
153
  ```
154
 
155
- The specialization is enabled ([[unord.hash]]).
156
 
157
- #### `thread` constructors <a id="thread.thread.constr">[[thread.thread.constr]]</a>
158
 
159
  ``` cpp
160
  thread() noexcept;
161
  ```
162
 
163
- *Effects:* Constructs a `thread` object that does not represent a thread
164
- of execution.
165
 
166
- *Postconditions:* `get_id() == id()`.
167
 
168
  ``` cpp
169
  template<class F, class... Args> explicit thread(F&& f, Args&&... args);
170
  ```
171
 
172
- *Requires:*  `F` and each `Ti` in `Args` shall satisfy the
173
- `MoveConstructible` requirements.
174
- ` `*`INVOKE`*`( `*`DECAY_COPY`*`( std::forward<F>(f)), `*`DECAY_COPY`*`( std::forward<Args>(args))...)` ([[func.require]])
175
- shall be a valid expression.
176
-
177
- *Remarks:* This constructor shall not participate in overload resolution
178
- if `decay_t<F>` is the same type as `std::thread`.
179
-
180
- *Effects:*  Constructs an object of type `thread`. The new thread of
181
- execution executes
182
- ` `*`INVOKE`*`( `*`DECAY_COPY`*`( std::forward<F>(f)), `*`DECAY_COPY`*`( std::forward<Args>(args))...)`
183
- with the calls to *`DECAY_COPY`* being evaluated in the constructing
 
 
 
 
 
 
 
 
184
  thread. Any return value from this invocation is ignored.
185
 
186
  [*Note 1*: This implies that any exceptions not thrown from the
187
  invocation of the copy of `f` will be thrown in the constructing thread,
188
  not the new thread. — *end note*]
189
 
190
- If the invocation of
191
- ` `*`INVOKE`*`( `*`DECAY_COPY`*`( std::forward<F>(f)), `*`DECAY_COPY`*`( std::forward<Args>(args))...)`
192
- terminates with an uncaught exception, `terminate` shall be called.
193
 
194
  *Synchronization:* The completion of the invocation of the constructor
195
  synchronizes with the beginning of the invocation of the copy of `f`.
196
 
197
- *Postconditions:* `get_id() != id()`. `*this` represents the newly
198
- started thread.
199
 
200
  *Throws:* `system_error` if unable to start the new thread.
201
 
202
  *Error conditions:*
203
 
@@ -207,45 +186,43 @@ started thread.
207
 
208
  ``` cpp
209
  thread(thread&& x) noexcept;
210
  ```
211
 
212
- *Effects:* Constructs an object of type `thread` from `x`, and sets `x`
213
- to a default constructed state.
214
 
215
- *Postconditions:* `x.get_id() == id()` and `get_id()` returns the value
216
- of `x.get_id()` prior to the start of construction.
217
-
218
- #### `thread` destructor <a id="thread.thread.destr">[[thread.thread.destr]]</a>
219
 
220
  ``` cpp
221
  ~thread();
222
  ```
223
 
224
- If `joinable()`, calls `terminate()`. Otherwise, has no effects.
 
225
 
226
  [*Note 1*: Either implicitly detaching or joining a `joinable()` thread
227
  in its destructor could result in difficult to debug correctness (for
228
  detach) or performance (for join) bugs encountered only when an
229
  exception is thrown. Thus the programmer must ensure that the destructor
230
  is never executed while the thread is still joinable. — *end note*]
231
 
232
- #### `thread` assignment <a id="thread.thread.assign">[[thread.thread.assign]]</a>
233
 
234
  ``` cpp
235
  thread& operator=(thread&& x) noexcept;
236
  ```
237
 
238
  *Effects:* If `joinable()`, calls `terminate()`. Otherwise, assigns the
239
  state of `x` to `*this` and sets `x` to a default constructed state.
240
 
241
- *Postconditions:* `x.get_id() == id()` and `get_id()` returns the value
242
- of `x.get_id()` prior to the assignment.
243
 
244
  *Returns:* `*this`.
245
 
246
- #### `thread` members <a id="thread.thread.member">[[thread.thread.member]]</a>
247
 
248
  ``` cpp
249
  void swap(thread& x) noexcept;
250
  ```
251
 
@@ -259,24 +236,23 @@ bool joinable() const noexcept;
259
 
260
  ``` cpp
261
  void join();
262
  ```
263
 
264
- *Effects:*  Blocks until the thread represented by `*this` has
265
- completed.
266
 
267
  *Synchronization:* The completion of the thread represented by `*this`
268
- synchronizes with ([[intro.multithread]]) the corresponding successful
269
  `join()` return.
270
 
271
  [*Note 1*: Operations on `*this` are not synchronized. — *end note*]
272
 
273
- *Postconditions:* The thread represented by `*this` has completed.
274
  `get_id() == id()`.
275
 
276
  *Throws:* `system_error` when an exception is
277
- required ([[thread.req.exception]]).
278
 
279
  *Error conditions:*
280
 
281
  - `resource_deadlock_would_occur` — if deadlock is detected or
282
  `get_id() == this_thread::get_id()`.
@@ -289,16 +265,16 @@ void detach();
289
 
290
  *Effects:* The thread represented by `*this` continues execution without
291
  the calling thread blocking. When `detach()` returns, `*this` no longer
292
  represents the possibly continuing thread of execution. When the thread
293
  previously represented by `*this` ends execution, the implementation
294
- shall release any owned resources.
295
 
296
- *Postconditions:* `get_id() == id()`.
297
 
298
  *Throws:* `system_error` when an exception is
299
- required ([[thread.req.exception]]).
300
 
301
  *Error conditions:*
302
 
303
  - `no_such_process` — if the thread is not valid.
304
  - `invalid_argument` — if the thread is not joinable.
@@ -309,25 +285,25 @@ id get_id() const noexcept;
309
 
310
  *Returns:* A default constructed `id` object if `*this` does not
311
  represent a thread, otherwise `this_thread::get_id()` for the thread of
312
  execution represented by `*this`.
313
 
314
- #### `thread` static members <a id="thread.thread.static">[[thread.thread.static]]</a>
315
 
316
  ``` cpp
317
  unsigned hardware_concurrency() noexcept;
318
  ```
319
 
320
  *Returns:* The number of hardware thread contexts.
321
 
322
  [*Note 1*: This value should only be considered to be a
323
  hint. — *end note*]
324
 
325
- If this value is not computable or well defined an implementation should
326
- return 0.
327
 
328
- #### `thread` specialized algorithms <a id="thread.thread.algorithm">[[thread.thread.algorithm]]</a>
329
 
330
  ``` cpp
331
  void swap(thread& x, thread& y) noexcept;
332
  ```
333
 
 
17
 
18
  ``` cpp
19
  namespace std {
20
  class thread {
21
  public:
22
+ // types
23
  class id;
24
+ using native_handle_type = implementation-defined; // see~[thread.req.native]
25
 
26
+ // construct/copy/destroy
27
  thread() noexcept;
28
  template<class F, class... Args> explicit thread(F&& f, Args&&... args);
29
  ~thread();
30
  thread(const thread&) = delete;
31
  thread(thread&&) noexcept;
32
  thread& operator=(const thread&) = delete;
33
  thread& operator=(thread&&) noexcept;
34
 
35
+ // members
36
  void swap(thread&) noexcept;
37
  bool joinable() const noexcept;
38
  void join();
39
  void detach();
40
  id get_id() const noexcept;
41
+ native_handle_type native_handle(); // see~[thread.req.native]
42
 
43
+ // static members
44
+ static unsigned int hardware_concurrency() noexcept;
45
  };
46
  }
47
  ```
48
 
49
  #### Class `thread::id` <a id="thread.thread.id">[[thread.thread.id]]</a>
 
54
  public:
55
  id() noexcept;
56
  };
57
 
58
  bool operator==(thread::id x, thread::id y) noexcept;
59
+ strong_ordering operator<=>(thread::id x, thread::id y) noexcept;
 
 
 
 
60
 
61
  template<class charT, class traits>
62
  basic_ostream<charT, traits>&
63
  operator<<(basic_ostream<charT, traits>& out, thread::id id);
64
 
65
+ // hash support
66
  template<class T> struct hash;
67
  template<> struct hash<thread::id>;
68
  }
69
  ```
70
 
71
  An object of type `thread::id` provides a unique identifier for each
72
  thread of execution and a single distinct value for all `thread` objects
73
+ that do not represent a thread of execution [[thread.thread.class]].
74
  Each thread of execution has an associated `thread::id` object that is
75
  not equal to the `thread::id` object of any other thread of execution
76
  and that is not equal to the `thread::id` object of any `thread` object
77
  that does not represent threads of execution.
78
 
79
+ `thread::id` is a trivially copyable class [[class.prop]]. The library
80
+ may reuse the value of a `thread::id` of a terminated thread that can no
81
+ longer be joined.
82
 
83
  [*Note 1*: Relational operators allow `thread::id` objects to be used
84
  as keys in associative containers. — *end note*]
85
 
86
  ``` cpp
87
  id() noexcept;
88
  ```
89
 
90
+ *Ensures:* The constructed object does not represent a thread of
 
 
91
  execution.
92
 
93
  ``` cpp
94
  bool operator==(thread::id x, thread::id y) noexcept;
95
  ```
96
 
97
  *Returns:* `true` only if `x` and `y` represent the same thread of
98
  execution or neither `x` nor `y` represents a thread of execution.
99
 
100
  ``` cpp
101
+ strong_ordering operator<=>(thread::id x, thread::id y) noexcept;
102
  ```
103
 
104
+ Let P(`x`, `y`) be an unspecified total ordering over `thread::id` as
105
+ described in [[alg.sorting]].
106
 
107
+ *Returns:* `strong_ordering::less` if P(`x`, `y`) is `true`. Otherwise,
108
+ `strong_ordering::greater` if P(`y`, `x`) is `true`. Otherwise,
109
+ `strong_ordering::equal`.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
110
 
111
  ``` cpp
112
  template<class charT, class traits>
113
  basic_ostream<charT, traits>&
114
  operator<< (basic_ostream<charT, traits>& out, thread::id id);
115
  ```
116
 
117
  *Effects:* Inserts an unspecified text representation of `id` into
118
  `out`. For two objects of type `thread::id` `x` and `y`, if `x == y` the
119
+ `thread::id` objects have the same text representation and if `x != y`
120
+ the `thread::id` objects have distinct text representations.
 
121
 
122
  *Returns:* `out`.
123
 
124
  ``` cpp
125
  template<> struct hash<thread::id>;
126
  ```
127
 
128
+ The specialization is enabled [[unord.hash]].
129
 
130
+ #### Constructors <a id="thread.thread.constr">[[thread.thread.constr]]</a>
131
 
132
  ``` cpp
133
  thread() noexcept;
134
  ```
135
 
136
+ *Effects:* The object does not represent a thread of execution.
 
137
 
138
+ *Ensures:* `get_id() == id()`.
139
 
140
  ``` cpp
141
  template<class F, class... Args> explicit thread(F&& f, Args&&... args);
142
  ```
143
 
144
+ *Constraints:* `remove_cvref_t<F>` is not the same type as `thread`.
145
+
146
+ *Mandates:* The following are all `true`:
147
+
148
+ - `is_constructible_v<decay_t<F>, F>`,
149
+ - `(is_constructible_v<decay_t<Args>, Args> && ...)`,
150
+ - `is_move_constructible_v<decay_t<F>>`,
151
+ - `(is_move_constructible_v<decay_t<Args>> && ...)`, and
152
+ - `is_invocable_v<decay_t<F>, decay_t<Args>...>`.
153
+
154
+ *Preconditions:* `decay_t<F>` and each type in `decay_t<Args>` meet the
155
+ *Cpp17MoveConstructible* requirements.
156
+
157
+ *Effects:* The new thread of execution executes
158
+
159
+ ``` cpp
160
+ invoke(decay-copy(std::forward<F>(f)), decay-copy(std::forward<Args>(args))...)
161
+ ```
162
+
163
+ with the calls to *`decay-copy`* being evaluated in the constructing
164
  thread. Any return value from this invocation is ignored.
165
 
166
  [*Note 1*: This implies that any exceptions not thrown from the
167
  invocation of the copy of `f` will be thrown in the constructing thread,
168
  not the new thread. — *end note*]
169
 
170
+ If the invocation of `invoke` terminates with an uncaught exception,
171
+ `terminate` is called.
 
172
 
173
  *Synchronization:* The completion of the invocation of the constructor
174
  synchronizes with the beginning of the invocation of the copy of `f`.
175
 
176
+ *Ensures:* `get_id() != id()`. `*this` represents the newly started
177
+ thread.
178
 
179
  *Throws:* `system_error` if unable to start the new thread.
180
 
181
  *Error conditions:*
182
 
 
186
 
187
  ``` cpp
188
  thread(thread&& x) noexcept;
189
  ```
190
 
191
+ *Ensures:* `x.get_id() == id()` and `get_id()` returns the value of
192
+ `x.get_id()` prior to the start of construction.
193
 
194
+ #### Destructor <a id="thread.thread.destr">[[thread.thread.destr]]</a>
 
 
 
195
 
196
  ``` cpp
197
  ~thread();
198
  ```
199
 
200
+ *Effects:* If `joinable()`, calls `terminate()`. Otherwise, has no
201
+ effects.
202
 
203
  [*Note 1*: Either implicitly detaching or joining a `joinable()` thread
204
  in its destructor could result in difficult to debug correctness (for
205
  detach) or performance (for join) bugs encountered only when an
206
  exception is thrown. Thus the programmer must ensure that the destructor
207
  is never executed while the thread is still joinable. — *end note*]
208
 
209
+ #### Assignment <a id="thread.thread.assign">[[thread.thread.assign]]</a>
210
 
211
  ``` cpp
212
  thread& operator=(thread&& x) noexcept;
213
  ```
214
 
215
  *Effects:* If `joinable()`, calls `terminate()`. Otherwise, assigns the
216
  state of `x` to `*this` and sets `x` to a default constructed state.
217
 
218
+ *Ensures:* `x.get_id() == id()` and `get_id()` returns the value of
219
+ `x.get_id()` prior to the assignment.
220
 
221
  *Returns:* `*this`.
222
 
223
+ #### Members <a id="thread.thread.member">[[thread.thread.member]]</a>
224
 
225
  ``` cpp
226
  void swap(thread& x) noexcept;
227
  ```
228
 
 
236
 
237
  ``` cpp
238
  void join();
239
  ```
240
 
241
+ *Effects:* Blocks until the thread represented by `*this` has completed.
 
242
 
243
  *Synchronization:* The completion of the thread represented by `*this`
244
+ synchronizes with [[intro.multithread]] the corresponding successful
245
  `join()` return.
246
 
247
  [*Note 1*: Operations on `*this` are not synchronized. — *end note*]
248
 
249
+ *Ensures:* The thread represented by `*this` has completed.
250
  `get_id() == id()`.
251
 
252
  *Throws:* `system_error` when an exception is
253
+ required [[thread.req.exception]].
254
 
255
  *Error conditions:*
256
 
257
  - `resource_deadlock_would_occur` — if deadlock is detected or
258
  `get_id() == this_thread::get_id()`.
 
265
 
266
  *Effects:* The thread represented by `*this` continues execution without
267
  the calling thread blocking. When `detach()` returns, `*this` no longer
268
  represents the possibly continuing thread of execution. When the thread
269
  previously represented by `*this` ends execution, the implementation
270
+ releases any owned resources.
271
 
272
+ *Ensures:* `get_id() == id()`.
273
 
274
  *Throws:* `system_error` when an exception is
275
+ required [[thread.req.exception]].
276
 
277
  *Error conditions:*
278
 
279
  - `no_such_process` — if the thread is not valid.
280
  - `invalid_argument` — if the thread is not joinable.
 
285
 
286
  *Returns:* A default constructed `id` object if `*this` does not
287
  represent a thread, otherwise `this_thread::get_id()` for the thread of
288
  execution represented by `*this`.
289
 
290
+ #### Static members <a id="thread.thread.static">[[thread.thread.static]]</a>
291
 
292
  ``` cpp
293
  unsigned hardware_concurrency() noexcept;
294
  ```
295
 
296
  *Returns:* The number of hardware thread contexts.
297
 
298
  [*Note 1*: This value should only be considered to be a
299
  hint. — *end note*]
300
 
301
+ If this value is not computable or well-defined, an implementation
302
+ should return 0.
303
 
304
+ #### Specialized algorithms <a id="thread.thread.algorithm">[[thread.thread.algorithm]]</a>
305
 
306
  ``` cpp
307
  void swap(thread& x, thread& y) noexcept;
308
  ```
309