```
void swap(optional& rhs) noexcept(see below);
```

Table 45: optional::swap(optional&) effects [tab:optional.swap]

*this contains a value | *this does not contain a value | ||

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 | |

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 |

Remarks:
The expression inside noexcept is equivalent to:

is_nothrow_move_constructible_v<T> && is_nothrow_swappable_v<T>

If any exception is thrown, the results of the expressions bool(*this) and bool(rhs) remain unchanged.

If an exception is thrown during the call to function swap,
the state of *val and *rhs.val is determined by the exception safety guarantee of swap for lvalues of T.

If an exception is thrown during the call to T's move constructor,
the state of *val and *rhs.val is determined by the exception safety guarantee of T's move constructor.