From Jason Turner

[optional]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmpidzua3wb/{from.md → to.md} +316 -187
tmp/tmpidzua3wb/{from.md → to.md} RENAMED
@@ -18,10 +18,15 @@ contained object is tracked by the optional object.
18
  namespace std {
19
  // [optional.optional], class template optional
20
  template<class T>
21
  class optional;
22
 
 
 
 
 
 
23
  // [optional.nullopt], no-value state indicator
24
  struct nullopt_t{see below};
25
  inline constexpr nullopt_t nullopt(unspecified);
26
 
27
  // [optional.bad.access], class bad_optional_access
@@ -60,17 +65,18 @@ namespace std {
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
 
73
  template<class T>
74
  constexpr optional<see below> make_optional(T&&);
75
  template<class T, class... Args>
76
  constexpr optional<T> make_optional(Args&&... args);
@@ -83,10 +89,12 @@ namespace std {
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:
@@ -102,48 +110,60 @@ namespace std {
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&&...);
123
 
124
  // [optional.swap], swap
125
- void swap(optional&) noexcept(see below);
126
 
127
  // [optional.observe], observers
128
- constexpr const T* operator->() const;
129
- constexpr T* operator->();
130
- constexpr const T& operator*() const&;
131
- constexpr T& operator*() &;
132
- constexpr T&& operator*() &&;
133
- constexpr const T&& operator*() const&&;
134
  constexpr explicit operator bool() const noexcept;
135
  constexpr bool has_value() const noexcept;
136
  constexpr const T& value() const &;
137
  constexpr T& value() &;
138
  constexpr T&& value() &&;
139
  constexpr const T&& value() const &&;
140
  template<class U> constexpr T value_or(U&&) const &;
141
  template<class U> constexpr T value_or(U&&) &&;
142
 
 
 
 
 
 
 
 
 
 
 
 
 
143
  // [optional.mod], modifiers
144
- void reset() noexcept;
145
 
146
  private:
147
  T *val; // exposition only
148
  };
149
 
@@ -155,25 +175,35 @@ namespace std {
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
158
  optional object’s *contained value*, is allocated within the storage of
159
  the optional object. Implementations are not permitted to use additional
160
- storage, such as dynamic memory, to allocate its contained value. The
161
- contained value shall be allocated in a region of the `optional<T>`
162
- storage suitably aligned for the type `T`. When an object of type
163
- `optional<T>` is contextually converted to `bool`, the conversion
164
- returns `true` if the object contains a value; otherwise the conversion
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
 
@@ -184,15 +214,14 @@ 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
@@ -203,31 +232,29 @@ trivial.
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`.
@@ -241,12 +268,11 @@ template<class U, class... 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`.
@@ -256,16 +282,19 @@ 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`.
@@ -277,60 +306,46 @@ this constructor is a constexpr constructor. The expression inside
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`,
291
- - `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
 
@@ -339,11 +354,11 @@ expression `std::move(*rhs)`. `bool(rhs)` is unchanged.
339
  ```
340
 
341
  #### Destructor <a id="optional.dtor">[[optional.dtor]]</a>
342
 
343
  ``` cpp
344
- ~optional();
345
  ```
346
 
347
  *Effects:* If `is_trivially_destructible_v<T> != true` and `*this`
348
  contains a value, calls
349
 
@@ -355,11 +370,11 @@ val->T::~T()
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
 
@@ -374,22 +389,22 @@ constexpr optional<T>& operator=(const optional& rhs);
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> &&`
@@ -402,161 +417,146 @@ constexpr optional& operator=(optional&& rhs) noexcept(see below);
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
  ```
426
 
427
- If any exception is thrown, the result of the expression `bool(*this)`
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`,
472
- - `is_constructible_v<T, const optional<U>&>` is `false`,
473
- - `is_constructible_v<T, const optional<U>&&>` is `false`,
474
- - `is_convertible_v<optional<U>&, T>` is `false`,
475
- - `is_convertible_v<optional<U>&&, T>` is `false`,
476
- - `is_convertible_v<const optional<U>&, T>` is `false`,
477
- - `is_convertible_v<const optional<U>&&, T>` 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`,
515
- - `is_constructible_v<T, const optional<U>&>` is `false`,
516
- - `is_constructible_v<T, const optional<U>&&>` is `false`,
517
- - `is_convertible_v<optional<U>&, T>` is `false`,
518
- - `is_convertible_v<optional<U>&&, T>` is `false`,
519
- - `is_convertible_v<const optional<U>&, T>` is `false`,
520
- - `is_convertible_v<const optional<U>&&, T>` 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
 
@@ -565,19 +565,18 @@ arguments `std::forward<Args>(args)...`.
565
  *Remarks:* If an exception is thrown during the call to `T`’s
566
  constructor, `*this` does not contain a value, and the previous `*val`
567
  (if any) has been destroyed.
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
 
@@ -588,75 +587,72 @@ 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>
617
  ```
618
 
619
- If any exception is thrown, the results of the expressions `bool(*this)`
620
- and `bool(rhs)` remain unchanged. If an exception is thrown during the
621
- call to function `swap`, the state of `*val` and `*rhs.val` is
622
- determined by the exception safety guarantee of `swap` for lvalues of
623
- `T`. If an exception is thrown during the call to `T`’s move
624
- constructor, the state of `*val` and `*rhs.val` is determined by the
625
- exception safety guarantee of `T`’s move constructor.
626
 
627
  #### Observers <a id="optional.observe">[[optional.observe]]</a>
628
 
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);`
@@ -683,22 +679,22 @@ constexpr T& value() &;
683
  ```
684
 
685
  *Effects:* Equivalent to:
686
 
687
  ``` cpp
688
- return bool(*this) ? *val : throw bad_optional_access();
689
  ```
690
 
691
  ``` cpp
692
  constexpr T&& value() &&;
693
  constexpr const T&& value() const &&;
694
  ```
695
 
696
  *Effects:* Equivalent to:
697
 
698
  ``` cpp
699
- return bool(*this) ? std::move(*val) : throw bad_optional_access();
700
  ```
701
 
702
  ``` cpp
703
  template<class U> constexpr T value_or(U&& v) const &;
704
  ```
@@ -707,11 +703,11 @@ template<class U> constexpr T value_or(U&& v) const&;
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
  ```
@@ -720,17 +716,145 @@ template<class U> constexpr T value_or(U&& v) &&;
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
 
@@ -753,15 +877,17 @@ 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.
@@ -781,12 +907,12 @@ template<class T, class U> constexpr bool operator==(const optional<T>& x, const
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
@@ -794,12 +920,12 @@ template<class T, class U> constexpr bool operator!=(const optional<T>& x, const
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
@@ -858,11 +984,12 @@ convertible to `bool`.
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>
@@ -875,11 +1002,11 @@ template<class T> constexpr bool operator==(const optional<T>& x, nullopt_t) noe
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);
@@ -888,124 +1015,126 @@ template<class T, class U> constexpr bool operator==(const optional<T>& x, const
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
 
@@ -1039,11 +1168,11 @@ template<class T, class U, class... Args>
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
 
 
18
  namespace std {
19
  // [optional.optional], class template optional
20
  template<class T>
21
  class optional;
22
 
23
+ template<class T>
24
+ concept is-derived-from-optional = requires(const T& t) { // exposition only
25
+ []<class U>(const optional<U>&){ }(t);
26
+ };
27
+
28
  // [optional.nullopt], no-value state indicator
29
  struct nullopt_t{see below};
30
  inline constexpr nullopt_t nullopt(unspecified);
31
 
32
  // [optional.bad.access], class bad_optional_access
 
65
  template<class T, class U> constexpr bool operator>(const T&, const optional<U>&);
66
  template<class T, class U> constexpr bool operator<=(const optional<T>&, const U&);
67
  template<class T, class U> constexpr bool operator<=(const T&, const optional<U>&);
68
  template<class T, class U> constexpr bool operator>=(const optional<T>&, const U&);
69
  template<class T, class U> constexpr bool operator>=(const T&, const optional<U>&);
70
+ template<class T, class U>
71
+ requires (!is-derived-from-optional<U>) && three_way_comparable_with<T, U>
72
  constexpr compare_three_way_result_t<T, U>
73
  operator<=>(const optional<T>&, const U&);
74
 
75
  // [optional.specalg], specialized algorithms
76
  template<class T>
77
+ constexpr void swap(optional<T>&, optional<T>&) noexcept(see below);
78
 
79
  template<class T>
80
  constexpr optional<see below> make_optional(T&&);
81
  template<class T, class... Args>
82
  constexpr optional<T> make_optional(Args&&... args);
 
89
  }
90
  ```
91
 
92
  ### Class template `optional` <a id="optional.optional">[[optional.optional]]</a>
93
 
94
+ #### General <a id="optional.optional.general">[[optional.optional.general]]</a>
95
+
96
  ``` cpp
97
  namespace std {
98
  template<class T>
99
  class optional {
100
  public:
 
110
  template<class U, class... Args>
111
  constexpr explicit optional(in_place_t, initializer_list<U>, Args&&...);
112
  template<class U = T>
113
  constexpr explicit(see below) optional(U&&);
114
  template<class U>
115
+ constexpr explicit(see below) optional(const optional<U>&);
116
  template<class U>
117
+ constexpr explicit(see below) optional(optional<U>&&);
118
 
119
  // [optional.dtor], destructor
120
+ constexpr ~optional();
121
 
122
  // [optional.assign], assignment
123
+ constexpr optional& operator=(nullopt_t) noexcept;
124
  constexpr optional& operator=(const optional&);
125
  constexpr optional& operator=(optional&&) noexcept(see below);
126
+ template<class U = T> constexpr optional& operator=(U&&);
127
+ template<class U> constexpr optional& operator=(const optional<U>&);
128
+ template<class U> constexpr optional& operator=(optional<U>&&);
129
+ template<class... Args> constexpr T& emplace(Args&&...);
130
+ template<class U, class... Args> constexpr T& emplace(initializer_list<U>, Args&&...);
131
 
132
  // [optional.swap], swap
133
+ constexpr void swap(optional&) noexcept(see below);
134
 
135
  // [optional.observe], observers
136
+ constexpr const T* operator->() const noexcept;
137
+ constexpr T* operator->() noexcept;
138
+ constexpr const T& operator*() const & noexcept;
139
+ constexpr T& operator*() & noexcept;
140
+ constexpr T&& operator*() && noexcept;
141
+ constexpr const T&& operator*() const && noexcept;
142
  constexpr explicit operator bool() const noexcept;
143
  constexpr bool has_value() const noexcept;
144
  constexpr const T& value() const &;
145
  constexpr T& value() &;
146
  constexpr T&& value() &&;
147
  constexpr const T&& value() const &&;
148
  template<class U> constexpr T value_or(U&&) const &;
149
  template<class U> constexpr T value_or(U&&) &&;
150
 
151
+ // [optional.monadic], monadic operations
152
+ template<class F> constexpr auto and_then(F&& f) &;
153
+ template<class F> constexpr auto and_then(F&& f) &&;
154
+ template<class F> constexpr auto and_then(F&& f) const &;
155
+ template<class F> constexpr auto and_then(F&& f) const &&;
156
+ template<class F> constexpr auto transform(F&& f) &;
157
+ template<class F> constexpr auto transform(F&& f) &&;
158
+ template<class F> constexpr auto transform(F&& f) const &;
159
+ template<class F> constexpr auto transform(F&& f) const &&;
160
+ template<class F> constexpr optional or_else(F&& f) &&;
161
+ template<class F> constexpr optional or_else(F&& f) const &;
162
+
163
  // [optional.mod], modifiers
164
+ constexpr void reset() noexcept;
165
 
166
  private:
167
  T *val; // exposition only
168
  };
169
 
 
175
  Any instance of `optional<T>` at any given time either contains a value
176
  or does not contain a value. When an instance of `optional<T>` *contains
177
  a value*, it means that an object of type `T`, referred to as the
178
  optional object’s *contained value*, is allocated within the storage of
179
  the optional object. Implementations are not permitted to use additional
180
+ storage, such as dynamic memory, to allocate its contained value. When
181
+ an object of type `optional<T>` is contextually converted to `bool`, the
182
+ conversion returns `true` if the object contains a value; otherwise the
183
+ conversion returns `false`.
 
 
184
 
185
+ When an `optional<T>` object contains a value, member `val` points to
186
+ the contained value.
187
 
188
  `T` shall be a type other than cv `in_place_t` or cv `nullopt_t` that
189
  meets the *Cpp17Destructible* requirements ([[cpp17.destructible]]).
190
 
191
  #### Constructors <a id="optional.ctor">[[optional.ctor]]</a>
192
 
193
+ The exposition-only variable template *`converts-from-any-cvref`* is
194
+ used by some constructors for `optional`.
195
+
196
+ ``` cpp
197
+ template<class T, class W>
198
+ constexpr bool converts-from-any-cvref = // exposition only
199
+ disjunction_v<is_constructible<T, W&>, is_convertible<W&, T>,
200
+ is_constructible<T, W>, is_convertible<W, T>,
201
+ is_constructible<T, const W&>, is_convertible<const W&, T>,
202
+ is_constructible<T, const W>, is_convertible<const W, T>>;
203
+ ```
204
+
205
  ``` cpp
206
  constexpr optional() noexcept;
207
  constexpr optional(nullopt_t) noexcept;
208
  ```
209
 
 
214
 
215
  ``` cpp
216
  constexpr optional(const optional& rhs);
217
  ```
218
 
219
+ *Effects:* If `rhs` contains a value, direct-non-list-initializes the
220
+ contained value with `*rhs`.
 
221
 
222
+ *Ensures:* `rhs.has_value() == this->has_value()`.
223
 
224
  *Throws:* Any exception thrown by the selected constructor of `T`.
225
 
226
  *Remarks:* This constructor is defined as deleted unless
227
  `is_copy_constructible_v<T>` is `true`. If
 
232
  constexpr optional(optional&& rhs) noexcept(see below);
233
  ```
234
 
235
  *Constraints:* `is_move_constructible_v<T>` is `true`.
236
 
237
+ *Effects:* If `rhs` contains a value, direct-non-list-initializes the
238
+ contained value with `std::move(*rhs)`. `rhs.has_value()` is unchanged.
 
239
 
240
+ *Ensures:* `rhs.has_value() == this->has_value()`.
241
 
242
  *Throws:* Any exception thrown by the selected constructor of `T`.
243
 
244
+ *Remarks:* The exception specification is equivalent to
245
  `is_nothrow_move_constructible_v<T>`. If
246
  `is_trivially_move_constructible_v<T>` is `true`, this constructor is
247
  trivial.
248
 
249
  ``` cpp
250
  template<class... Args> constexpr explicit optional(in_place_t, Args&&... args);
251
  ```
252
 
253
  *Constraints:* `is_constructible_v<T, Args...>` is `true`.
254
 
255
+ *Effects:* Direct-non-list-initializes the contained value with
 
256
  `std::forward<Args>(args)...`.
257
 
258
  *Ensures:* `*this` contains a value.
259
 
260
  *Throws:* Any exception thrown by the selected constructor of `T`.
 
268
  ```
269
 
270
  *Constraints:* `is_constructible_v<T, initializer_list<U>&, Args...>` is
271
  `true`.
272
 
273
+ *Effects:* Direct-non-list-initializes the contained value with
 
274
  `il, std::forward<Args>(args)...`.
275
 
276
  *Ensures:* `*this` contains a value.
277
 
278
  *Throws:* Any exception thrown by the selected constructor of `T`.
 
282
 
283
  ``` cpp
284
  template<class U = T> constexpr explicit(see below) optional(U&& v);
285
  ```
286
 
287
+ *Constraints:*
 
 
288
 
289
+ - `is_constructible_v<T, U>` is `true`,
290
+ - `is_same_v<remove_cvref_t<U>, in_place_t>` is `false`,
291
+ - `is_same_v<remove_cvref_t<U>, optional>` is `false`, and
292
+ - if `T` is cv `bool`, `remove_cvref_t<U>` is not a specialization of
293
+ `optional`.
294
+
295
+ *Effects:* Direct-non-list-initializes the contained value with
296
  `std::forward<U>(v)`.
297
 
298
  *Ensures:* `*this` contains a value.
299
 
300
  *Throws:* Any exception thrown by the selected constructor of `T`.
 
306
  ``` cpp
307
  !is_convertible_v<U, T>
308
  ```
309
 
310
  ``` cpp
311
+ template<class U> constexpr explicit(see below) optional(const optional<U>& rhs);
312
  ```
313
 
314
  *Constraints:*
315
 
316
+ - `is_constructible_v<T, const U&>` is `true`, and
317
+ - if `T` is not cv `bool`, *`converts-from-any-cvref`*`<T, optional<U>>`
318
+ is `false`.
 
 
 
 
 
 
319
 
320
+ *Effects:* If `rhs` contains a value, direct-non-list-initializes the
321
+ contained value with `*rhs`.
 
322
 
323
+ *Ensures:* `rhs.has_value() == this->has_value()`.
324
 
325
  *Throws:* Any exception thrown by the selected constructor of `T`.
326
 
327
  *Remarks:* The expression inside `explicit` is equivalent to:
328
 
329
  ``` cpp
330
  !is_convertible_v<const U&, T>
331
  ```
332
 
333
  ``` cpp
334
+ template<class U> constexpr explicit(see below) optional(optional<U>&& rhs);
335
  ```
336
 
337
  *Constraints:*
338
 
339
+ - `is_constructible_v<T, U>` is `true`, and
340
+ - if `T` is not cv `bool`, *`converts-from-any-cvref`*`<T, optional<U>>`
341
+ is `false`.
 
 
 
 
 
 
342
 
343
+ *Effects:* If `rhs` contains a value, direct-non-list-initializes the
344
+ contained value with `std::move(*rhs)`. `rhs.has_value()` is unchanged.
 
345
 
346
+ *Ensures:* `rhs.has_value() == this->has_value()`.
347
 
348
  *Throws:* Any exception thrown by the selected constructor of `T`.
349
 
350
  *Remarks:* The expression inside `explicit` is equivalent to:
351
 
 
354
  ```
355
 
356
  #### Destructor <a id="optional.dtor">[[optional.dtor]]</a>
357
 
358
  ``` cpp
359
+ constexpr ~optional();
360
  ```
361
 
362
  *Effects:* If `is_trivially_destructible_v<T> != true` and `*this`
363
  contains a value, calls
364
 
 
370
  destructor is trivial.
371
 
372
  #### Assignment <a id="optional.assign">[[optional.assign]]</a>
373
 
374
  ``` cpp
375
+ constexpr optional<T>& operator=(nullopt_t) noexcept;
376
  ```
377
 
378
  *Effects:* If `*this` contains a value, calls `val->T::T̃()` to destroy
379
  the contained value; otherwise no effect.
380
 
 
389
  *Effects:* See [[optional.assign.copy]].
390
 
391
  **Table: `optional::operator=(const optional&)` effects** <a id="optional.assign.copy">[optional.assign.copy]</a>
392
 
393
  | | `*this` contains a value | `*this` does not contain a value |
394
+ | ------------------------------ | ------------------------------------------------------ | ----------------------------------------------------------- |
395
+ | `rhs` contains a value | assigns `*rhs` to the contained value | direct-non-list-initializes the contained value with `*rhs` |
396
  | `rhs` does not contain a value | destroys the contained value by calling `val->T::~T()` | no effect |
397
 
398
 
399
+ *Ensures:* `rhs.has_value() == this->has_value()`.
400
 
401
  *Returns:* `*this`.
402
 
403
  *Remarks:* If any exception is thrown, the result of the expression
404
+ `this->has_value()` remains unchanged. If an exception is thrown during
405
+ the call to `T`’s copy constructor, no effect. If an exception is thrown
406
  during the call to `T`’s copy assignment, the state of its contained
407
  value is as defined by the exception safety guarantee of `T`’s copy
408
  assignment. This operator is defined as deleted unless
409
  `is_copy_constructible_v<T>` is `true` and `is_copy_assignable_v<T>` is
410
  `true`. If `is_trivially_copy_constructible_v<T> &&`
 
417
 
418
  *Constraints:* `is_move_constructible_v<T>` is `true` and
419
  `is_move_assignable_v<T>` is `true`.
420
 
421
  *Effects:* See [[optional.assign.move]]. The result of the expression
422
+ `rhs.has_value()` remains unchanged.
423
 
424
  **Table: `optional::operator=(optional&&)` effects** <a id="optional.assign.move">[optional.assign.move]</a>
425
 
426
  | | `*this` contains a value | `*this` does not contain a value |
427
+ | ------------------------------ | ------------------------------------------------------ | ---------------------------------------------------------------------- |
428
+ | `rhs` contains a value | assigns `std::move(*rhs)` to the contained value | direct-non-list-initializes the contained value with `std::move(*rhs)` |
429
  | `rhs` does not contain a value | destroys the contained value by calling `val->T::~T()` | no effect |
430
 
431
 
432
+ *Ensures:* `rhs.has_value() == this->has_value()`.
433
 
434
  *Returns:* `*this`.
435
 
436
+ *Remarks:* The exception specification is equivalent to:
437
 
438
  ``` cpp
439
  is_nothrow_move_assignable_v<T> && is_nothrow_move_constructible_v<T>
440
  ```
441
 
442
+ If any exception is thrown, the result of the expression
443
+ `this->has_value()` remains unchanged. If an exception is thrown during
444
+ the call to `T`’s move constructor, the state of `*rhs.val` is
445
+ determined by the exception safety guarantee of `T`’s move constructor.
446
+ If an exception is thrown during the call to `T`’s move assignment, the
447
+ state of `*val` and `*rhs.val` is determined by the exception safety
448
+ guarantee of `T`’s move assignment. If
449
+ `is_trivially_move_constructible_v<T> &&`
450
  `is_trivially_move_assignable_v<T> &&` `is_trivially_destructible_v<T>`
451
  is `true`, this assignment operator is trivial.
452
 
453
  ``` cpp
454
+ template<class U = T> constexpr optional<T>& operator=(U&& v);
455
  ```
456
 
457
  *Constraints:* `is_same_v<remove_cvref_t<U>, optional>` is `false`,
458
  `conjunction_v<is_scalar<T>, is_same<T, decay_t<U>>>` is `false`,
459
  `is_constructible_v<T, U>` is `true`, and `is_assignable_v<T&, U>` is
460
  `true`.
461
 
462
  *Effects:* If `*this` contains a value, assigns `std::forward<U>(v)` to
463
+ the contained value; otherwise direct-non-list-initializes the contained
464
+ value with `std::forward<U>(v)`.
 
465
 
466
  *Ensures:* `*this` contains a value.
467
 
468
  *Returns:* `*this`.
469
 
470
  *Remarks:* If any exception is thrown, the result of the expression
471
+ `this->has_value()` remains unchanged. If an exception is thrown during
472
+ the call to `T`’s constructor, the state of `v` is determined by the
473
  exception safety guarantee of `T`’s constructor. If an exception is
474
  thrown during the call to `T`’s assignment, the state of `*val` and `v`
475
  is determined by the exception safety guarantee of `T`’s assignment.
476
 
477
  ``` cpp
478
+ template<class U> constexpr optional<T>& operator=(const optional<U>& rhs);
479
  ```
480
 
481
  *Constraints:*
482
 
483
  - `is_constructible_v<T, const U&>` is `true`,
484
  - `is_assignable_v<T&, const U&>` is `true`,
485
+ - *`converts-from-any-cvref`*`<T, optional<U>>` is `false`,
 
 
 
 
 
 
 
486
  - `is_assignable_v<T&, optional<U>&>` is `false`,
487
  - `is_assignable_v<T&, optional<U>&&>` is `false`,
488
  - `is_assignable_v<T&, const optional<U>&>` is `false`, and
489
  - `is_assignable_v<T&, const optional<U>&&>` is `false`.
490
 
491
  *Effects:* See [[optional.assign.copy.templ]].
492
 
493
  **Table: `optional::operator=(const optional<U>&)` effects** <a id="optional.assign.copy.templ">[optional.assign.copy.templ]</a>
494
 
495
  | | `*this` contains a value | `*this` does not contain a value |
496
+ | ------------------------------ | ------------------------------------------------------ | ----------------------------------------------------------- |
497
+ | `rhs` contains a value | assigns `*rhs` to the contained value | direct-non-list-initializes the contained value with `*rhs` |
498
  | `rhs` does not contain a value | destroys the contained value by calling `val->T::~T()` | no effect |
499
 
500
 
501
+ *Ensures:* `rhs.has_value() == this->has_value()`.
502
 
503
  *Returns:* `*this`.
504
 
505
  *Remarks:* If any exception is thrown, the result of the expression
506
+ `this->has_value()` remains unchanged. If an exception is thrown during
507
+ the call to `T`’s constructor, the state of `*rhs.val` is determined by
508
+ the exception safety guarantee of `T`’s constructor. If an exception is
509
  thrown during the call to `T`’s assignment, the state of `*val` and
510
  `*rhs.val` is determined by the exception safety guarantee of `T`’s
511
  assignment.
512
 
513
  ``` cpp
514
+ template<class U> constexpr optional<T>& operator=(optional<U>&& rhs);
515
  ```
516
 
517
  *Constraints:*
518
 
519
  - `is_constructible_v<T, U>` is `true`,
520
  - `is_assignable_v<T&, U>` is `true`,
521
+ - *`converts-from-any-cvref`*`<T, optional<U>>` is `false`,
 
 
 
 
 
 
 
522
  - `is_assignable_v<T&, optional<U>&>` is `false`,
523
  - `is_assignable_v<T&, optional<U>&&>` is `false`,
524
  - `is_assignable_v<T&, const optional<U>&>` is `false`, and
525
  - `is_assignable_v<T&, const optional<U>&&>` is `false`.
526
 
527
  *Effects:* See [[optional.assign.move.templ]]. The result of the
528
+ expression `rhs.has_value()` remains unchanged.
529
 
530
  **Table: `optional::operator=(optional<U>&&)` effects** <a id="optional.assign.move.templ">[optional.assign.move.templ]</a>
531
 
532
  | | `*this` contains a value | `*this` does not contain a value |
533
+ | ------------------------------ | ------------------------------------------------------ | ---------------------------------------------------------------------- |
534
+ | `rhs` contains a value | assigns `std::move(*rhs)` to the contained value | direct-non-list-initializes the contained value with `std::move(*rhs)` |
535
  | `rhs` does not contain a value | destroys the contained value by calling `val->T::~T()` | no effect |
536
 
537
 
538
+ *Ensures:* `rhs.has_value() == this->has_value()`.
539
 
540
  *Returns:* `*this`.
541
 
542
  *Remarks:* If any exception is thrown, the result of the expression
543
+ `this->has_value()` remains unchanged. If an exception is thrown during
544
+ the call to `T`’s constructor, the state of `*rhs.val` is determined by
545
+ the exception safety guarantee of `T`’s constructor. If an exception is
546
  thrown during the call to `T`’s assignment, the state of `*val` and
547
  `*rhs.val` is determined by the exception safety guarantee of `T`’s
548
  assignment.
549
 
550
  ``` cpp
551
+ template<class... Args> constexpr T& emplace(Args&&... args);
552
  ```
553
 
554
  *Mandates:* `is_constructible_v<T, Args...>` is `true`.
555
 
556
+ *Effects:* Calls `*this = nullopt`. Then direct-non-list-initializes the
557
+ contained value with `std::forward<Args>(args)...`.
 
558
 
559
  *Ensures:* `*this` contains a value.
560
 
561
  *Returns:* A reference to the new contained value.
562
 
 
565
  *Remarks:* If an exception is thrown during the call to `T`’s
566
  constructor, `*this` does not contain a value, and the previous `*val`
567
  (if any) has been destroyed.
568
 
569
  ``` cpp
570
+ template<class U, class... Args> constexpr 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 direct-non-list-initializes the
577
+ contained value with `il, std::forward<Args>(args)...`.
 
578
 
579
  *Ensures:* `*this` contains a value.
580
 
581
  *Returns:* A reference to the new contained value.
582
 
 
587
  (if any) has been destroyed.
588
 
589
  #### Swap <a id="optional.swap">[[optional.swap]]</a>
590
 
591
  ``` cpp
592
+ constexpr void swap(optional& rhs) noexcept(see below);
593
  ```
594
 
595
  *Mandates:* `is_move_constructible_v<T>` is `true`.
596
 
597
+ *Preconditions:* `T` meets the *Cpp17Swappable*
598
+ requirements [[swappable.requirements]].
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)` | direct-non-list-initializes the contained value of `*this` with `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 | direct-non-list-initializes the contained value of `rhs` with `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 exception specification is equivalent to:
614
 
615
  ``` cpp
616
  is_nothrow_move_constructible_v<T> && is_nothrow_swappable_v<T>
617
  ```
618
 
619
+ If any exception is thrown, the results of the expressions
620
+ `this->has_value()` and `rhs.has_value()` remain unchanged. If an
621
+ exception is thrown during the call to function `swap`, the state of
622
+ `*val` and `*rhs.val` is determined by the exception safety guarantee of
623
+ `swap` for lvalues of `T`. If an exception is thrown during the call to
624
+ `T`’s move constructor, the state of `*val` and `*rhs.val` is determined
625
+ by the exception safety guarantee of `T`’s move constructor.
626
 
627
  #### Observers <a id="optional.observe">[[optional.observe]]</a>
628
 
629
  ``` cpp
630
+ constexpr const T* operator->() const noexcept;
631
+ constexpr T* operator->() noexcept;
632
  ```
633
 
634
  *Preconditions:* `*this` contains a value.
635
 
636
  *Returns:* `val`.
637
 
 
 
638
  *Remarks:* These functions are constexpr functions.
639
 
640
  ``` cpp
641
+ constexpr const T& operator*() const & noexcept;
642
+ constexpr T& operator*() & noexcept;
643
  ```
644
 
645
  *Preconditions:* `*this` contains a value.
646
 
647
  *Returns:* `*val`.
648
 
 
 
649
  *Remarks:* These functions are constexpr functions.
650
 
651
  ``` cpp
652
+ constexpr T&& operator*() && noexcept;
653
+ constexpr const T&& operator*() const && noexcept;
654
  ```
655
 
656
  *Preconditions:* `*this` contains a value.
657
 
658
  *Effects:* Equivalent to: `return std::move(*val);`
 
679
  ```
680
 
681
  *Effects:* Equivalent to:
682
 
683
  ``` cpp
684
+ return has_value() ? *val : throw bad_optional_access();
685
  ```
686
 
687
  ``` cpp
688
  constexpr T&& value() &&;
689
  constexpr const T&& value() const &&;
690
  ```
691
 
692
  *Effects:* Equivalent to:
693
 
694
  ``` cpp
695
+ return has_value() ? std::move(*val) : throw bad_optional_access();
696
  ```
697
 
698
  ``` cpp
699
  template<class U> constexpr T value_or(U&& v) const &;
700
  ```
 
703
  `true`.
704
 
705
  *Effects:* Equivalent to:
706
 
707
  ``` cpp
708
+ return has_value() ? **this : static_cast<T>(std::forward<U>(v));
709
  ```
710
 
711
  ``` cpp
712
  template<class U> constexpr T value_or(U&& v) &&;
713
  ```
 
716
  `true`.
717
 
718
  *Effects:* Equivalent to:
719
 
720
  ``` cpp
721
+ return has_value() ? std::move(**this) : static_cast<T>(std::forward<U>(v));
722
+ ```
723
+
724
+ #### Monadic operations <a id="optional.monadic">[[optional.monadic]]</a>
725
+
726
+ ``` cpp
727
+ template<class F> constexpr auto and_then(F&& f) &;
728
+ template<class F> constexpr auto and_then(F&& f) const &;
729
+ ```
730
+
731
+ Let `U` be `invoke_result_t<F, decltype(value())>`.
732
+
733
+ *Mandates:* `remove_cvref_t<U>` is a specialization of `optional`.
734
+
735
+ *Effects:* Equivalent to:
736
+
737
+ ``` cpp
738
+ if (*this) {
739
+ return invoke(std::forward<F>(f), value());
740
+ } else {
741
+ return remove_cvref_t<U>();
742
+ }
743
+ ```
744
+
745
+ ``` cpp
746
+ template<class F> constexpr auto and_then(F&& f) &&;
747
+ template<class F> constexpr auto and_then(F&& f) const &&;
748
+ ```
749
+
750
+ Let `U` be `invoke_result_t<F, decltype(std::move(value()))>`.
751
+
752
+ *Mandates:* `remove_cvref_t<U>` is a specialization of `optional`.
753
+
754
+ *Effects:* Equivalent to:
755
+
756
+ ``` cpp
757
+ if (*this) {
758
+ return invoke(std::forward<F>(f), std::move(value()));
759
+ } else {
760
+ return remove_cvref_t<U>();
761
+ }
762
+ ```
763
+
764
+ ``` cpp
765
+ template<class F> constexpr auto transform(F&& f) &;
766
+ template<class F> constexpr auto transform(F&& f) const &;
767
+ ```
768
+
769
+ Let `U` be `remove_cv_t<invoke_result_t<F, decltype(value())>>`.
770
+
771
+ *Mandates:* `U` is a non-array object type other than `in_place_t` or
772
+ `nullopt_t`. The declaration
773
+
774
+ ``` cpp
775
+ U u(invoke(std::forward<F>(f), value()));
776
+ ```
777
+
778
+ is well-formed for some invented variable `u`.
779
+
780
+ [*Note 1*: There is no requirement that `U` is
781
+ movable [[dcl.init.general]]. — *end note*]
782
+
783
+ *Returns:* If `*this` contains a value, an `optional<U>` object whose
784
+ contained value is direct-non-list-initialized with
785
+ `invoke(std::forward<F>(f), value())`; otherwise, `optional<U>()`.
786
+
787
+ ``` cpp
788
+ template<class F> constexpr auto transform(F&& f) &&;
789
+ template<class F> constexpr auto transform(F&& f) const &&;
790
+ ```
791
+
792
+ Let `U` be
793
+ `remove_cv_t<invoke_result_t<F, decltype(std::move(value()))>>`.
794
+
795
+ *Mandates:* `U` is a non-array object type other than `in_place_t` or
796
+ `nullopt_t`. The declaration
797
+
798
+ ``` cpp
799
+ U u(invoke(std::forward<F>(f), std::move(value())));
800
+ ```
801
+
802
+ is well-formed for some invented variable `u`.
803
+
804
+ [*Note 2*: There is no requirement that `U` is
805
+ movable [[dcl.init.general]]. — *end note*]
806
+
807
+ *Returns:* If `*this` contains a value, an `optional<U>` object whose
808
+ contained value is direct-non-list-initialized with
809
+ `invoke(std::forward<F>(f), std::move(value()))`; otherwise,
810
+ `optional<U>()`.
811
+
812
+ ``` cpp
813
+ template<class F> constexpr optional or_else(F&& f) const &;
814
+ ```
815
+
816
+ *Constraints:* `F` models `invocable<>` and `T` models
817
+ `copy_constructible`.
818
+
819
+ *Mandates:* `is_same_v<remove_cvref_t<invoke_result_t<F>>, optional>` is
820
+ `true`.
821
+
822
+ *Effects:* Equivalent to:
823
+
824
+ ``` cpp
825
+ if (*this) {
826
+ return *this;
827
+ } else {
828
+ return std::forward<F>(f)();
829
+ }
830
+ ```
831
+
832
+ ``` cpp
833
+ template<class F> constexpr optional or_else(F&& f) &&;
834
+ ```
835
+
836
+ *Constraints:* `F` models `invocable<>` and `T` models
837
+ `move_constructible`.
838
+
839
+ *Mandates:* `is_same_v<remove_cvref_t<invoke_result_t<F>>, optional>` is
840
+ `true`.
841
+
842
+ *Effects:* Equivalent to:
843
+
844
+ ``` cpp
845
+ if (*this) {
846
+ return std::move(*this);
847
+ } else {
848
+ return std::forward<F>(f)();
849
+ }
850
  ```
851
 
852
  #### Modifiers <a id="optional.mod">[[optional.mod]]</a>
853
 
854
  ``` cpp
855
+ constexpr void reset() noexcept;
856
  ```
857
 
858
  *Effects:* If `*this` contains a value, calls `val->T::T̃()` to destroy
859
  the contained value; otherwise no effect.
860
 
 
877
  initializer-list constructor, and shall not be an aggregate.
878
 
879
  ### Class `bad_optional_access` <a id="optional.bad.access">[[optional.bad.access]]</a>
880
 
881
  ``` cpp
882
+ namespace std {
883
  class bad_optional_access : public exception {
884
  public:
885
  // see [exception] for the specification of the special member functions
886
  const char* what() const noexcept override;
887
  };
888
+ }
889
  ```
890
 
891
  The class `bad_optional_access` defines the type of objects thrown as
892
  exceptions to report the situation where an attempt is made to access
893
  the value of an optional object that does not contain a value.
 
907
  *Mandates:* The expression `*x == *y` is well-formed and its result is
908
  convertible to `bool`.
909
 
910
  [*Note 1*: `T` need not be *Cpp17EqualityComparable*. — *end note*]
911
 
912
+ *Returns:* If `x.has_value() != y.has_value()`, `false`; otherwise if
913
+ `x.has_value() == false`, `true`; otherwise `*x == *y`.
914
 
915
  *Remarks:* Specializations of this function template for which
916
  `*x == *y` is a core constant expression are constexpr functions.
917
 
918
  ``` cpp
 
920
  ```
921
 
922
  *Mandates:* The expression `*x != *y` is well-formed and its result is
923
  convertible to `bool`.
924
 
925
+ *Returns:* If `x.has_value() != y.has_value()`, `true`; otherwise, if
926
+ `x.has_value() == false`, `false`; otherwise `*x != *y`.
927
 
928
  *Remarks:* Specializations of this function template for which
929
  `*x != *y` is a core constant expression are constexpr functions.
930
 
931
  ``` cpp
 
984
  template<class T, three_way_comparable_with<T> U>
985
  constexpr compare_three_way_result_t<T, U>
986
  operator<=>(const optional<T>& x, const optional<U>& y);
987
  ```
988
 
989
+ *Returns:* If `x && y`, `*x <=> *y`; otherwise
990
+ `x.has_value() <=> y.has_value()`.
991
 
992
  *Remarks:* Specializations of this function template for which
993
  `*x <=> *y` is a core constant expression are constexpr functions.
994
 
995
  ### Comparison with `nullopt` <a id="optional.nullops">[[optional.nullops]]</a>
 
1002
 
1003
  ``` cpp
1004
  template<class T> constexpr strong_ordering operator<=>(const optional<T>& x, nullopt_t) noexcept;
1005
  ```
1006
 
1007
+ *Returns:* `x.has_value() <=> false`.
1008
 
1009
  ### Comparison with `T` <a id="optional.comp.with.t">[[optional.comp.with.t]]</a>
1010
 
1011
  ``` cpp
1012
  template<class T, class U> constexpr bool operator==(const optional<T>& x, const U& v);
 
1015
  *Mandates:* The expression `*x == v` is well-formed and its result is
1016
  convertible to `bool`.
1017
 
1018
  [*Note 1*: `T` need not be *Cpp17EqualityComparable*. — *end note*]
1019
 
1020
+ *Effects:* Equivalent to: `return x.has_value() ? *x == v : false;`
1021
 
1022
  ``` cpp
1023
  template<class T, class U> constexpr bool operator==(const T& v, const optional<U>& x);
1024
  ```
1025
 
1026
  *Mandates:* The expression `v == *x` is well-formed and its result is
1027
  convertible to `bool`.
1028
 
1029
+ *Effects:* Equivalent to: `return x.has_value() ? v == *x : false;`
1030
 
1031
  ``` cpp
1032
  template<class T, class U> constexpr bool operator!=(const optional<T>& x, const U& v);
1033
  ```
1034
 
1035
  *Mandates:* The expression `*x != v` is well-formed and its result is
1036
  convertible to `bool`.
1037
 
1038
+ *Effects:* Equivalent to: `return x.has_value() ? *x != v : true;`
1039
 
1040
  ``` cpp
1041
  template<class T, class U> constexpr bool operator!=(const T& v, const optional<U>& x);
1042
  ```
1043
 
1044
  *Mandates:* The expression `v != *x` is well-formed and its result is
1045
  convertible to `bool`.
1046
 
1047
+ *Effects:* Equivalent to: `return x.has_value() ? v != *x : true;`
1048
 
1049
  ``` cpp
1050
  template<class T, class U> constexpr bool operator<(const optional<T>& x, const U& v);
1051
  ```
1052
 
1053
  *Mandates:* The expression `*x < v` is well-formed and its result is
1054
  convertible to `bool`.
1055
 
1056
+ *Effects:* Equivalent to: `return x.has_value() ? *x < v : true;`
1057
 
1058
  ``` cpp
1059
  template<class T, class U> constexpr bool operator<(const T& v, const optional<U>& x);
1060
  ```
1061
 
1062
  *Mandates:* The expression `v < *x` is well-formed and its result is
1063
  convertible to `bool`.
1064
 
1065
+ *Effects:* Equivalent to: `return x.has_value() ? v < *x : false;`
1066
 
1067
  ``` cpp
1068
  template<class T, class U> constexpr bool operator>(const optional<T>& x, const U& v);
1069
  ```
1070
 
1071
  *Mandates:* The expression `*x > v` is well-formed and its result is
1072
  convertible to `bool`.
1073
 
1074
+ *Effects:* Equivalent to: `return x.has_value() ? *x > v : false;`
1075
 
1076
  ``` cpp
1077
  template<class T, class U> constexpr bool operator>(const T& v, const optional<U>& x);
1078
  ```
1079
 
1080
  *Mandates:* The expression `v > *x` is well-formed and its result is
1081
  convertible to `bool`.
1082
 
1083
+ *Effects:* Equivalent to: `return x.has_value() ? v > *x : true;`
1084
 
1085
  ``` cpp
1086
  template<class T, class U> constexpr bool operator<=(const optional<T>& x, const U& v);
1087
  ```
1088
 
1089
  *Mandates:* The expression `*x <= v` is well-formed and its result is
1090
  convertible to `bool`.
1091
 
1092
+ *Effects:* Equivalent to: `return x.has_value() ? *x <= v : true;`
1093
 
1094
  ``` cpp
1095
  template<class T, class U> constexpr bool operator<=(const T& v, const optional<U>& x);
1096
  ```
1097
 
1098
  *Mandates:* The expression `v <= *x` is well-formed and its result is
1099
  convertible to `bool`.
1100
 
1101
+ *Effects:* Equivalent to: `return x.has_value() ? v <= *x : false;`
1102
 
1103
  ``` cpp
1104
  template<class T, class U> constexpr bool operator>=(const optional<T>& x, const U& v);
1105
  ```
1106
 
1107
  *Mandates:* The expression `*x >= v` is well-formed and its result is
1108
  convertible to `bool`.
1109
 
1110
+ *Effects:* Equivalent to: `return x.has_value() ? *x >= v : false;`
1111
 
1112
  ``` cpp
1113
  template<class T, class U> constexpr bool operator>=(const T& v, const optional<U>& x);
1114
  ```
1115
 
1116
  *Mandates:* The expression `v >= *x` is well-formed and its result is
1117
  convertible to `bool`.
1118
 
1119
+ *Effects:* Equivalent to: `return x.has_value() ? v >= *x : true;`
1120
 
1121
  ``` cpp
1122
+ template<class T, class U>
1123
+ requires (!is-derived-from-optional<U>) && three_way_comparable_with<T, U>
1124
  constexpr compare_three_way_result_t<T, U>
1125
  operator<=>(const optional<T>& x, const U& v);
1126
  ```
1127
 
1128
  *Effects:* Equivalent to:
1129
+ `return x.has_value() ? *x <=> v : strong_ordering::less;`
1130
 
1131
  ### Specialized algorithms <a id="optional.specalg">[[optional.specalg]]</a>
1132
 
1133
  ``` cpp
1134
+ template<class T>
1135
+ constexpr void swap(optional<T>& x, optional<T>& y) noexcept(noexcept(x.swap(y)));
1136
  ```
1137
 
1138
  *Constraints:* `is_move_constructible_v<T>` is `true` and
1139
  `is_swappable_v<T>` is `true`.
1140
 
 
1168
  template<class T> struct hash<optional<T>>;
1169
  ```
1170
 
1171
  The specialization `hash<optional<T>>` is enabled [[unord.hash]] if and
1172
  only if `hash<remove_const_t<T>>` is enabled. When enabled, for an
1173
+ object `o` of type `optional<T>`, if `o.has_value() == true`, then
1174
  `hash<optional<T>>()(o)` evaluates to the same value as
1175
  `hash<remove_const_t<T>>()(*o)`; otherwise it evaluates to an
1176
  unspecified value. The member functions are not guaranteed to be
1177
  `noexcept`.
1178