From Jason Turner

[optional]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmpj_8xh13b/{from.md → to.md} +308 -329
tmp/tmpj_8xh13b/{from.md → to.md} RENAMED
@@ -1,20 +1,22 @@
1
  ## Optional objects <a id="optional">[[optional]]</a>
2
 
3
  ### In general <a id="optional.general">[[optional.general]]</a>
4
 
5
- This subclause describes class template `optional` that represents
6
- optional objects. An *optional object* is an object that contains the
7
- storage for another object and manages the lifetime of this contained
8
- object, if any. The contained object may be initialized after the
9
- optional object has been initialized, and may be destroyed before the
10
- optional object has been destroyed. The initialization state of the
11
  contained object is tracked by the optional object.
12
 
13
  ### Header `<optional>` synopsis <a id="optional.syn">[[optional.syn]]</a>
14
 
15
  ``` cpp
 
 
16
  namespace std {
17
  // [optional.optional], class template optional
18
  template<class T>
19
  class optional;
20
 
@@ -36,38 +38,35 @@ namespace std {
36
  constexpr bool operator>(const optional<T>&, const optional<U>&);
37
  template<class T, class U>
38
  constexpr bool operator<=(const optional<T>&, const optional<U>&);
39
  template<class T, class U>
40
  constexpr bool operator>=(const optional<T>&, const optional<U>&);
 
 
 
41
 
42
  // [optional.nullops], comparison with nullopt
43
  template<class T> constexpr bool operator==(const optional<T>&, nullopt_t) noexcept;
44
- template <class T> constexpr bool operator==(nullopt_t, const optional<T>&) noexcept;
45
- template <class T> constexpr bool operator!=(const optional<T>&, nullopt_t) noexcept;
46
- template <class T> constexpr bool operator!=(nullopt_t, const optional<T>&) noexcept;
47
- template <class T> constexpr bool operator<(const optional<T>&, nullopt_t) noexcept;
48
- template <class T> constexpr bool operator<(nullopt_t, const optional<T>&) noexcept;
49
- template <class T> constexpr bool operator<=(const optional<T>&, nullopt_t) noexcept;
50
- template <class T> constexpr bool operator<=(nullopt_t, const optional<T>&) noexcept;
51
- template <class T> constexpr bool operator>(const optional<T>&, nullopt_t) noexcept;
52
- template <class T> constexpr bool operator>(nullopt_t, const optional<T>&) noexcept;
53
- template <class T> constexpr bool operator>=(const optional<T>&, nullopt_t) noexcept;
54
- template <class T> constexpr bool operator>=(nullopt_t, const optional<T>&) noexcept;
55
 
56
- // [optional.comp_with_t], comparison with T
57
  template<class T, class U> constexpr bool operator==(const optional<T>&, const U&);
58
- template <class T, class U> constexpr bool operator==(const U&, const optional<T>&);
59
  template<class T, class U> constexpr bool operator!=(const optional<T>&, const U&);
60
- template <class T, class U> constexpr bool operator!=(const U&, const optional<T>&);
61
  template<class T, class U> constexpr bool operator<(const optional<T>&, const U&);
62
- template <class T, class U> constexpr bool operator<(const U&, const optional<T>&);
63
- template <class T, class U> constexpr bool operator<=(const optional<T>&, const U&);
64
- template <class T, class U> constexpr bool operator<=(const U&, const optional<T>&);
65
  template<class T, class U> constexpr bool operator>(const optional<T>&, const U&);
66
- template <class T, class U> constexpr bool operator>(const U&, const optional<T>&);
 
 
67
  template<class T, class U> constexpr bool operator>=(const optional<T>&, const U&);
68
- template <class T, class U> constexpr bool operator>=(const U&, const optional<T>&);
 
 
 
69
 
70
  // [optional.specalg], specialized algorithms
71
  template<class T>
72
  void swap(optional<T>&, optional<T>&) noexcept(see below);
73
 
@@ -82,17 +81,14 @@ namespace std {
82
  template<class T> struct hash;
83
  template<class T> struct hash<optional<T>>;
84
  }
85
  ```
86
 
87
- A program that necessitates the instantiation of template `optional` for
88
- a reference type, or for possibly cv-qualified types `in_place_t` or
89
- `nullopt_t` is ill-formed.
90
-
91
  ### Class template `optional` <a id="optional.optional">[[optional.optional]]</a>
92
 
93
  ``` cpp
 
94
  template<class T>
95
  class optional {
96
  public:
97
  using value_type = T;
98
 
@@ -104,23 +100,23 @@ template <class T>
104
  template<class... Args>
105
  constexpr explicit optional(in_place_t, Args&&...);
106
  template<class U, class... Args>
107
  constexpr explicit optional(in_place_t, initializer_list<U>, Args&&...);
108
  template<class U = T>
109
- \EXPLICIT constexpr optional(U&&);
110
  template<class U>
111
- \EXPLICIT optional(const optional<U>&);
112
  template<class U>
113
- \EXPLICIT optional(optional<U>&&);
114
 
115
  // [optional.dtor], destructor
116
  ~optional();
117
 
118
  // [optional.assign], assignment
119
  optional& operator=(nullopt_t) noexcept;
120
- optional& operator=(const optional&);
121
- optional& operator=(optional&&) noexcept(see below);
122
  template<class U = T> optional& operator=(U&&);
123
  template<class U> optional& operator=(const optional<U>&);
124
  template<class U> optional& operator=(optional<U>&&);
125
  template<class... Args> T& emplace(Args&&...);
126
  template<class U, class... Args> T& emplace(initializer_list<U>, Args&&...);
@@ -149,11 +145,13 @@ template <class T>
149
 
150
  private:
151
  T *val; // exposition only
152
  };
153
 
154
- template<class T> optional(T) -> optional<T>;
 
 
155
  ```
156
 
157
  Any instance of `optional<T>` at any given time either contains a value
158
  or does not contain a value. When an instance of `optional<T>` *contains
159
  a value*, it means that an object of type `T`, referred to as the
@@ -167,135 +165,126 @@ returns `true` if the object contains a value; otherwise the conversion
167
  returns `false`.
168
 
169
  Member `val` is provided for exposition only. When an `optional<T>`
170
  object contains a value, `val` points to the contained value.
171
 
172
- `T` shall be an object type and shall satisfy the requirements of
173
- `Destructible` (Table  [[tab:destructible]]).
174
 
175
  #### Constructors <a id="optional.ctor">[[optional.ctor]]</a>
176
 
177
  ``` cpp
178
  constexpr optional() noexcept;
179
  constexpr optional(nullopt_t) noexcept;
180
  ```
181
 
182
- *Postconditions:* `*this` does not contain a value.
183
 
184
  *Remarks:* No contained value is initialized. For every object type `T`
185
- these constructors shall be constexpr constructors ([[dcl.constexpr]]).
186
 
187
  ``` cpp
188
  constexpr optional(const optional& rhs);
189
  ```
190
 
191
  *Effects:* If `rhs` contains a value, initializes the contained value as
192
  if direct-non-list-initializing an object of type `T` with the
193
  expression `*rhs`.
194
 
195
- *Postconditions:* `bool(rhs) == bool(*this)`.
196
 
197
  *Throws:* Any exception thrown by the selected constructor of `T`.
198
 
199
- *Remarks:* This constructor shall be defined as deleted unless
200
  `is_copy_constructible_v<T>` is `true`. If
201
- `is_trivially_copy_constructible_v<T>` is `true`, this constructor shall
202
- be a `constexpr` constructor.
203
 
204
  ``` cpp
205
  constexpr optional(optional&& rhs) noexcept(see below);
206
  ```
207
 
 
 
208
  *Effects:* If `rhs` contains a value, initializes the contained value as
209
  if direct-non-list-initializing an object of type `T` with the
210
  expression `std::move(*rhs)`. `bool(rhs)` is unchanged.
211
 
212
- *Postconditions:* `bool(rhs) == bool(*this)`.
213
 
214
  *Throws:* Any exception thrown by the selected constructor of `T`.
215
 
216
  *Remarks:* The expression inside `noexcept` is equivalent to
217
- `is_nothrow_move_constructible_v<T>`. This constructor shall not
218
- participate in overload resolution unless `is_move_constructible_v<T>`
219
- is `true`. If `is_trivially_move_constructible_v<T>` is `true`, this
220
- constructor shall be a `constexpr` constructor.
221
 
222
  ``` cpp
223
  template<class... Args> constexpr explicit optional(in_place_t, Args&&... args);
224
  ```
225
 
 
 
226
  *Effects:* Initializes the contained value as if
227
  direct-non-list-initializing an object of type `T` with the arguments
228
  `std::forward<Args>(args)...`.
229
 
230
- *Postconditions:* `*this` contains a value.
231
 
232
  *Throws:* Any exception thrown by the selected constructor of `T`.
233
 
234
  *Remarks:* If `T`’s constructor selected for the initialization is a
235
- constexpr constructor, this constructor shall be a constexpr
236
- constructor. This constructor shall not participate in overload
237
- resolution unless `is_constructible_v<T, Args...>` is `true`.
238
 
239
  ``` cpp
240
  template<class U, class... Args>
241
  constexpr explicit optional(in_place_t, initializer_list<U> il, Args&&... args);
242
  ```
243
 
 
 
 
244
  *Effects:* Initializes the contained value as if
245
  direct-non-list-initializing an object of type `T` with the arguments
246
  `il, std::forward<Args>(args)...`.
247
 
248
- *Postconditions:* `*this` contains a value.
249
 
250
  *Throws:* Any exception thrown by the selected constructor of `T`.
251
 
252
- *Remarks:* This constructor shall not participate in overload resolution
253
- unless `is_constructible_v<T, initializer_list<U>&, Args&&...>` is
254
- `true`. If `T`’s constructor selected for the initialization is a
255
- constexpr constructor, this constructor shall be a constexpr
256
- constructor.
257
-
258
- [*Note 1*: The following constructors are conditionally specified as
259
- explicit. This is typically implemented by declaring two such
260
- constructors, of which at most one participates in overload
261
- resolution. — *end note*]
262
 
263
  ``` cpp
264
- template <class U = T> \EXPLICIT constexpr optional(U&& v);
265
  ```
266
 
 
 
 
 
267
  *Effects:* Initializes the contained value as if
268
  direct-non-list-initializing an object of type `T` with the expression
269
  `std::forward<U>(v)`.
270
 
271
- *Postconditions:* `*this` contains a value.
272
 
273
  *Throws:* Any exception thrown by the selected constructor of `T`.
274
 
275
  *Remarks:* If `T`’s selected constructor is a constexpr constructor,
276
- this constructor shall be a constexpr constructor. This constructor
277
- shall not participate in overload resolution unless
278
- `is_constructible_v<T, U&&>` is `true`,
279
- `is_same_v<decay_t<U>, in_place_t>` is `false`, and
280
- `is_same_v<optional<T>, decay_t<U>>` is `false`. The constructor is
281
- explicit if and only if `is_convertible_v<U&&, T>` is `false`.
282
 
283
  ``` cpp
284
- template <class U> \EXPLICIT optional(const optional<U>& rhs);
285
  ```
286
 
287
- *Effects:* If `rhs` contains a value, initializes the contained value as
288
- if direct-non-list-initializing an object of type `T` with the
289
- expression `*rhs`.
290
-
291
- *Postconditions:* `bool(rhs)` == `bool(*this)`.
292
-
293
- *Throws:* Any exception thrown by the selected constructor of `T`.
294
 
295
- *Remarks:* This constructor shall not participate in overload resolution
296
- unless
297
 
298
  - `is_constructible_v<T, const U&>` is `true`,
299
  - `is_constructible_v<T, optional<U>&>` is `false`,
300
  - `is_constructible_v<T, optional<U>&&>` is `false`,
301
  - `is_constructible_v<T, const optional<U>&>` is `false`,
@@ -303,40 +292,53 @@ unless
303
  - `is_convertible_v<optional<U>&, T>` is `false`,
304
  - `is_convertible_v<optional<U>&&, T>` is `false`,
305
  - `is_convertible_v<const optional<U>&, T>` is `false`, and
306
  - `is_convertible_v<const optional<U>&&, T>` is `false`.
307
 
308
- The constructor is explicit if and only if
309
- `is_convertible_v<const U&, T>` is `false`.
 
 
 
 
 
 
 
 
 
 
 
310
 
311
  ``` cpp
312
- template <class U> \EXPLICIT optional(optional<U>&& rhs);
313
  ```
314
 
 
 
 
 
 
 
 
 
 
 
 
 
315
  *Effects:* If `rhs` contains a value, initializes the contained value as
316
  if direct-non-list-initializing an object of type `T` with the
317
  expression `std::move(*rhs)`. `bool(rhs)` is unchanged.
318
 
319
- *Postconditions:* `bool(rhs)` == `bool(*this)`.
320
 
321
  *Throws:* Any exception thrown by the selected constructor of `T`.
322
 
323
- *Remarks:* This constructor shall not participate in overload resolution
324
- unless
325
 
326
- - `is_constructible_v<T, U&&>` is true,
327
- - `is_constructible_v<T, optional<U>&>` is `false`,
328
- - `is_constructible_v<T, optional<U>&&>` is `false`,
329
- - `is_constructible_v<T, const optional<U>&>` is `false`,
330
- - `is_constructible_v<T, const optional<U>&&>` is `false`,
331
- - `is_convertible_v<optional<U>&, T>` is `false`,
332
- - `is_convertible_v<optional<U>&&, T>` is `false`,
333
- - `is_convertible_v<const optional<U>&, T>` is `false`, and
334
- - `is_convertible_v<const optional<U>&&, T>` is `false`.
335
-
336
- The constructor is explicit if and only if `is_convertible_v<U&&, T>` is
337
- `false`.
338
 
339
  #### Destructor <a id="optional.dtor">[[optional.dtor]]</a>
340
 
341
  ``` cpp
342
  ~optional();
@@ -347,72 +349,77 @@ contains a value, calls
347
 
348
  ``` cpp
349
  val->T::~T()
350
  ```
351
 
352
- *Remarks:* If `is_trivially_destructible_v<T> == true` then this
353
- destructor shall be a trivial destructor.
354
 
355
  #### Assignment <a id="optional.assign">[[optional.assign]]</a>
356
 
357
  ``` cpp
358
  optional<T>& operator=(nullopt_t) noexcept;
359
  ```
360
 
361
  *Effects:* If `*this` contains a value, calls `val->T::T̃()` to destroy
362
  the contained value; otherwise no effect.
363
 
364
- *Returns:* `*this`.
365
 
366
- *Postconditions:* `*this` does not contain a value.
367
 
368
  ``` cpp
369
- optional<T>& operator=(const optional& rhs);
370
  ```
371
 
372
- *Effects:* See Table  [[tab:optional.assign.copy]].
373
 
374
- **Table: `optional::operator=(const optional&)` effects** <a id="tab:optional.assign.copy">[tab:optional.assign.copy]</a>
375
 
376
  | | `*this` contains a value | `*this` does not contain a value |
377
  | ------------------------------ | ------------------------------------------------------ | ---------------------------------------------------------------------------------------------------- |
378
  | `rhs` contains a value | assigns `*rhs` to the contained value | initializes the contained value as if direct-non-list-initializing an object of type `T` with `*rhs` |
379
  | `rhs` does not contain a value | destroys the contained value by calling `val->T::~T()` | no effect |
380
 
381
 
382
- *Returns:* `*this`.
383
 
384
- *Postconditions:* `bool(rhs) == bool(*this)`.
385
 
386
  *Remarks:* If any exception is thrown, the result of the expression
387
  `bool(*this)` remains unchanged. If an exception is thrown during the
388
  call to `T`’s copy constructor, no effect. If an exception is thrown
389
  during the call to `T`’s copy assignment, the state of its contained
390
  value is as defined by the exception safety guarantee of `T`’s copy
391
- assignment. This operator shall be defined as deleted unless
392
  `is_copy_constructible_v<T>` is `true` and `is_copy_assignable_v<T>` is
393
- `true`.
 
 
394
 
395
  ``` cpp
396
- optional<T>& operator=(optional&& rhs) noexcept(see below);
397
  ```
398
 
399
- *Effects:* See Table  [[tab:optional.assign.move]]. The result of the
400
- expression `bool(rhs)` remains unchanged.
401
 
402
- **Table: `optional::operator=(optional&&)` effects** <a id="tab:optional.assign.move">[tab:optional.assign.move]</a>
 
 
 
403
 
404
  | | `*this` contains a value | `*this` does not contain a value |
405
  | ------------------------------ | ------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------- |
406
  | `rhs` contains a value | assigns `std::move(*rhs)` to the contained value | initializes the contained value as if direct-non-list-initializing an object of type `T` with `std::move(*rhs)` |
407
  | `rhs` does not contain a value | destroys the contained value by calling `val->T::~T()` | no effect |
408
 
409
 
 
 
410
  *Returns:* `*this`.
411
 
412
- *Postconditions:* `bool(rhs) == bool(*this)`.
413
-
414
  *Remarks:* The expression inside `noexcept` is equivalent to:
415
 
416
  ``` cpp
417
  is_nothrow_move_assignable_v<T> && is_nothrow_move_constructible_v<T>
418
  ```
@@ -421,65 +428,44 @@ If any exception is thrown, the result of the expression `bool(*this)`
421
  remains unchanged. If an exception is thrown during the call to `T`’s
422
  move constructor, the state of `*rhs.val` is determined by the exception
423
  safety guarantee of `T`’s move constructor. If an exception is thrown
424
  during the call to `T`’s move assignment, the state of `*val` and
425
  `*rhs.val` is determined by the exception safety guarantee of `T`’s move
426
- assignment. This operator shall not participate in overload resolution
427
- unless `is_move_constructible_v<T>` is `true` and
428
- `is_move_assignable_v<T>` is `true`.
429
 
430
  ``` cpp
431
  template<class U = T> optional<T>& operator=(U&& v);
432
  ```
433
 
 
 
 
 
 
434
  *Effects:* If `*this` contains a value, assigns `std::forward<U>(v)` to
435
  the contained value; otherwise initializes the contained value as if
436
  direct-non-list-initializing object of type `T` with
437
  `std::forward<U>(v)`.
438
 
439
- *Returns:* `*this`.
440
 
441
- *Postconditions:* `*this` contains a value.
442
 
443
  *Remarks:* If any exception is thrown, the result of the expression
444
  `bool(*this)` remains unchanged. If an exception is thrown during the
445
  call to `T`’s constructor, the state of `v` is determined by the
446
  exception safety guarantee of `T`’s constructor. If an exception is
447
  thrown during the call to `T`’s assignment, the state of `*val` and `v`
448
  is determined by the exception safety guarantee of `T`’s assignment.
449
- This function shall not participate in overload resolution unless
450
- `is_same_v<optional<T>, decay_t<U>>` is `false`,
451
- `conjunction_v<is_scalar<T>, is_same<T, decay_t<U>>>` is `false`,
452
- `is_constructible_v<T, U>` is `true`, and `is_assignable_v<T&, U>` is
453
- `true`.
454
 
455
  ``` cpp
456
  template<class U> optional<T>& operator=(const optional<U>& rhs);
457
  ```
458
 
459
- *Effects:* See Table  [[tab:optional.assign.copy.templ]].
460
-
461
- **Table: `optional::operator=(const optional<U>&)` effects** <a id="tab:optional.assign.copy.templ">[tab:optional.assign.copy.templ]</a>
462
-
463
- | | `*this` contains a value | `*this` does not contain a value |
464
- | ------------------------------ | ------------------------------------------------------ | ---------------------------------------------------------------------------------------------------- |
465
- | `rhs` contains a value | assigns `*rhs` to the contained value | initializes the contained value as if direct-non-list-initializing an object of type `T` with `*rhs` |
466
- | `rhs` does not contain a value | destroys the contained value by calling `val->T::~T()` | no effect |
467
-
468
-
469
- *Returns:* `*this`.
470
-
471
- *Postconditions:* `bool(rhs) == bool(*this)`.
472
-
473
- *Remarks:* If any exception is thrown, the result of the expression
474
- `bool(*this)` remains unchanged. If an exception is thrown during the
475
- call to `T`’s constructor, the state of `*rhs.val` is determined by the
476
- exception safety guarantee of `T`’s constructor. If an exception is
477
- thrown during the call to `T`’s assignment, the state of `*val` and
478
- `*rhs.val` is determined by the exception safety guarantee of `T`’s
479
- assignment. This function shall not participate in overload resolution
480
- unless
481
 
482
  - `is_constructible_v<T, const U&>` is `true`,
483
  - `is_assignable_v<T&, const U&>` is `true`,
484
  - `is_constructible_v<T, optional<U>&>` is `false`,
485
  - `is_constructible_v<T, optional<U>&&>` is `false`,
@@ -492,37 +478,37 @@ unless
492
  - `is_assignable_v<T&, optional<U>&>` is `false`,
493
  - `is_assignable_v<T&, optional<U>&&>` is `false`,
494
  - `is_assignable_v<T&, const optional<U>&>` is `false`, and
495
  - `is_assignable_v<T&, const optional<U>&&>` is `false`.
496
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
497
  ``` cpp
498
  template<class U> optional<T>& operator=(optional<U>&& rhs);
499
  ```
500
 
501
- *Effects:* See Table  [[tab:optional.assign.move.templ]]. The result of
502
- the expression `bool(rhs)` remains unchanged.
503
-
504
- **Table: `optional::operator=(optional<U>&&)` effects** <a id="tab:optional.assign.move.templ">[tab:optional.assign.move.templ]</a>
505
-
506
- | | `*this` contains a value | `*this` does not contain a value |
507
- | ------------------------------ | ------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------- |
508
- | `rhs` contains a value | assigns `std::move(*rhs)` to the contained value | initializes the contained value as if direct-non-list-initializing an object of type `T` with `std::move(*rhs)` |
509
- | `rhs` does not contain a value | destroys the contained value by calling `val->T::~T()` | no effect |
510
-
511
-
512
- *Returns:* `*this`.
513
-
514
- *Postconditions:* `bool(rhs) == bool(*this)`.
515
-
516
- *Remarks:* If any exception is thrown, the result of the expression
517
- `bool(*this)` remains unchanged. If an exception is thrown during the
518
- call to `T`’s constructor, the state of `*rhs.val` is determined by the
519
- exception safety guarantee of `T`’s constructor. If an exception is
520
- thrown during the call to `T`’s assignment, the state of `*val` and
521
- `*rhs.val` is determined by the exception safety guarantee of `T`’s
522
- assignment. This function shall not participate in overload resolution
523
- unless
524
 
525
  - `is_constructible_v<T, U>` is `true`,
526
  - `is_assignable_v<T&, U>` is `true`,
527
  - `is_constructible_v<T, optional<U>&>` is `false`,
528
  - `is_constructible_v<T, optional<U>&&>` is `false`,
@@ -535,21 +521,44 @@ unless
535
  - `is_assignable_v<T&, optional<U>&>` is `false`,
536
  - `is_assignable_v<T&, optional<U>&&>` is `false`,
537
  - `is_assignable_v<T&, const optional<U>&>` is `false`, and
538
  - `is_assignable_v<T&, const optional<U>&&>` is `false`.
539
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
540
  ``` cpp
541
  template<class... Args> T& emplace(Args&&... args);
542
  ```
543
 
544
- *Requires:* `is_constructible_v<T, Args&&...>` is `true`.
545
 
546
  *Effects:* Calls `*this = nullopt`. Then initializes the contained value
547
  as if direct-non-list-initializing an object of type `T` with the
548
  arguments `std::forward<Args>(args)...`.
549
 
550
- *Postconditions:* `*this` contains a value.
551
 
552
  *Returns:* A reference to the new contained value.
553
 
554
  *Throws:* Any exception thrown by the selected constructor of `T`.
555
 
@@ -559,47 +568,49 @@ constructor, `*this` does not contain a value, and the previous `*val`
559
 
560
  ``` cpp
561
  template<class U, class... Args> T& emplace(initializer_list<U> il, Args&&... args);
562
  ```
563
 
 
 
 
564
  *Effects:* Calls `*this = nullopt`. Then initializes the contained value
565
  as if direct-non-list-initializing an object of type `T` with the
566
  arguments `il, std::forward<Args>(args)...`.
567
 
568
- *Postconditions:* `*this` contains a value.
569
 
570
  *Returns:* A reference to the new contained value.
571
 
572
  *Throws:* Any exception thrown by the selected constructor of `T`.
573
 
574
  *Remarks:* If an exception is thrown during the call to `T`’s
575
  constructor, `*this` does not contain a value, and the previous `*val`
576
- (if any) has been destroyed. This function shall not participate in
577
- overload resolution unless
578
- `is_constructible_v<T, initializer_list<U>&, Args&&...>` is `true`.
579
 
580
  #### Swap <a id="optional.swap">[[optional.swap]]</a>
581
 
582
  ``` cpp
583
  void swap(optional& rhs) noexcept(see below);
584
  ```
585
 
586
- *Requires:* Lvalues of type `T` shall be swappable and
587
- `is_move_constructible_v<T>` is `true`.
588
 
589
- *Effects:* See Table  [[tab:optional.swap]].
590
 
591
- **Table: `optional::swap(optional&)` effects** <a id="tab:optional.swap">[tab:optional.swap]</a>
 
 
592
 
593
  | | `*this` contains a value | `*this` does not contain a value |
594
  | ------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
595
  | `rhs` contains a value | calls `swap(*(*this), *rhs)` | initializes the contained value of `*this` as if direct-non-list-initializing an object of type `T` with the expression `std::move(*rhs)`, followed by `rhs.val->T::~T()`; postcondition is that `*this` contains a value and `rhs` does not contain a value |
596
  | `rhs` does not contain a value | initializes the contained value of `rhs` as if direct-non-list-initializing an object of type `T` with the expression `std::move(*(*this))`, followed by `val->T::~T()`; postcondition is that `*this` does not contain a value and `rhs` contains a value | no effect |
597
 
598
 
599
  *Throws:* Any exceptions thrown by the operations in the relevant part
600
- of Table  [[tab:optional.swap]].
601
 
602
  *Remarks:* The expression inside `noexcept` is equivalent to:
603
 
604
  ``` cpp
605
  is_nothrow_move_constructible_v<T> && is_nothrow_swappable_v<T>
@@ -618,55 +629,55 @@ exception safety guarantee of `T`’s move constructor.
618
  ``` cpp
619
  constexpr const T* operator->() const;
620
  constexpr T* operator->();
621
  ```
622
 
623
- *Requires:* `*this` contains a value.
624
 
625
  *Returns:* `val`.
626
 
627
  *Throws:* Nothing.
628
 
629
- *Remarks:* These functions shall be constexpr functions.
630
 
631
  ``` cpp
632
  constexpr const T& operator*() const&;
633
  constexpr T& operator*() &;
634
  ```
635
 
636
- *Requires:* `*this` contains a value.
637
 
638
  *Returns:* `*val`.
639
 
640
  *Throws:* Nothing.
641
 
642
- *Remarks:* These functions shall be constexpr functions.
643
 
644
  ``` cpp
645
  constexpr T&& operator*() &&;
646
  constexpr const T&& operator*() const&&;
647
  ```
648
 
649
- *Requires:* `*this` contains a value.
650
 
651
  *Effects:* Equivalent to: `return std::move(*val);`
652
 
653
  ``` cpp
654
  constexpr explicit operator bool() const noexcept;
655
  ```
656
 
657
  *Returns:* `true` if and only if `*this` contains a value.
658
 
659
- *Remarks:* This function shall be a constexpr function.
660
 
661
  ``` cpp
662
  constexpr bool has_value() const noexcept;
663
  ```
664
 
665
  *Returns:* `true` if and only if `*this` contains a value.
666
 
667
- *Remarks:* This function shall be a constexpr function.
668
 
669
  ``` cpp
670
  constexpr const T& value() const&;
671
  constexpr T& value() &;
672
  ```
@@ -690,350 +701,318 @@ return bool(*this) ? std::move(*val) : throw bad_optional_access();
690
 
691
  ``` cpp
692
  template<class U> constexpr T value_or(U&& v) const&;
693
  ```
694
 
 
 
 
695
  *Effects:* Equivalent to:
696
 
697
  ``` cpp
698
  return bool(*this) ? **this : static_cast<T>(std::forward<U>(v));
699
  ```
700
 
701
- *Remarks:* If `is_copy_constructible_v<T> && is_convertible_v<U&&, T>`
702
- is `false`, the program is ill-formed.
703
-
704
  ``` cpp
705
  template<class U> constexpr T value_or(U&& v) &&;
706
  ```
707
 
 
 
 
708
  *Effects:* Equivalent to:
709
 
710
  ``` cpp
711
  return bool(*this) ? std::move(**this) : static_cast<T>(std::forward<U>(v));
712
  ```
713
 
714
- *Remarks:* If `is_move_constructible_v<T> && is_convertible_v<U&&, T>`
715
- is `false`, the program is ill-formed.
716
-
717
  #### Modifiers <a id="optional.mod">[[optional.mod]]</a>
718
 
719
  ``` cpp
720
  void reset() noexcept;
721
  ```
722
 
723
  *Effects:* If `*this` contains a value, calls `val->T::T̃()` to destroy
724
  the contained value; otherwise no effect.
725
 
726
- *Postconditions:* `*this` does not contain a value.
727
 
728
  ### No-value state indicator <a id="optional.nullopt">[[optional.nullopt]]</a>
729
 
730
  ``` cpp
731
  struct nullopt_t{see below};
732
  inline constexpr nullopt_t nullopt(unspecified);
733
  ```
734
 
735
- The struct `nullopt_t` is an empty structure type used as a unique type
736
- to indicate the state of not containing a value for `optional` objects.
737
- In particular, `optional<T>` has a constructor with `nullopt_t` as a
738
- single argument; this indicates that an optional object not containing a
739
- value shall be constructed.
740
 
741
  Type `nullopt_t` shall not have a default constructor or an
742
  initializer-list constructor, and shall not be an aggregate.
743
 
744
  ### Class `bad_optional_access` <a id="optional.bad.access">[[optional.bad.access]]</a>
745
 
746
  ``` cpp
747
  class bad_optional_access : public exception {
748
  public:
749
- bad_optional_access();
 
750
  };
751
  ```
752
 
753
  The class `bad_optional_access` defines the type of objects thrown as
754
  exceptions to report the situation where an attempt is made to access
755
  the value of an optional object that does not contain a value.
756
 
757
  ``` cpp
758
- bad_optional_access();
759
  ```
760
 
761
- *Effects:* Constructs an object of class `bad_optional_access`.
762
-
763
- *Postconditions:* `what()` returns an *implementation-defined* NTBS.
764
 
765
  ### Relational operators <a id="optional.relops">[[optional.relops]]</a>
766
 
767
  ``` cpp
768
  template<class T, class U> constexpr bool operator==(const optional<T>& x, const optional<U>& y);
769
  ```
770
 
771
- *Requires:* The expression `*x == *y` shall be well-formed and its
772
- result shall be convertible to `bool`.
773
 
774
- [*Note 1*: `T` need not be `EqualityComparable`. — *end note*]
775
 
776
  *Returns:* If `bool(x) != bool(y)`, `false`; otherwise if
777
  `bool(x) == false`, `true`; otherwise `*x == *y`.
778
 
779
  *Remarks:* Specializations of this function template for which
780
- `*x == *y` is a core constant expression shall be constexpr functions.
781
 
782
  ``` cpp
783
  template<class T, class U> constexpr bool operator!=(const optional<T>& x, const optional<U>& y);
784
  ```
785
 
786
- *Requires:* The expression `*x != *y` shall be well-formed and its
787
- result shall be convertible to `bool`.
788
 
789
  *Returns:* If `bool(x) != bool(y)`, `true`; otherwise, if
790
  `bool(x) == false`, `false`; otherwise `*x != *y`.
791
 
792
  *Remarks:* Specializations of this function template for which
793
- `*x != *y` is a core constant expression shall be constexpr functions.
794
 
795
  ``` cpp
796
  template<class T, class U> constexpr bool operator<(const optional<T>& x, const optional<U>& y);
797
  ```
798
 
799
- *Requires:* `*x < *y` shall be well-formed and its result shall be
800
- convertible to `bool`.
801
 
802
  *Returns:* If `!y`, `false`; otherwise, if `!x`, `true`; otherwise
803
  `*x < *y`.
804
 
805
  *Remarks:* Specializations of this function template for which `*x < *y`
806
- is a core constant expression shall be constexpr functions.
807
 
808
  ``` cpp
809
  template<class T, class U> constexpr bool operator>(const optional<T>& x, const optional<U>& y);
810
  ```
811
 
812
- *Requires:* The expression `*x > *y` shall be well-formed and its result
813
- shall be convertible to `bool`.
814
 
815
  *Returns:* If `!x`, `false`; otherwise, if `!y`, `true`; otherwise
816
  `*x > *y`.
817
 
818
  *Remarks:* Specializations of this function template for which `*x > *y`
819
- is a core constant expression shall be constexpr functions.
820
 
821
  ``` cpp
822
  template<class T, class U> constexpr bool operator<=(const optional<T>& x, const optional<U>& y);
823
  ```
824
 
825
- *Requires:* The expression `*x <= *y` shall be well-formed and its
826
- result shall be convertible to `bool`.
827
 
828
  *Returns:* If `!x`, `true`; otherwise, if `!y`, `false`; otherwise
829
  `*x <= *y`.
830
 
831
  *Remarks:* Specializations of this function template for which
832
- `*x <= *y` is a core constant expression shall be constexpr functions.
833
 
834
  ``` cpp
835
  template<class T, class U> constexpr bool operator>=(const optional<T>& x, const optional<U>& y);
836
  ```
837
 
838
- *Requires:* The expression `*x >= *y` shall be well-formed and its
839
- result shall be convertible to `bool`.
840
 
841
  *Returns:* If `!y`, `true`; otherwise, if `!x`, `false`; otherwise
842
  `*x >= *y`.
843
 
844
  *Remarks:* Specializations of this function template for which
845
- `*x >= *y` is a core constant expression shall be constexpr functions.
 
 
 
 
 
 
 
 
 
 
 
846
 
847
  ### Comparison with `nullopt` <a id="optional.nullops">[[optional.nullops]]</a>
848
 
849
  ``` cpp
850
  template<class T> constexpr bool operator==(const optional<T>& x, nullopt_t) noexcept;
851
- template <class T> constexpr bool operator==(nullopt_t, const optional<T>& x) noexcept;
852
  ```
853
 
854
  *Returns:* `!x`.
855
 
856
  ``` cpp
857
- template <class T> constexpr bool operator!=(const optional<T>& x, nullopt_t) noexcept;
858
- template <class T> constexpr bool operator!=(nullopt_t, const optional<T>& x) noexcept;
859
  ```
860
 
861
- *Returns:* `bool(x)`.
862
 
863
- ``` cpp
864
- template <class T> constexpr bool operator<(const optional<T>& x, nullopt_t) noexcept;
865
- ```
866
-
867
- *Returns:* `false`.
868
-
869
- ``` cpp
870
- template <class T> constexpr bool operator<(nullopt_t, const optional<T>& x) noexcept;
871
- ```
872
-
873
- *Returns:* `bool(x)`.
874
-
875
- ``` cpp
876
- template <class T> constexpr bool operator<=(const optional<T>& x, nullopt_t) noexcept;
877
- ```
878
-
879
- *Returns:* `!x`.
880
-
881
- ``` cpp
882
- template <class T> constexpr bool operator<=(nullopt_t, const optional<T>& x) noexcept;
883
- ```
884
-
885
- *Returns:* `true`.
886
-
887
- ``` cpp
888
- template <class T> constexpr bool operator>(const optional<T>& x, nullopt_t) noexcept;
889
- ```
890
-
891
- *Returns:* `bool(x)`.
892
-
893
- ``` cpp
894
- template <class T> constexpr bool operator>(nullopt_t, const optional<T>& x) noexcept;
895
- ```
896
-
897
- *Returns:* `false`.
898
-
899
- ``` cpp
900
- template <class T> constexpr bool operator>=(const optional<T>& x, nullopt_t) noexcept;
901
- ```
902
-
903
- *Returns:* `true`.
904
-
905
- ``` cpp
906
- template <class T> constexpr bool operator>=(nullopt_t, const optional<T>& x) noexcept;
907
- ```
908
-
909
- *Returns:* `!x`.
910
-
911
- ### Comparison with `T` <a id="optional.comp_with_t">[[optional.comp_with_t]]</a>
912
 
913
  ``` cpp
914
  template<class T, class U> constexpr bool operator==(const optional<T>& x, const U& v);
915
  ```
916
 
917
- *Requires:* The expression `*x == v` shall be well-formed and its result
918
- shall be convertible to `bool`.
919
 
920
- [*Note 1*: `T` need not be `EqualityComparable`. — *end note*]
921
 
922
  *Effects:* Equivalent to: `return bool(x) ? *x == v : false;`
923
 
924
  ``` cpp
925
- template <class T, class U> constexpr bool operator==(const U& v, const optional<T>& x);
926
  ```
927
 
928
- *Requires:* The expression `v == *x` shall be well-formed and its result
929
- shall be convertible to `bool`.
930
 
931
  *Effects:* Equivalent to: `return bool(x) ? v == *x : false;`
932
 
933
  ``` cpp
934
  template<class T, class U> constexpr bool operator!=(const optional<T>& x, const U& v);
935
  ```
936
 
937
- *Requires:* The expression `*x != v` shall be well-formed and its result
938
- shall be convertible to `bool`.
939
 
940
  *Effects:* Equivalent to: `return bool(x) ? *x != v : true;`
941
 
942
  ``` cpp
943
- template <class T, class U> constexpr bool operator!=(const U& v, const optional<T>& x);
944
  ```
945
 
946
- *Requires:* The expression `v != *x` shall be well-formed and its result
947
- shall be convertible to `bool`.
948
 
949
  *Effects:* Equivalent to: `return bool(x) ? v != *x : true;`
950
 
951
  ``` cpp
952
  template<class T, class U> constexpr bool operator<(const optional<T>& x, const U& v);
953
  ```
954
 
955
- *Requires:* The expression `*x < v` shall be well-formed and its result
956
- shall be convertible to `bool`.
957
 
958
  *Effects:* Equivalent to: `return bool(x) ? *x < v : true;`
959
 
960
  ``` cpp
961
- template <class T, class U> constexpr bool operator<(const U& v, const optional<T>& x);
962
  ```
963
 
964
- *Requires:* The expression `v < *x` shall be well-formed and its result
965
- shall be convertible to `bool`.
966
 
967
  *Effects:* Equivalent to: `return bool(x) ? v < *x : false;`
968
 
969
- ``` cpp
970
- template <class T, class U> constexpr bool operator<=(const optional<T>& x, const U& v);
971
- ```
972
-
973
- *Requires:* The expression `*x <= v` shall be well-formed and its result
974
- shall be convertible to `bool`.
975
-
976
- *Effects:* Equivalent to: `return bool(x) ? *x <= v : true;`
977
-
978
- ``` cpp
979
- template <class T, class U> constexpr bool operator<=(const U& v, const optional<T>& x);
980
- ```
981
-
982
- *Requires:* The expression `v <= *x` shall be well-formed and its result
983
- shall be convertible to `bool`.
984
-
985
- *Effects:* Equivalent to: `return bool(x) ? v <= *x : false;`
986
-
987
  ``` cpp
988
  template<class T, class U> constexpr bool operator>(const optional<T>& x, const U& v);
989
  ```
990
 
991
- *Requires:* The expression `*x > v` shall be well-formed and its result
992
- shall be convertible to `bool`.
993
 
994
  *Effects:* Equivalent to: `return bool(x) ? *x > v : false;`
995
 
996
  ``` cpp
997
- template <class T, class U> constexpr bool operator>(const U& v, const optional<T>& x);
998
  ```
999
 
1000
- *Requires:* The expression `v > *x` shall be well-formed and its result
1001
- shall be convertible to `bool`.
1002
 
1003
  *Effects:* Equivalent to: `return bool(x) ? v > *x : true;`
1004
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1005
  ``` cpp
1006
  template<class T, class U> constexpr bool operator>=(const optional<T>& x, const U& v);
1007
  ```
1008
 
1009
- *Requires:* The expression `*x >= v` shall be well-formed and its result
1010
- shall be convertible to `bool`.
1011
 
1012
  *Effects:* Equivalent to: `return bool(x) ? *x >= v : false;`
1013
 
1014
  ``` cpp
1015
- template <class T, class U> constexpr bool operator>=(const U& v, const optional<T>& x);
1016
  ```
1017
 
1018
- *Requires:* The expression `v >= *x` shall be well-formed and its result
1019
- shall be convertible to `bool`.
1020
 
1021
  *Effects:* Equivalent to: `return bool(x) ? v >= *x : true;`
1022
 
 
 
 
 
 
 
 
 
 
1023
  ### Specialized algorithms <a id="optional.specalg">[[optional.specalg]]</a>
1024
 
1025
  ``` cpp
1026
  template<class T> void swap(optional<T>& x, optional<T>& y) noexcept(noexcept(x.swap(y)));
1027
  ```
1028
 
 
 
 
1029
  *Effects:* Calls `x.swap(y)`.
1030
 
1031
- *Remarks:* This function shall not participate in overload resolution
1032
- unless `is_move_constructible_v<T>` is `true` and `is_swappable_v<T>` is
1033
- `true`.
1034
-
1035
  ``` cpp
1036
  template<class T> constexpr optional<decay_t<T>> make_optional(T&& v);
1037
  ```
1038
 
1039
  *Returns:* `optional<decay_t<T>>(std::forward<T>(v))`.
@@ -1058,13 +1037,13 @@ template <class T, class U, class... Args>
1058
 
1059
  ``` cpp
1060
  template<class T> struct hash<optional<T>>;
1061
  ```
1062
 
1063
- The specialization `hash<optional<T>>` is enabled ([[unord.hash]]) if
1064
- and only if `hash<remove_const_t<T>>` is enabled. When enabled, for an
1065
  object `o` of type `optional<T>`, if `bool(o) == true`, then
1066
- `hash<optional<T>>()(o)` shall evaluate to the same value as
1067
  `hash<remove_const_t<T>>()(*o)`; otherwise it evaluates to an
1068
  unspecified value. The member functions are not guaranteed to be
1069
  `noexcept`.
1070
 
 
1
  ## Optional objects <a id="optional">[[optional]]</a>
2
 
3
  ### In general <a id="optional.general">[[optional.general]]</a>
4
 
5
+ Subclause  [[optional]] describes class template `optional` that
6
+ represents optional objects. An *optional object* is an object that
7
+ contains the storage for another object and manages the lifetime of this
8
+ contained object, if any. The contained object may be initialized after
9
+ the optional object has been initialized, and may be destroyed before
10
+ the optional object has been destroyed. The initialization state of the
11
  contained object is tracked by the optional object.
12
 
13
  ### Header `<optional>` synopsis <a id="optional.syn">[[optional.syn]]</a>
14
 
15
  ``` cpp
16
+ #include <compare> // see [compare.syn]
17
+
18
  namespace std {
19
  // [optional.optional], class template optional
20
  template<class T>
21
  class optional;
22
 
 
38
  constexpr bool operator>(const optional<T>&, const optional<U>&);
39
  template<class T, class U>
40
  constexpr bool operator<=(const optional<T>&, const optional<U>&);
41
  template<class T, class U>
42
  constexpr bool operator>=(const optional<T>&, const optional<U>&);
43
+ template<class T, three_way_comparable_with<T> U>
44
+ constexpr compare_three_way_result_t<T,U>
45
+ operator<=>(const optional<T>&, const optional<U>&);
46
 
47
  // [optional.nullops], comparison with nullopt
48
  template<class T> constexpr bool operator==(const optional<T>&, nullopt_t) noexcept;
49
+ template<class T>
50
+ constexpr strong_ordering operator<=>(const optional<T>&, nullopt_t) noexcept;
 
 
 
 
 
 
 
 
 
51
 
52
+ // [optional.comp.with.t], comparison with T
53
  template<class T, class U> constexpr bool operator==(const optional<T>&, const U&);
54
+ template<class T, class U> constexpr bool operator==(const T&, const optional<U>&);
55
  template<class T, class U> constexpr bool operator!=(const optional<T>&, const U&);
56
+ template<class T, class U> constexpr bool operator!=(const T&, const optional<U>&);
57
  template<class T, class U> constexpr bool operator<(const optional<T>&, const U&);
58
+ template<class T, class U> constexpr bool operator<(const T&, const optional<U>&);
 
 
59
  template<class T, class U> constexpr bool operator>(const optional<T>&, const U&);
60
+ template<class T, class U> constexpr bool operator>(const T&, const optional<U>&);
61
+ template<class T, class U> constexpr bool operator<=(const optional<T>&, const U&);
62
+ template<class T, class U> constexpr bool operator<=(const T&, const optional<U>&);
63
  template<class T, class U> constexpr bool operator>=(const optional<T>&, const U&);
64
+ template<class T, class U> constexpr bool operator>=(const T&, const optional<U>&);
65
+ template<class T, three_way_comparable_with<T> U>
66
+ constexpr compare_three_way_result_t<T,U>
67
+ operator<=>(const optional<T>&, const U&);
68
 
69
  // [optional.specalg], specialized algorithms
70
  template<class T>
71
  void swap(optional<T>&, optional<T>&) noexcept(see below);
72
 
 
81
  template<class T> struct hash;
82
  template<class T> struct hash<optional<T>>;
83
  }
84
  ```
85
 
 
 
 
 
86
  ### Class template `optional` <a id="optional.optional">[[optional.optional]]</a>
87
 
88
  ``` cpp
89
+ namespace std {
90
  template<class T>
91
  class optional {
92
  public:
93
  using value_type = T;
94
 
 
100
  template<class... Args>
101
  constexpr explicit optional(in_place_t, Args&&...);
102
  template<class U, class... Args>
103
  constexpr explicit optional(in_place_t, initializer_list<U>, Args&&...);
104
  template<class U = T>
105
+ constexpr explicit(see below) optional(U&&);
106
  template<class U>
107
+ explicit(see below) optional(const optional<U>&);
108
  template<class U>
109
+ explicit(see below) optional(optional<U>&&);
110
 
111
  // [optional.dtor], destructor
112
  ~optional();
113
 
114
  // [optional.assign], assignment
115
  optional& operator=(nullopt_t) noexcept;
116
+ constexpr optional& operator=(const optional&);
117
+ constexpr optional& operator=(optional&&) noexcept(see below);
118
  template<class U = T> optional& operator=(U&&);
119
  template<class U> optional& operator=(const optional<U>&);
120
  template<class U> optional& operator=(optional<U>&&);
121
  template<class... Args> T& emplace(Args&&...);
122
  template<class U, class... Args> T& emplace(initializer_list<U>, Args&&...);
 
145
 
146
  private:
147
  T *val; // exposition only
148
  };
149
 
150
+ template<class T>
151
+ optional(T) -> optional<T>;
152
+ }
153
  ```
154
 
155
  Any instance of `optional<T>` at any given time either contains a value
156
  or does not contain a value. When an instance of `optional<T>` *contains
157
  a value*, it means that an object of type `T`, referred to as the
 
165
  returns `false`.
166
 
167
  Member `val` is provided for exposition only. When an `optional<T>`
168
  object contains a value, `val` points to the contained value.
169
 
170
+ `T` shall be a type other than cv `in_place_t` or cv `nullopt_t` that
171
+ meets the *Cpp17Destructible* requirements ([[cpp17.destructible]]).
172
 
173
  #### Constructors <a id="optional.ctor">[[optional.ctor]]</a>
174
 
175
  ``` cpp
176
  constexpr optional() noexcept;
177
  constexpr optional(nullopt_t) noexcept;
178
  ```
179
 
180
+ *Ensures:* `*this` does not contain a value.
181
 
182
  *Remarks:* No contained value is initialized. For every object type `T`
183
+ these constructors are constexpr constructors [[dcl.constexpr]].
184
 
185
  ``` cpp
186
  constexpr optional(const optional& rhs);
187
  ```
188
 
189
  *Effects:* If `rhs` contains a value, initializes the contained value as
190
  if direct-non-list-initializing an object of type `T` with the
191
  expression `*rhs`.
192
 
193
+ *Ensures:* `bool(rhs) == bool(*this)`.
194
 
195
  *Throws:* Any exception thrown by the selected constructor of `T`.
196
 
197
+ *Remarks:* This constructor is defined as deleted unless
198
  `is_copy_constructible_v<T>` is `true`. If
199
+ `is_trivially_copy_constructible_v<T>` is `true`, this constructor is
200
+ trivial.
201
 
202
  ``` cpp
203
  constexpr optional(optional&& rhs) noexcept(see below);
204
  ```
205
 
206
+ *Constraints:* `is_move_constructible_v<T>` is `true`.
207
+
208
  *Effects:* If `rhs` contains a value, initializes the contained value as
209
  if direct-non-list-initializing an object of type `T` with the
210
  expression `std::move(*rhs)`. `bool(rhs)` is unchanged.
211
 
212
+ *Ensures:* `bool(rhs) == bool(*this)`.
213
 
214
  *Throws:* Any exception thrown by the selected constructor of `T`.
215
 
216
  *Remarks:* The expression inside `noexcept` is equivalent to
217
+ `is_nothrow_move_constructible_v<T>`. If
218
+ `is_trivially_move_constructible_v<T>` is `true`, this constructor is
219
+ trivial.
 
220
 
221
  ``` cpp
222
  template<class... Args> constexpr explicit optional(in_place_t, Args&&... args);
223
  ```
224
 
225
+ *Constraints:* `is_constructible_v<T, Args...>` is `true`.
226
+
227
  *Effects:* Initializes the contained value as if
228
  direct-non-list-initializing an object of type `T` with the arguments
229
  `std::forward<Args>(args)...`.
230
 
231
+ *Ensures:* `*this` contains a value.
232
 
233
  *Throws:* Any exception thrown by the selected constructor of `T`.
234
 
235
  *Remarks:* If `T`’s constructor selected for the initialization is a
236
+ constexpr constructor, this constructor is a constexpr constructor.
 
 
237
 
238
  ``` cpp
239
  template<class U, class... Args>
240
  constexpr explicit optional(in_place_t, initializer_list<U> il, Args&&... args);
241
  ```
242
 
243
+ *Constraints:* `is_constructible_v<T, initializer_list<U>&, Args...>` is
244
+ `true`.
245
+
246
  *Effects:* Initializes the contained value as if
247
  direct-non-list-initializing an object of type `T` with the arguments
248
  `il, std::forward<Args>(args)...`.
249
 
250
+ *Ensures:* `*this` contains a value.
251
 
252
  *Throws:* Any exception thrown by the selected constructor of `T`.
253
 
254
+ *Remarks:* If `T`’s constructor selected for the initialization is a
255
+ constexpr constructor, this constructor is a constexpr constructor.
 
 
 
 
 
 
 
 
256
 
257
  ``` cpp
258
+ template<class U = T> constexpr explicit(see below) optional(U&& v);
259
  ```
260
 
261
+ *Constraints:* `is_constructible_v<T, U>` is `true`,
262
+ `is_same_v<remove_cvref_t<U>, in_place_t>` is `false`, and
263
+ `is_same_v<remove_cvref_t<U>, optional>` is `false`.
264
+
265
  *Effects:* Initializes the contained value as if
266
  direct-non-list-initializing an object of type `T` with the expression
267
  `std::forward<U>(v)`.
268
 
269
+ *Ensures:* `*this` contains a value.
270
 
271
  *Throws:* Any exception thrown by the selected constructor of `T`.
272
 
273
  *Remarks:* If `T`’s selected constructor is a constexpr constructor,
274
+ this constructor is a constexpr constructor. The expression inside
275
+ `explicit` is equivalent to:
 
 
 
 
276
 
277
  ``` cpp
278
+ !is_convertible_v<U, T>
279
  ```
280
 
281
+ ``` cpp
282
+ template<class U> explicit(see below) optional(const optional<U>& rhs);
283
+ ```
 
 
 
 
284
 
285
+ *Constraints:*
 
286
 
287
  - `is_constructible_v<T, const U&>` is `true`,
288
  - `is_constructible_v<T, optional<U>&>` is `false`,
289
  - `is_constructible_v<T, optional<U>&&>` is `false`,
290
  - `is_constructible_v<T, const optional<U>&>` is `false`,
 
292
  - `is_convertible_v<optional<U>&, T>` is `false`,
293
  - `is_convertible_v<optional<U>&&, T>` is `false`,
294
  - `is_convertible_v<const optional<U>&, T>` is `false`, and
295
  - `is_convertible_v<const optional<U>&&, T>` is `false`.
296
 
297
+ *Effects:* If `rhs` contains a value, initializes the contained value as
298
+ if direct-non-list-initializing an object of type `T` with the
299
+ expression `*rhs`.
300
+
301
+ *Ensures:* `bool(rhs)` == `bool(*this)`.
302
+
303
+ *Throws:* Any exception thrown by the selected constructor of `T`.
304
+
305
+ *Remarks:* The expression inside `explicit` is equivalent to:
306
+
307
+ ``` cpp
308
+ !is_convertible_v<const U&, T>
309
+ ```
310
 
311
  ``` cpp
312
+ template<class U> explicit(see below) optional(optional<U>&& rhs);
313
  ```
314
 
315
+ *Constraints:*
316
+
317
+ - `is_constructible_v<T, U>` is true,
318
+ - `is_constructible_v<T, optional<U>&>` is `false`,
319
+ - `is_constructible_v<T, optional<U>&&>` is `false`,
320
+ - `is_constructible_v<T, const optional<U>&>` is `false`,
321
+ - `is_constructible_v<T, const optional<U>&&>` is `false`,
322
+ - `is_convertible_v<optional<U>&, T>` is `false`,
323
+ - `is_convertible_v<optional<U>&&, T>` is `false`,
324
+ - `is_convertible_v<const optional<U>&, T>` is `false`, and
325
+ - `is_convertible_v<const optional<U>&&, T>` is `false`.
326
+
327
  *Effects:* If `rhs` contains a value, initializes the contained value as
328
  if direct-non-list-initializing an object of type `T` with the
329
  expression `std::move(*rhs)`. `bool(rhs)` is unchanged.
330
 
331
+ *Ensures:* `bool(rhs)` == `bool(*this)`.
332
 
333
  *Throws:* Any exception thrown by the selected constructor of `T`.
334
 
335
+ *Remarks:* The expression inside `explicit` is equivalent to:
 
336
 
337
+ ``` cpp
338
+ !is_convertible_v<U, T>
339
+ ```
 
 
 
 
 
 
 
 
 
340
 
341
  #### Destructor <a id="optional.dtor">[[optional.dtor]]</a>
342
 
343
  ``` cpp
344
  ~optional();
 
349
 
350
  ``` cpp
351
  val->T::~T()
352
  ```
353
 
354
+ *Remarks:* If `is_trivially_destructible_v<T>` is `true`, then this
355
+ destructor is trivial.
356
 
357
  #### Assignment <a id="optional.assign">[[optional.assign]]</a>
358
 
359
  ``` cpp
360
  optional<T>& operator=(nullopt_t) noexcept;
361
  ```
362
 
363
  *Effects:* If `*this` contains a value, calls `val->T::T̃()` to destroy
364
  the contained value; otherwise no effect.
365
 
366
+ *Ensures:* `*this` does not contain a value.
367
 
368
+ *Returns:* `*this`.
369
 
370
  ``` cpp
371
+ constexpr optional<T>& operator=(const optional& rhs);
372
  ```
373
 
374
+ *Effects:* See [[optional.assign.copy]].
375
 
376
+ **Table: `optional::operator=(const optional&)` effects** <a id="optional.assign.copy">[optional.assign.copy]</a>
377
 
378
  | | `*this` contains a value | `*this` does not contain a value |
379
  | ------------------------------ | ------------------------------------------------------ | ---------------------------------------------------------------------------------------------------- |
380
  | `rhs` contains a value | assigns `*rhs` to the contained value | initializes the contained value as if direct-non-list-initializing an object of type `T` with `*rhs` |
381
  | `rhs` does not contain a value | destroys the contained value by calling `val->T::~T()` | no effect |
382
 
383
 
384
+ *Ensures:* `bool(rhs) == bool(*this)`.
385
 
386
+ *Returns:* `*this`.
387
 
388
  *Remarks:* If any exception is thrown, the result of the expression
389
  `bool(*this)` remains unchanged. If an exception is thrown during the
390
  call to `T`’s copy constructor, no effect. If an exception is thrown
391
  during the call to `T`’s copy assignment, the state of its contained
392
  value is as defined by the exception safety guarantee of `T`’s copy
393
+ assignment. This operator is defined as deleted unless
394
  `is_copy_constructible_v<T>` is `true` and `is_copy_assignable_v<T>` is
395
+ `true`. If `is_trivially_copy_constructible_v<T> &&`
396
+ `is_trivially_copy_assignable_v<T> &&` `is_trivially_destructible_v<T>`
397
+ is `true`, this assignment operator is trivial.
398
 
399
  ``` cpp
400
+ constexpr optional& operator=(optional&& rhs) noexcept(see below);
401
  ```
402
 
403
+ *Constraints:* `is_move_constructible_v<T>` is `true` and
404
+ `is_move_assignable_v<T>` is `true`.
405
 
406
+ *Effects:* See [[optional.assign.move]]. The result of the expression
407
+ `bool(rhs)` remains unchanged.
408
+
409
+ **Table: `optional::operator=(optional&&)` effects** <a id="optional.assign.move">[optional.assign.move]</a>
410
 
411
  | | `*this` contains a value | `*this` does not contain a value |
412
  | ------------------------------ | ------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------- |
413
  | `rhs` contains a value | assigns `std::move(*rhs)` to the contained value | initializes the contained value as if direct-non-list-initializing an object of type `T` with `std::move(*rhs)` |
414
  | `rhs` does not contain a value | destroys the contained value by calling `val->T::~T()` | no effect |
415
 
416
 
417
+ *Ensures:* `bool(rhs) == bool(*this)`.
418
+
419
  *Returns:* `*this`.
420
 
 
 
421
  *Remarks:* The expression inside `noexcept` is equivalent to:
422
 
423
  ``` cpp
424
  is_nothrow_move_assignable_v<T> && is_nothrow_move_constructible_v<T>
425
  ```
 
428
  remains unchanged. If an exception is thrown during the call to `T`’s
429
  move constructor, the state of `*rhs.val` is determined by the exception
430
  safety guarantee of `T`’s move constructor. If an exception is thrown
431
  during the call to `T`’s move assignment, the state of `*val` and
432
  `*rhs.val` is determined by the exception safety guarantee of `T`’s move
433
+ assignment. If `is_trivially_move_constructible_v<T> &&`
434
+ `is_trivially_move_assignable_v<T> &&` `is_trivially_destructible_v<T>`
435
+ is `true`, this assignment operator is trivial.
436
 
437
  ``` cpp
438
  template<class U = T> optional<T>& operator=(U&& v);
439
  ```
440
 
441
+ *Constraints:* `is_same_v<remove_cvref_t<U>, optional>` is `false`,
442
+ `conjunction_v<is_scalar<T>, is_same<T, decay_t<U>>>` is `false`,
443
+ `is_constructible_v<T, U>` is `true`, and `is_assignable_v<T&, U>` is
444
+ `true`.
445
+
446
  *Effects:* If `*this` contains a value, assigns `std::forward<U>(v)` to
447
  the contained value; otherwise initializes the contained value as if
448
  direct-non-list-initializing object of type `T` with
449
  `std::forward<U>(v)`.
450
 
451
+ *Ensures:* `*this` contains a value.
452
 
453
+ *Returns:* `*this`.
454
 
455
  *Remarks:* If any exception is thrown, the result of the expression
456
  `bool(*this)` remains unchanged. If an exception is thrown during the
457
  call to `T`’s constructor, the state of `v` is determined by the
458
  exception safety guarantee of `T`’s constructor. If an exception is
459
  thrown during the call to `T`’s assignment, the state of `*val` and `v`
460
  is determined by the exception safety guarantee of `T`’s assignment.
 
 
 
 
 
461
 
462
  ``` cpp
463
  template<class U> optional<T>& operator=(const optional<U>& rhs);
464
  ```
465
 
466
+ *Constraints:*
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
467
 
468
  - `is_constructible_v<T, const U&>` is `true`,
469
  - `is_assignable_v<T&, const U&>` is `true`,
470
  - `is_constructible_v<T, optional<U>&>` is `false`,
471
  - `is_constructible_v<T, optional<U>&&>` is `false`,
 
478
  - `is_assignable_v<T&, optional<U>&>` is `false`,
479
  - `is_assignable_v<T&, optional<U>&&>` is `false`,
480
  - `is_assignable_v<T&, const optional<U>&>` is `false`, and
481
  - `is_assignable_v<T&, const optional<U>&&>` is `false`.
482
 
483
+ *Effects:* See [[optional.assign.copy.templ]].
484
+
485
+ **Table: `optional::operator=(const optional<U>&)` effects** <a id="optional.assign.copy.templ">[optional.assign.copy.templ]</a>
486
+
487
+ | | `*this` contains a value | `*this` does not contain a value |
488
+ | ------------------------------ | ------------------------------------------------------ | ---------------------------------------------------------------------------------------------------- |
489
+ | `rhs` contains a value | assigns `*rhs` to the contained value | initializes the contained value as if direct-non-list-initializing an object of type `T` with `*rhs` |
490
+ | `rhs` does not contain a value | destroys the contained value by calling `val->T::~T()` | no effect |
491
+
492
+
493
+ *Ensures:* `bool(rhs) == bool(*this)`.
494
+
495
+ *Returns:* `*this`.
496
+
497
+ *Remarks:* If any exception is thrown, the result of the expression
498
+ `bool(*this)` remains unchanged. If an exception is thrown during the
499
+ call to `T`’s constructor, the state of `*rhs.val` is determined by the
500
+ exception safety guarantee of `T`’s constructor. If an exception is
501
+ thrown during the call to `T`’s assignment, the state of `*val` and
502
+ `*rhs.val` is determined by the exception safety guarantee of `T`’s
503
+ assignment.
504
+
505
  ``` cpp
506
  template<class U> optional<T>& operator=(optional<U>&& rhs);
507
  ```
508
 
509
+ *Constraints:*
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
510
 
511
  - `is_constructible_v<T, U>` is `true`,
512
  - `is_assignable_v<T&, U>` is `true`,
513
  - `is_constructible_v<T, optional<U>&>` is `false`,
514
  - `is_constructible_v<T, optional<U>&&>` is `false`,
 
521
  - `is_assignable_v<T&, optional<U>&>` is `false`,
522
  - `is_assignable_v<T&, optional<U>&&>` is `false`,
523
  - `is_assignable_v<T&, const optional<U>&>` is `false`, and
524
  - `is_assignable_v<T&, const optional<U>&&>` is `false`.
525
 
526
+ *Effects:* See [[optional.assign.move.templ]]. The result of the
527
+ expression `bool(rhs)` remains unchanged.
528
+
529
+ **Table: `optional::operator=(optional<U>&&)` effects** <a id="optional.assign.move.templ">[optional.assign.move.templ]</a>
530
+
531
+ | | `*this` contains a value | `*this` does not contain a value |
532
+ | ------------------------------ | ------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------- |
533
+ | `rhs` contains a value | assigns `std::move(*rhs)` to the contained value | initializes the contained value as if direct-non-list-initializing an object of type `T` with `std::move(*rhs)` |
534
+ | `rhs` does not contain a value | destroys the contained value by calling `val->T::~T()` | no effect |
535
+
536
+
537
+ *Ensures:* `bool(rhs) == bool(*this)`.
538
+
539
+ *Returns:* `*this`.
540
+
541
+ *Remarks:* If any exception is thrown, the result of the expression
542
+ `bool(*this)` remains unchanged. If an exception is thrown during the
543
+ call to `T`’s constructor, the state of `*rhs.val` is determined by the
544
+ exception safety guarantee of `T`’s constructor. If an exception is
545
+ thrown during the call to `T`’s assignment, the state of `*val` and
546
+ `*rhs.val` is determined by the exception safety guarantee of `T`’s
547
+ assignment.
548
+
549
  ``` cpp
550
  template<class... Args> T& emplace(Args&&... args);
551
  ```
552
 
553
+ *Mandates:* `is_constructible_v<T, Args...>` is `true`.
554
 
555
  *Effects:* Calls `*this = nullopt`. Then initializes the contained value
556
  as if direct-non-list-initializing an object of type `T` with the
557
  arguments `std::forward<Args>(args)...`.
558
 
559
+ *Ensures:* `*this` contains a value.
560
 
561
  *Returns:* A reference to the new contained value.
562
 
563
  *Throws:* Any exception thrown by the selected constructor of `T`.
564
 
 
568
 
569
  ``` cpp
570
  template<class U, class... Args> T& emplace(initializer_list<U> il, Args&&... args);
571
  ```
572
 
573
+ *Constraints:* `is_constructible_v<T, initializer_list<U>&, Args...>` is
574
+ `true`.
575
+
576
  *Effects:* Calls `*this = nullopt`. Then initializes the contained value
577
  as if direct-non-list-initializing an object of type `T` with the
578
  arguments `il, std::forward<Args>(args)...`.
579
 
580
+ *Ensures:* `*this` contains a value.
581
 
582
  *Returns:* A reference to the new contained value.
583
 
584
  *Throws:* Any exception thrown by the selected constructor of `T`.
585
 
586
  *Remarks:* If an exception is thrown during the call to `T`’s
587
  constructor, `*this` does not contain a value, and the previous `*val`
588
+ (if any) has been destroyed.
 
 
589
 
590
  #### Swap <a id="optional.swap">[[optional.swap]]</a>
591
 
592
  ``` cpp
593
  void swap(optional& rhs) noexcept(see below);
594
  ```
595
 
596
+ *Mandates:* `is_move_constructible_v<T>` is `true`.
 
597
 
598
+ *Preconditions:* Lvalues of type `T` are swappable.
599
 
600
+ *Effects:* See [[optional.swap]].
601
+
602
+ **Table: `optional::swap(optional&)` effects** <a id="optional.swap">[optional.swap]</a>
603
 
604
  | | `*this` contains a value | `*this` does not contain a value |
605
  | ------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
606
  | `rhs` contains a value | calls `swap(*(*this), *rhs)` | initializes the contained value of `*this` as if direct-non-list-initializing an object of type `T` with the expression `std::move(*rhs)`, followed by `rhs.val->T::~T()`; postcondition is that `*this` contains a value and `rhs` does not contain a value |
607
  | `rhs` does not contain a value | initializes the contained value of `rhs` as if direct-non-list-initializing an object of type `T` with the expression `std::move(*(*this))`, followed by `val->T::~T()`; postcondition is that `*this` does not contain a value and `rhs` contains a value | no effect |
608
 
609
 
610
  *Throws:* Any exceptions thrown by the operations in the relevant part
611
+ of [[optional.swap]].
612
 
613
  *Remarks:* The expression inside `noexcept` is equivalent to:
614
 
615
  ``` cpp
616
  is_nothrow_move_constructible_v<T> && is_nothrow_swappable_v<T>
 
629
  ``` cpp
630
  constexpr const T* operator->() const;
631
  constexpr T* operator->();
632
  ```
633
 
634
+ *Preconditions:* `*this` contains a value.
635
 
636
  *Returns:* `val`.
637
 
638
  *Throws:* Nothing.
639
 
640
+ *Remarks:* These functions are constexpr functions.
641
 
642
  ``` cpp
643
  constexpr const T& operator*() const&;
644
  constexpr T& operator*() &;
645
  ```
646
 
647
+ *Preconditions:* `*this` contains a value.
648
 
649
  *Returns:* `*val`.
650
 
651
  *Throws:* Nothing.
652
 
653
+ *Remarks:* These functions are constexpr functions.
654
 
655
  ``` cpp
656
  constexpr T&& operator*() &&;
657
  constexpr const T&& operator*() const&&;
658
  ```
659
 
660
+ *Preconditions:* `*this` contains a value.
661
 
662
  *Effects:* Equivalent to: `return std::move(*val);`
663
 
664
  ``` cpp
665
  constexpr explicit operator bool() const noexcept;
666
  ```
667
 
668
  *Returns:* `true` if and only if `*this` contains a value.
669
 
670
+ *Remarks:* This function is a constexpr function.
671
 
672
  ``` cpp
673
  constexpr bool has_value() const noexcept;
674
  ```
675
 
676
  *Returns:* `true` if and only if `*this` contains a value.
677
 
678
+ *Remarks:* This function is a constexpr function.
679
 
680
  ``` cpp
681
  constexpr const T& value() const&;
682
  constexpr T& value() &;
683
  ```
 
701
 
702
  ``` cpp
703
  template<class U> constexpr T value_or(U&& v) const&;
704
  ```
705
 
706
+ *Mandates:* `is_copy_constructible_v<T> && is_convertible_v<U&&, T>` is
707
+ `true`.
708
+
709
  *Effects:* Equivalent to:
710
 
711
  ``` cpp
712
  return bool(*this) ? **this : static_cast<T>(std::forward<U>(v));
713
  ```
714
 
 
 
 
715
  ``` cpp
716
  template<class U> constexpr T value_or(U&& v) &&;
717
  ```
718
 
719
+ *Mandates:* `is_move_constructible_v<T> && is_convertible_v<U&&, T>` is
720
+ `true`.
721
+
722
  *Effects:* Equivalent to:
723
 
724
  ``` cpp
725
  return bool(*this) ? std::move(**this) : static_cast<T>(std::forward<U>(v));
726
  ```
727
 
 
 
 
728
  #### Modifiers <a id="optional.mod">[[optional.mod]]</a>
729
 
730
  ``` cpp
731
  void reset() noexcept;
732
  ```
733
 
734
  *Effects:* If `*this` contains a value, calls `val->T::T̃()` to destroy
735
  the contained value; otherwise no effect.
736
 
737
+ *Ensures:* `*this` does not contain a value.
738
 
739
  ### No-value state indicator <a id="optional.nullopt">[[optional.nullopt]]</a>
740
 
741
  ``` cpp
742
  struct nullopt_t{see below};
743
  inline constexpr nullopt_t nullopt(unspecified);
744
  ```
745
 
746
+ The struct `nullopt_t` is an empty class type used as a unique type to
747
+ indicate the state of not containing a value for `optional` objects. In
748
+ particular, `optional<T>` has a constructor with `nullopt_t` as a single
749
+ argument; this indicates that an optional object not containing a value
750
+ shall be constructed.
751
 
752
  Type `nullopt_t` shall not have a default constructor or an
753
  initializer-list constructor, and shall not be an aggregate.
754
 
755
  ### Class `bad_optional_access` <a id="optional.bad.access">[[optional.bad.access]]</a>
756
 
757
  ``` cpp
758
  class bad_optional_access : public exception {
759
  public:
760
+ // see [exception] for the specification of the special member functions
761
+ const char* what() const noexcept override;
762
  };
763
  ```
764
 
765
  The class `bad_optional_access` defines the type of objects thrown as
766
  exceptions to report the situation where an attempt is made to access
767
  the value of an optional object that does not contain a value.
768
 
769
  ``` cpp
770
+ const char* what() const noexcept override;
771
  ```
772
 
773
+ *Returns:* An *implementation-defined* NTBS.
 
 
774
 
775
  ### Relational operators <a id="optional.relops">[[optional.relops]]</a>
776
 
777
  ``` cpp
778
  template<class T, class U> constexpr bool operator==(const optional<T>& x, const optional<U>& y);
779
  ```
780
 
781
+ *Mandates:* The expression `*x == *y` is well-formed and its result is
782
+ convertible to `bool`.
783
 
784
+ [*Note 1*: `T` need not be *Cpp17EqualityComparable*. — *end note*]
785
 
786
  *Returns:* If `bool(x) != bool(y)`, `false`; otherwise if
787
  `bool(x) == false`, `true`; otherwise `*x == *y`.
788
 
789
  *Remarks:* Specializations of this function template for which
790
+ `*x == *y` is a core constant expression are constexpr functions.
791
 
792
  ``` cpp
793
  template<class T, class U> constexpr bool operator!=(const optional<T>& x, const optional<U>& y);
794
  ```
795
 
796
+ *Mandates:* The expression `*x != *y` is well-formed and its result is
797
+ convertible to `bool`.
798
 
799
  *Returns:* If `bool(x) != bool(y)`, `true`; otherwise, if
800
  `bool(x) == false`, `false`; otherwise `*x != *y`.
801
 
802
  *Remarks:* Specializations of this function template for which
803
+ `*x != *y` is a core constant expression are constexpr functions.
804
 
805
  ``` cpp
806
  template<class T, class U> constexpr bool operator<(const optional<T>& x, const optional<U>& y);
807
  ```
808
 
809
+ *Mandates:* `*x < *y` is well-formed and its result is convertible to
810
+ `bool`.
811
 
812
  *Returns:* If `!y`, `false`; otherwise, if `!x`, `true`; otherwise
813
  `*x < *y`.
814
 
815
  *Remarks:* Specializations of this function template for which `*x < *y`
816
+ is a core constant expression are constexpr functions.
817
 
818
  ``` cpp
819
  template<class T, class U> constexpr bool operator>(const optional<T>& x, const optional<U>& y);
820
  ```
821
 
822
+ *Mandates:* The expression `*x > *y` is well-formed and its result is
823
+ convertible to `bool`.
824
 
825
  *Returns:* If `!x`, `false`; otherwise, if `!y`, `true`; otherwise
826
  `*x > *y`.
827
 
828
  *Remarks:* Specializations of this function template for which `*x > *y`
829
+ is a core constant expression are constexpr functions.
830
 
831
  ``` cpp
832
  template<class T, class U> constexpr bool operator<=(const optional<T>& x, const optional<U>& y);
833
  ```
834
 
835
+ *Mandates:* The expression `*x <= *y` is well-formed and its result is
836
+ convertible to `bool`.
837
 
838
  *Returns:* If `!x`, `true`; otherwise, if `!y`, `false`; otherwise
839
  `*x <= *y`.
840
 
841
  *Remarks:* Specializations of this function template for which
842
+ `*x <= *y` is a core constant expression are constexpr functions.
843
 
844
  ``` cpp
845
  template<class T, class U> constexpr bool operator>=(const optional<T>& x, const optional<U>& y);
846
  ```
847
 
848
+ *Mandates:* The expression `*x >= *y` is well-formed and its result is
849
+ convertible to `bool`.
850
 
851
  *Returns:* If `!y`, `true`; otherwise, if `!x`, `false`; otherwise
852
  `*x >= *y`.
853
 
854
  *Remarks:* Specializations of this function template for which
855
+ `*x >= *y` is a core constant expression are constexpr functions.
856
+
857
+ ``` cpp
858
+ template<class T, three_way_comparable_with<T> U>
859
+ constexpr compare_three_way_result_t<T,U>
860
+ operator<=>(const optional<T>& x, const optional<U>& y);
861
+ ```
862
+
863
+ *Returns:* If `x && y`, `*x <=> *y`; otherwise `bool(x) <=> bool(y)`.
864
+
865
+ *Remarks:* Specializations of this function template for which
866
+ `*x <=> *y` is a core constant expression are constexpr functions.
867
 
868
  ### Comparison with `nullopt` <a id="optional.nullops">[[optional.nullops]]</a>
869
 
870
  ``` cpp
871
  template<class T> constexpr bool operator==(const optional<T>& x, nullopt_t) noexcept;
 
872
  ```
873
 
874
  *Returns:* `!x`.
875
 
876
  ``` cpp
877
+ template<class T> constexpr strong_ordering operator<=>(const optional<T>& x, nullopt_t) noexcept;
 
878
  ```
879
 
880
+ *Returns:* `bool(x) <=> false`.
881
 
882
+ ### Comparison with `T` <a id="optional.comp.with.t">[[optional.comp.with.t]]</a>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
883
 
884
  ``` cpp
885
  template<class T, class U> constexpr bool operator==(const optional<T>& x, const U& v);
886
  ```
887
 
888
+ *Mandates:* The expression `*x == v` is well-formed and its result is
889
+ convertible to `bool`.
890
 
891
+ [*Note 1*: `T` need not be *Cpp17EqualityComparable*. — *end note*]
892
 
893
  *Effects:* Equivalent to: `return bool(x) ? *x == v : false;`
894
 
895
  ``` cpp
896
+ template<class T, class U> constexpr bool operator==(const T& v, const optional<U>& x);
897
  ```
898
 
899
+ *Mandates:* The expression `v == *x` is well-formed and its result is
900
+ convertible to `bool`.
901
 
902
  *Effects:* Equivalent to: `return bool(x) ? v == *x : false;`
903
 
904
  ``` cpp
905
  template<class T, class U> constexpr bool operator!=(const optional<T>& x, const U& v);
906
  ```
907
 
908
+ *Mandates:* The expression `*x != v` is well-formed and its result is
909
+ convertible to `bool`.
910
 
911
  *Effects:* Equivalent to: `return bool(x) ? *x != v : true;`
912
 
913
  ``` cpp
914
+ template<class T, class U> constexpr bool operator!=(const T& v, const optional<U>& x);
915
  ```
916
 
917
+ *Mandates:* The expression `v != *x` is well-formed and its result is
918
+ convertible to `bool`.
919
 
920
  *Effects:* Equivalent to: `return bool(x) ? v != *x : true;`
921
 
922
  ``` cpp
923
  template<class T, class U> constexpr bool operator<(const optional<T>& x, const U& v);
924
  ```
925
 
926
+ *Mandates:* The expression `*x < v` is well-formed and its result is
927
+ convertible to `bool`.
928
 
929
  *Effects:* Equivalent to: `return bool(x) ? *x < v : true;`
930
 
931
  ``` cpp
932
+ template<class T, class U> constexpr bool operator<(const T& v, const optional<U>& x);
933
  ```
934
 
935
+ *Mandates:* The expression `v < *x` is well-formed and its result is
936
+ convertible to `bool`.
937
 
938
  *Effects:* Equivalent to: `return bool(x) ? v < *x : false;`
939
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
940
  ``` cpp
941
  template<class T, class U> constexpr bool operator>(const optional<T>& x, const U& v);
942
  ```
943
 
944
+ *Mandates:* The expression `*x > v` is well-formed and its result is
945
+ convertible to `bool`.
946
 
947
  *Effects:* Equivalent to: `return bool(x) ? *x > v : false;`
948
 
949
  ``` cpp
950
+ template<class T, class U> constexpr bool operator>(const T& v, const optional<U>& x);
951
  ```
952
 
953
+ *Mandates:* The expression `v > *x` is well-formed and its result is
954
+ convertible to `bool`.
955
 
956
  *Effects:* Equivalent to: `return bool(x) ? v > *x : true;`
957
 
958
+ ``` cpp
959
+ template<class T, class U> constexpr bool operator<=(const optional<T>& x, const U& v);
960
+ ```
961
+
962
+ *Mandates:* The expression `*x <= v` is well-formed and its result is
963
+ convertible to `bool`.
964
+
965
+ *Effects:* Equivalent to: `return bool(x) ? *x <= v : true;`
966
+
967
+ ``` cpp
968
+ template<class T, class U> constexpr bool operator<=(const T& v, const optional<U>& x);
969
+ ```
970
+
971
+ *Mandates:* The expression `v <= *x` is well-formed and its result is
972
+ convertible to `bool`.
973
+
974
+ *Effects:* Equivalent to: `return bool(x) ? v <= *x : false;`
975
+
976
  ``` cpp
977
  template<class T, class U> constexpr bool operator>=(const optional<T>& x, const U& v);
978
  ```
979
 
980
+ *Mandates:* The expression `*x >= v` is well-formed and its result is
981
+ convertible to `bool`.
982
 
983
  *Effects:* Equivalent to: `return bool(x) ? *x >= v : false;`
984
 
985
  ``` cpp
986
+ template<class T, class U> constexpr bool operator>=(const T& v, const optional<U>& x);
987
  ```
988
 
989
+ *Mandates:* The expression `v >= *x` is well-formed and its result is
990
+ convertible to `bool`.
991
 
992
  *Effects:* Equivalent to: `return bool(x) ? v >= *x : true;`
993
 
994
+ ``` cpp
995
+ template<class T, three_way_comparable_with<T> U>
996
+ constexpr compare_three_way_result_t<T,U>
997
+ operator<=>(const optional<T>& x, const U& v);
998
+ ```
999
+
1000
+ *Effects:* Equivalent to:
1001
+ `return bool(x) ? *x <=> v : strong_ordering::less;`
1002
+
1003
  ### Specialized algorithms <a id="optional.specalg">[[optional.specalg]]</a>
1004
 
1005
  ``` cpp
1006
  template<class T> void swap(optional<T>& x, optional<T>& y) noexcept(noexcept(x.swap(y)));
1007
  ```
1008
 
1009
+ *Constraints:* `is_move_constructible_v<T>` is `true` and
1010
+ `is_swappable_v<T>` is `true`.
1011
+
1012
  *Effects:* Calls `x.swap(y)`.
1013
 
 
 
 
 
1014
  ``` cpp
1015
  template<class T> constexpr optional<decay_t<T>> make_optional(T&& v);
1016
  ```
1017
 
1018
  *Returns:* `optional<decay_t<T>>(std::forward<T>(v))`.
 
1037
 
1038
  ``` cpp
1039
  template<class T> struct hash<optional<T>>;
1040
  ```
1041
 
1042
+ The specialization `hash<optional<T>>` is enabled [[unord.hash]] if and
1043
+ only if `hash<remove_const_t<T>>` is enabled. When enabled, for an
1044
  object `o` of type `optional<T>`, if `bool(o) == true`, then
1045
+ `hash<optional<T>>()(o)` evaluates to the same value as
1046
  `hash<remove_const_t<T>>()(*o)`; otherwise it evaluates to an
1047
  unspecified value. The member functions are not guaranteed to be
1048
  `noexcept`.
1049