| Home | Libraries | People | FAQ | More

## Exception Safety Guarantees

This library assumes that `T`'s destructor does not throw exceptions. If it does, the behaviour of many operations on `optional<T>` is undefined.

The following mutating operations never throw exceptions:

- `optional<T>::operator= ( none_t ) noexcept`
- `optional<T>::reset() noexcept`

In addition, the following constructors and the destructor never throw exceptions:

- `optional<T>::optional() noexcept`
- `optional<T>::optional( none_t ) noexcept`

Regarding the following assignment functions:

- `optional<T>::operator= ( optional<T> const& )`
- `optional<T>::operator= ( T const& )`
- `template<class U> optional<T>::operator= ( optional<U> const& )`
- `template<class InPlaceFactory> optional<T>::operator= ( InPlaceFactory const& )`
- `template<class TypedInPlaceFactory> optional<T>::operator= ( TypedInPlaceFactory const& )`
- `optional<T>::reset( T const& )`

They forward calls to the corresponding `T`'s constructors or assignments (depending on whether the optional object is initialized or not); so if both `T`'s constructor and the assignment provide strong exception safety guarantee, `optional<T>`'s assignment also provides strong exception safety guarantee; otherwise we only get the basic guarantee. Additionally, if both involved `T`'s constructor and the assignment never throw, `optional<T>`'s assignment also never throws.

Unless `T`'s constructor or assignment throws, assignments to `optional<T>` do not throw anything else on its own. A throw during assignment never changes the initialization state of any optional object involved:

    optional<T> opt1(val1);
    optional<T> opt2(val2);
    assert(opt1);
    assert(opt2);

    try
    {
      opt1 = opt2; // throws
    }
    catch(...)
    {
      assert(opt1);
      assert(opt2);
    }

This also applies to move assignments/constructors. However, move operations are made no-throw more often.

Operation `emplace` provides basic exception safety guarantee. If it throws, the optional object becomes uninitialized regardless of its initial state, and its previous contained value (if any) is destroyed. It doesn't call any assignment or move/copy constructor on `T`.

#### Swap

Unless `swap` on optional is customized, its primary implementation forwards calls to `T`'s `swap` or move constructor (depending on the initialization state of the optional objects). Thus, if both `T`'s `swap` and move constructor never throw, `swap` on `optional<T>` never throws. similarly, if both `T`'s `swap` and move constructor offer strong guarantee, `swap` on `optional<T>` also offers a strong guarantee.

In case `swap` on optional is customized, the call to `T`'s move constructor are replaced with the calls to `T`'s default constructor followed by `swap`. (This is more useful on older compilers that do not support move semantics, when one wants to achieve stronger exception safety guarantees.) In this case the exception safety guarantees for `swap` are reliant on the guarantees of `T`'s `swap` and default constructor