From Jason Turner

[func.wrap.move]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmpympyh0tg/{from.md → to.md} +266 -0
tmp/tmpympyh0tg/{from.md → to.md} RENAMED
@@ -0,0 +1,266 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #### Move only wrapper <a id="func.wrap.move">[[func.wrap.move]]</a>
2
+
3
+ ##### General <a id="func.wrap.move.general">[[func.wrap.move.general]]</a>
4
+
5
+ The header provides partial specializations of `move_only_function` for
6
+ each combination of the possible replacements of the placeholders cv,
7
+ *ref*, and *noex* where
8
+
9
+ - cv is either const or empty,
10
+ - *ref* is either `&`, `&&`, or empty, and
11
+ - *noex* is either `true` or `false`.
12
+
13
+ For each of the possible combinations of the placeholders mentioned
14
+ above, there is a placeholder *inv-quals* defined as follows:
15
+
16
+ - If *ref* is empty, let *inv-quals* be cv`&`,
17
+ - otherwise, let *inv-quals* be cv *ref*.
18
+
19
+ ##### Class template `move_only_function` <a id="func.wrap.move.class">[[func.wrap.move.class]]</a>
20
+
21
+ ``` cpp
22
+ namespace std {
23
+ template<class... S> class move_only_function; // not defined
24
+
25
+ template<class R, class... ArgTypes>
26
+ class move_only_function<R(ArgTypes...) cv ref noexcept(noex)> {
27
+ public:
28
+ using result_type = R;
29
+
30
+ // [func.wrap.move.ctor], constructors, assignment, and destructor
31
+ move_only_function() noexcept;
32
+ move_only_function(nullptr_t) noexcept;
33
+ move_only_function(move_only_function&&) noexcept;
34
+ template<class F> move_only_function(F&&);
35
+ template<class T, class... Args>
36
+ explicit move_only_function(in_place_type_t<T>, Args&&...);
37
+ template<class T, class U, class... Args>
38
+ explicit move_only_function(in_place_type_t<T>, initializer_list<U>, Args&&...);
39
+
40
+ move_only_function& operator=(move_only_function&&);
41
+ move_only_function& operator=(nullptr_t) noexcept;
42
+ template<class F> move_only_function& operator=(F&&);
43
+
44
+ ~move_only_function();
45
+
46
+ // [func.wrap.move.inv], invocation
47
+ explicit operator bool() const noexcept;
48
+ R operator()(ArgTypes...) cv ref noexcept(noex);
49
+
50
+ // [func.wrap.move.util], utility
51
+ void swap(move_only_function&) noexcept;
52
+ friend void swap(move_only_function&, move_only_function&) noexcept;
53
+ friend bool operator==(const move_only_function&, nullptr_t) noexcept;
54
+
55
+ private:
56
+ template<class VT>
57
+ static constexpr bool is-callable-from = see below; // exposition only
58
+ };
59
+ }
60
+ ```
61
+
62
+ The `move_only_function` class template provides polymorphic wrappers
63
+ that generalize the notion of a callable object [[func.def]]. These
64
+ wrappers can store, move, and call arbitrary callable objects, given a
65
+ call signature.
66
+
67
+ *Recommended practice:* Implementations should avoid the use of
68
+ dynamically allocated memory for a small contained value.
69
+
70
+ [*Note 1*: Such small-object optimization can only be applied to a type
71
+ `T` for which `is_nothrow_move_constructible_v<T>` is
72
+ `true`. — *end note*]
73
+
74
+ ##### Constructors, assignment, and destructor <a id="func.wrap.move.ctor">[[func.wrap.move.ctor]]</a>
75
+
76
+ ``` cpp
77
+ template<class VT>
78
+ static constexpr bool is-callable-from = see below;
79
+ ```
80
+
81
+ If *noex* is `true`, *`is-callable-from`*`<VT>` is equal to:
82
+
83
+ ``` cpp
84
+ is_nothrow_invocable_r_v<R, VT cv ref, ArgTypes...> &&
85
+ is_nothrow_invocable_r_v<R, VT inv-quals, ArgTypes...>
86
+ ```
87
+
88
+ Otherwise, *`is-callable-from`*`<VT>` is equal to:
89
+
90
+ ``` cpp
91
+ is_invocable_r_v<R, VT cv ref, ArgTypes...> &&
92
+ is_invocable_r_v<R, VT inv-quals, ArgTypes...>
93
+ ```
94
+
95
+ ``` cpp
96
+ move_only_function() noexcept;
97
+ move_only_function(nullptr_t) noexcept;
98
+ ```
99
+
100
+ *Ensures:* `*this` has no target object.
101
+
102
+ ``` cpp
103
+ move_only_function(move_only_function&& f) noexcept;
104
+ ```
105
+
106
+ *Ensures:* The target object of `*this` is the target object `f` had
107
+ before construction, and `f` is in a valid state with an unspecified
108
+ value.
109
+
110
+ ``` cpp
111
+ template<class F> move_only_function(F&& f);
112
+ ```
113
+
114
+ Let `VT` be `decay_t<F>`.
115
+
116
+ *Constraints:*
117
+
118
+ - `remove_cvref_t<F>` is not the same type as `move_only_function`, and
119
+ - `remove_cvref_t<F>` is not a specialization of `in_place_type_t`, and
120
+ - *`is-callable-from`*`<VT>` is `true`.
121
+
122
+ *Mandates:* `is_constructible_v<VT, F>` is `true`.
123
+
124
+ *Preconditions:* `VT` meets the *Cpp17Destructible* requirements, and if
125
+ `is_move_constructible_v<VT>` is `true`, `VT` meets the
126
+ *Cpp17MoveConstructible* requirements.
127
+
128
+ *Ensures:* `*this` has no target object if any of the following hold:
129
+
130
+ - `f` is a null function pointer value, or
131
+ - `f` is a null member pointer value, or
132
+ - `remove_cvref_t<F>` is a specialization of the `move_only_function`
133
+ class template, and `f` has no target object.
134
+
135
+ Otherwise, `*this` has a target object of type `VT`
136
+ direct-non-list-initialized with `std::forward<F>(f)`.
137
+
138
+ *Throws:* Any exception thrown by the initialization of the target
139
+ object. May throw `bad_alloc` unless `VT` is a function pointer or a
140
+ specialization of `reference_wrapper`.
141
+
142
+ ``` cpp
143
+ template<class T, class... Args>
144
+ explicit move_only_function(in_place_type_t<T>, Args&&... args);
145
+ ```
146
+
147
+ Let `VT` be `decay_t<T>`.
148
+
149
+ *Constraints:*
150
+
151
+ - `is_constructible_v<VT, Args...>` is `true`, and
152
+ - *`is-callable-from`*`<VT>` is `true`.
153
+
154
+ *Mandates:* `VT` is the same type as `T`.
155
+
156
+ *Preconditions:* `VT` meets the *Cpp17Destructible* requirements, and if
157
+ `is_move_constructible_v<VT>` is `true`, `VT` meets the
158
+ *Cpp17MoveConstructible* requirements.
159
+
160
+ *Ensures:* `*this` has a target object of type `VT`
161
+ direct-non-list-initialized with `std::forward<Args>(args)...`.
162
+
163
+ *Throws:* Any exception thrown by the initialization of the target
164
+ object. May throw `bad_alloc` unless `VT` is a function pointer or a
165
+ specialization of `reference_wrapper`.
166
+
167
+ ``` cpp
168
+ template<class T, class U, class... Args>
169
+ explicit move_only_function(in_place_type_t<T>, initializer_list<U> ilist, Args&&... args);
170
+ ```
171
+
172
+ Let `VT` be `decay_t<T>`.
173
+
174
+ *Constraints:*
175
+
176
+ - `is_constructible_v<VT, initializer_list<U>&, Args...>` is `true`, and
177
+ - *`is-callable-from`*`<VT>` is `true`.
178
+
179
+ *Mandates:* `VT` is the same type as `T`.
180
+
181
+ *Preconditions:* `VT` meets the *Cpp17Destructible* requirements, and if
182
+ `is_move_constructible_v<VT>` is `true`, `VT` meets the
183
+ *Cpp17MoveConstructible* requirements.
184
+
185
+ *Ensures:* `*this` has a target object of type `VT`
186
+ direct-non-list-initialized with `ilist, std::forward<Args>(args)...`.
187
+
188
+ *Throws:* Any exception thrown by the initialization of the target
189
+ object. May throw `bad_alloc` unless `VT` is a function pointer or a
190
+ specialization of `reference_wrapper`.
191
+
192
+ ``` cpp
193
+ move_only_function& operator=(move_only_function&& f);
194
+ ```
195
+
196
+ *Effects:* Equivalent to:
197
+ `move_only_function(std::move(f)).swap(*this);`
198
+
199
+ *Returns:* `*this`.
200
+
201
+ ``` cpp
202
+ move_only_function& operator=(nullptr_t) noexcept;
203
+ ```
204
+
205
+ *Effects:* Destroys the target object of `*this`, if any.
206
+
207
+ *Returns:* `*this`.
208
+
209
+ ``` cpp
210
+ template<class F> move_only_function& operator=(F&& f);
211
+ ```
212
+
213
+ *Effects:* Equivalent to:
214
+ `move_only_function(std::forward<F>(f)).swap(*this);`
215
+
216
+ *Returns:* `*this`.
217
+
218
+ ``` cpp
219
+ ~move_only_function();
220
+ ```
221
+
222
+ *Effects:* Destroys the target object of `*this`, if any.
223
+
224
+ ##### Invocation <a id="func.wrap.move.inv">[[func.wrap.move.inv]]</a>
225
+
226
+ ``` cpp
227
+ explicit operator bool() const noexcept;
228
+ ```
229
+
230
+ *Returns:* `true` if `*this` has a target object, otherwise `false`.
231
+
232
+ ``` cpp
233
+ R operator()(ArgTypes... args) cv ref noexcept(noex);
234
+ ```
235
+
236
+ *Preconditions:* `*this` has a target object.
237
+
238
+ *Effects:* Equivalent to:
239
+
240
+ ``` cpp
241
+ return INVOKE<R>(static_cast<F inv-quals>(f), std::forward<ArgTypes>(args)...);
242
+ ```
243
+
244
+ where `f` is an lvalue designating the target object of `*this` and `F`
245
+ is the type of `f`.
246
+
247
+ ##### Utility <a id="func.wrap.move.util">[[func.wrap.move.util]]</a>
248
+
249
+ ``` cpp
250
+ void swap(move_only_function& other) noexcept;
251
+ ```
252
+
253
+ *Effects:* Exchanges the target objects of `*this` and `other`.
254
+
255
+ ``` cpp
256
+ friend void swap(move_only_function& f1, move_only_function& f2) noexcept;
257
+ ```
258
+
259
+ *Effects:* Equivalent to `f1.swap(f2)`.
260
+
261
+ ``` cpp
262
+ friend bool operator==(const move_only_function& f, nullptr_t) noexcept;
263
+ ```
264
+
265
+ *Returns:* `true` if `f` has no target object, otherwise `false`.
266
+