| Home | Libraries | People | FAQ | More

#### Detailed Semantics

Because `T` might be of reference type, in the sequel, those entries whose semantic depends on `T` being of reference type or not will be distinguished using the following convention:

- If the entry reads: `optional<T`(not a ref)`>`, the description corresponds only to the case where `T` is not of reference type.
- If the entry reads: `optional<T&>`, the description corresponds only to the case where `T` is of reference type.
- If the entry reads: `optional<T>`, the description is the same for both cases.

| Note
The following section contains various `assert()` which are used only to show the postconditions as sample code. It is not implied that the type `T` must support each particular expression but that if the expression is supported, the implied condition holds.

###### optional class member functions

> `optional<T>::optional() noexcept;`

- Effect: Default-Constructs an `optional`.
- Postconditions: `*this` is uninitialized.
- Notes: T's default constructor is not called.
- Example:

      optional<T> def ;
      assert ( !def ) ;

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

- Effect: Constructs an `optional` uninitialized.
- Postconditions: `*this` is uninitialized.
- Notes: `T`'s default constructor is not called. The expression `boost::none` denotes an instance of `boost::none_t` that can be used as the parameter.
- Example:

      #include <boost/none.hpp>
      optional<T> n(none) ;
      assert ( !n ) ;

> `optional<T` (not a ref)`>::optional( T const& v )`

- Requires: `is_copy_constructible<T>::value` is `true`.
- Effect: Directly-Constructs an `optional`.
- Postconditions: `*this` is initialized and its value is a copy of `v`.
- Throws: Whatever `T::T( T const& )` throws.
- Notes: `T::T( T const& )` is called.
- Exception Safety: Exceptions can only be thrown during `T::T( T const& );` in that case, this constructor has no effect.
- Example:

      T v;
      optional<T> opt(v);
      assert ( *opt == v ) ;

> `optional<T&>::optional( T& ref )`

- Effect: Directly-Constructs an `optional`.
- Postconditions: `*this` is initialized and its value is an instance of an internal type wrapping the reference `ref`.
- Throws: Nothing.
- Example:

      T v;
      T& vref = v ;
      optional<T&> opt(vref);
      assert ( *opt == v ) ;
      ++ v ; // mutate referee
      assert (*opt == v);

> `optional<T` (not a ref)`>::optional( T&& v )`

- Requires: `is_move_constructible<T>::value` is `true`.
- Effect: Directly-Move-Constructs an `optional`.
- Postconditions: `*this` is initialized and its value is move-constructed from `v`.
- Throws: Whatever `T::T( T&& )` throws.
- Notes: `T::T( T&& )` is called.
- Exception Safety: Exceptions can only be thrown during `T::T( T&& );` in that case, the state of `v` is determined by exception safety guarantees for `T::T(T&&)`.
- Example:

      T v1, v2;
      optional<T> opt(std::move(v1));
      assert ( *opt == v2 ) ;

> `optional<T&>::optional( T&& ref ) = delete`

- Notes: This constructor is deleted

> `optional<T` (not a ref)`>::optional( bool condition, T const& v ) ;`

> `optional<T&> ::optional( bool condition, T& v ) ;`

- If condition is true, same as:

> `optional<T` (not a ref)`>::optional( T const& v )`

> `optional<T&> ::optional( T& v )`

- otherwise, same as:

> `optional<T` (not a ref)`>::optional()`

> `optional<T&> ::optional()`

> `optional<T` (not a ref)`>::optional( optional const& rhs );`

- Requires: `is_copy_constructible<T>::value` is `true`.
- Effect: Copy-Constructs an `optional`.
- Postconditions: If rhs is initialized, `*this` is initialized and its value is a copy of the value of `rhs`; else `*this` is uninitialized.
- Throws: Whatever `T::T( T const& )` throws.
- Notes: If rhs is initialized, `T::T(T const& )` is called.
- Exception Safety: Exceptions can only be thrown during `T::T( T const& );` in that case, this constructor has no effect.
- Example:

      optional<T> uninit ;
      assert (!uninit);

      optional<T> uinit2 ( uninit ) ;
      assert ( uninit2 == uninit );

      optional<T> init( T(2) );
      assert ( *init == T(2) ) ;

      optional<T> init2 ( init ) ;
      assert ( init2 == init ) ;

> `optional<T&>::optional( optional const& rhs );`

- Effect: Copy-Constructs an `optional`.
- Postconditions: If `rhs` is initialized, `*this` is initialized and its value is another reference to the same object referenced by `*rhs`; else `*this` is uninitialized.
- Throws: Nothing.
- Notes: If `rhs` is initialized, both `*this` and `*rhs` will refer to the same object (they alias).
- Example:

      optional<T&> uninit ;
      assert (!uninit);

      optional<T&> uinit2 ( uninit ) ;
      assert ( uninit2 == uninit );

      T v = 2 ; T& ref = v ;
      optional<T> init(ref);
      assert ( *init == v ) ;

      optional<T> init2 ( init ) ;
      assert ( *init2 == v ) ;

      v = 3 ;

      assert ( *init  == 3 ) ;
      assert ( *init2 == 3 ) ;

> `optional<T` (not a ref)`>::optional( optional&& rhs ) noexcept(`see below`);`

- Requires: `is_move_constructible<T>::value` is `true`.
- Effect: Move-constructs an `optional`.
- Postconditions: If `rhs` is initialized, `*this` is initialized and its value is move constructed from `rhs`; else `*this` is uninitialized.
- Throws: Whatever `T::T( T&& )` throws.
- Remarks: The expression inside `noexcept` is equivalent to `is_nothrow_move_constructible<T>::value`.
- Notes: If `rhs` is initialized, `T::T( T && )` is called.
- Exception Safety: Exceptions can only be thrown during `T::T( T&& );` in that case, `rhs` remains initialized and the value of `*rhs` is determined by exception safety of `T::T(T&&)`.
- Example:

      optional<std::unique_ptr<T>> uninit ;
      assert (!uninit);

      optional<std::unique_ptr<T>> uinit2 ( std::move(uninit) ) ;
      assert ( uninit2 == uninit );

      optional<std::unique_ptr<T>> init( std::uniqye_ptr<T>(new T(2)) );
      assert ( **init == T(2) ) ;

      optional<std::unique_ptr<T>> init2 ( std::move(init) ) ;
      assert ( init );
      assert ( *init == nullptr );
      assert ( init2 );
      assert ( **init2 == T(2) ) ;

> `optional<T&>::optional( optional && rhs );`

- Effect: Move-Constructs an `optional`.
- Postconditions: If `rhs` is initialized, `*this` is initialized and its value is another reference to the same object referenced by `*rhs`; else `*this` is uninitialized.
- Throws: Nothing.
- Notes: If `rhs` is initialized, both `*this` and `*rhs` will refer to the same object (they alias).
- Example:

      optional<std::unique_ptr<T>&> uninit ;
      assert (!uninit);

      optional<std::unique_ptr<T>&> uinit2 ( std::move(uninit) ) ;
      assert ( uninit2 == uninit );

      std::unique_ptr<T> v(new T(2)) ;
      optional<std::unique_ptr<T>&> init(v);
      assert ( *init == v ) ;

      optional<std::unique_ptr<T>&> init2 ( std::move(init) ) ;
      assert ( *init2 == v ) ;

      *v = 3 ;

      assert ( **init  == 3 ) ;
      assert ( **init2 == 3 ) ;

> `template<U> explicit optional<T` (not a ref)`>::optional( optional<U> const& rhs );`

- Effect: Copy-Constructs an `optional`.
- Postconditions: If `rhs` is initialized, `*this` is initialized and its value is a copy of the value of rhs converted to type `T`; else `*this` is uninitialized.
- Throws: Whatever `T::T( U const& )` throws.
- Notes: `T::T( U const& )` is called if `rhs` is initialized, which requires a valid conversion from `U` to `T`.
- Exception Safety: Exceptions can only be thrown during `T::T( U const& );` in that case, this constructor has no effect.
- Example:

      optional<double> x(123.4);
      assert ( *x == 123.4 ) ;

      optional<int> y(x) ;
      assert( *y == 123 ) ;

> `template<U> explicit optional<T` (not a ref)`>::optional( optional<U>&& rhs );`

- Effect: Move-constructs an `optional`.
- Postconditions: If `rhs` is initialized, `*this` is initialized and its value is move-constructed from `*rhs`; else `*this` is uninitialized.
- Throws: Whatever `T::T( U&& )` throws.
- Notes: `T::T( U&& )` is called if `rhs` is initialized, which requires a valid conversion from `U` to `T`.
- Exception Safety: Exceptions can only be thrown during `T::T( U&& );` in that case, `rhs` remains initialized and the value of `*rhs` is determined by exception safety guarantee of `T::T( U&& )`.
- Example:

      optional<double> x(123.4);
      assert ( *x == 123.4 ) ;

      optional<int> y(std::move(x)) ;
      assert( *y == 123 ) ;

> `template<InPlaceFactory> explicit optional<T` (not a ref)`>::optional( InPlaceFactory const& f );`

> `template<TypedInPlaceFactory> explicit optional<T` (not a ref)`>::optional( TypedInPlaceFactory const& f );`

- Effect: Constructs an `optional` with a value of `T` obtained from the factory.
- Postconditions: `*this` is initialized and its value is directly given from the factory `f` (i.e., the value is not copied).
- Throws: Whatever the `T` constructor called by the factory throws.
- Notes: See In-Place Factories
- Exception Safety: Exceptions can only be thrown during the call to the `T` constructor used by the factory; in that case, this constructor has no effect.
- Example:

      class C { C ( char, double, std::string ) ; } ;

      C v('A',123.4,"hello");

      optional<C> x( in_place   ('A', 123.4, "hello") ); // InPlaceFactory used
      optional<C> y( in_place<C>('A', 123.4, "hello") ); // TypedInPlaceFactory used

      assert ( *x == v ) ;
      assert ( *y == v ) ;

> `optional& optional<T>::operator= ( none_t ) noexcept;`

- Effect: If `*this` is initialized destroys its contained value.
- Postconditions: `*this` is uninitialized.

> `optional& optional<T` (not a ref)`>::operator= ( T const& rhs ) ;`

- Effect: Assigns the value `rhs` to an `optional`.
- Postconditions: `*this` is initialized and its value is a copy of `rhs`.
- Throws: Whatever `T::operator=( T const& )` or `T::T(T const&)` throws.
- Notes: If `*this` was initialized, `T`'s assignment operator is used, otherwise, its copy-constructor is used.
- Exception Safety: In the event of an exception, the initialization state of `*this` is unchanged and its value unspecified as far as `optional` is concerned (it is up to `T`'s `operator=()`). If `*this` is initially uninitialized and `T`'s copy constructor fails, `*this` is left properly uninitialized.
- Example:

      T x;
      optional<T> def ;
      optional<T> opt(x) ;

      T y;
      def = y ;
      assert ( *def == y ) ;
      opt = y ;
      assert ( *opt == y ) ;

> `optional<T&>& optional<T&>::operator= ( T& rhs ) ;`

- Effect: (Re)binds the wrapped reference.
- Postconditions: `*this` is initialized and it references the same object referenced by `rhs`.
- Notes: If `*this` was initialized, it is rebound to the new object. See here for details on this behavior.
- Example:

      int a = 1 ;
      int b = 2 ;
      T& ra = a ;
      T& rb = b ;
      optional<int&> def ;
      optional<int&> opt(ra) ;

      def = rb ; // binds 'def' to 'b' through 'rb'
      assert ( *def == b ) ;
      *def = a ; // changes the value of 'b' to a copy of the value of 'a'
      assert ( b == a ) ;
      int c = 3;
      int& rc = c ;
      opt = rc ; // REBINDS to 'c' through 'rc'
      c = 4 ;
      assert ( *opt == 4 ) ;

> `optional& optional<T` (not a ref)`>::operator= ( T&& rhs ) ;`

- Effect: Moves the value `rhs` to an `optional`.
- Postconditions: `*this` is initialized and its value is moved from `rhs`.
- Throws: Whatever `T::operator=( T&& )` or `T::T(T &&)` throws.
- Notes: If `*this` was initialized, `T`'s move-assignment operator is used, otherwise, its move-constructor is used.
- Exception Safety: In the event of an exception, the initialization state of `*this` is unchanged and its value unspecified as far as `optional` is concerned (it is up to `T`'s `operator=()`). If `*this` is initially uninitialized and `T`'s move constructor fails, `*this` is left properly uninitialized.
- Example:

      T x;
      optional<T> def ;
      optional<T> opt(x) ;

      T y1, y2, yR;
      def = std::move(y1) ;
      assert ( *def == yR ) ;
      opt = std::move(y2) ;
      assert ( *opt == yR ) ;

> `optional<T&>& optional<T&>::operator= ( T&& rhs ) = delete;`

- Notes: This assignment operator is deleted.

> `optional& optional<T` (not a ref)`>::operator= ( optional const& rhs ) ;`

- Requires: `T` is `CopyConstructible` and `CopyAssignable`.

- Effects:

  | `*this` contains a value | `*this` does not contain a value
  --- | --- | ---
  `rhs` contains a value | assigns `*rhs` to the contained value | initializes the contained value as if direct-initializing an object of type `T` with `*rhs`
  `rhs` does not contain a value | destroys the contained value by calling `val->T::~T()` | no effect

- Returns: `*this`;
- Postconditions: `bool(rhs) == bool(*this)`.
- Exception Safety: If any exception is thrown, the initialization state of `*this` and `rhs` remains unchanged. If an exception is thrown during the call to `T`'s copy constructor, no effect. If an exception is thrown during the call to `T`'s copy assignment, the state of its contained value is as defined by the exception safety guarantee of `T`'s copy assignment.
- Example:

      T v;
      optional<T> opt(v);
      optional<T> def ;

      opt = def ;
      assert ( !def ) ;
      // previous value (copy of 'v') destroyed from within 'opt'.

> `optional<T&> & optional<T&>::operator= ( optional<T&> const& rhs ) ;`

- Effect: (Re)binds thee wrapped reference.
- Postconditions: If `*rhs` is initialized, `*this` is initialized and it references the same object referenced by `*rhs`; otherwise, `*this` is uninitialized (and references no object).
- Notes: If `*this` was initialized and so is `*rhs`, `*this` is rebound to the new object. See here for details on this behavior.
- Example:

      int a = 1 ;
      int b = 2 ;
      T& ra = a ;
      T& rb = b ;
      optional<int&> def ;
      optional<int&> ora(ra) ;
      optional<int&> orb(rb) ;

      def = orb ; // binds 'def' to 'b' through 'rb' wrapped within 'orb'
      assert ( *def == b ) ;
      *def = ora ; // changes the value of 'b' to a copy of the value of 'a'
      assert ( b == a ) ;
      int c = 3;
      int& rc = c ;
      optional<int&> orc(rc) ;
      ora = orc ; // REBINDS ora to 'c' through 'rc'
      c = 4 ;
      assert ( *ora == 4 ) ;

> `optional& optional<T` (not a ref)`>::operator= ( optional&& rhs ) noexcept(`see below`);`

- Requires: `T` is `MoveConstructible` and `MoveAssignable`.

- Effects:

  | `*this` contains a value | `*this` does not contain a value
  --- | --- | ---
  `rhs` contains a value | assigns `std::move(*rhs)` to the contained value | initializes the contained value as if direct-initializing an object of type `T` with `std::move(*rhs)`
  `rhs` does not contain a value | destroys the contained value by calling `val->T::~T()` | no effect

- Returns: `*this`;
- Postconditions: `bool(rhs) == bool(*this)`.
- Remarks: The expression inside `noexcept` is equivalent to `is_nothrow_move_constructible<T>::value && is_nothrow_move_assignable<T>::value`.
- Exception Safety: If any exception is thrown, the initialization state of `*this` and `rhs` remains unchanged. If an exception is thrown during the call to `T`'s move constructor, the state of `*rhs` is determined by the exception safety guarantee of `T`'s move constructor. If an exception is thrown during the call to T's move-assignment, the state of `**this` and `*rhs` is determined by the exception safety guarantee of T's move assignment.
- Example:

      optional<T> opt(T(2)) ;
      optional<T> def ;

      opt = def ;
      assert ( def ) ;
      assert ( opt ) ;
      assert ( *opt == T(2) ) ;

> `optional<T&> & optional<T&>::operator= ( optional<T&>&& rhs ) ;`

- Effect: Same as `optional<T&>::operator= ( optional<T&> const& rhs )`.

> `template<U> optional& optional<T` (not a ref)`>::operator= ( optional<U> const& rhs ) ;`

- Effect:

  | `*this` contains a value | `*this` does not contain a value
  --- | --- | ---
  `rhs` contains a value | assigns `*rhs` to the contained value | initializes the contained value as if direct-initializing an object of type `T` with `*rhs`
  `rhs` does not contain a value | destroys the contained value by calling `val->T::~T()` | no effect

- Returns: `*this`.
- Postconditions: `bool(rhs) == bool(*this)`.
- Exception Safety: If any exception is thrown, the result of the expression `bool(*this)` remains unchanged. If an exception is thrown during the call to `T`'s constructor, no effect. If an exception is thrown during the call to `T`'s assignment, the state of its contained value is as defined by the exception safety guarantee of `T`'s copy assignment.
- Example:

      T v;
      optional<T> opt0(v);
      optional<U> opt1;

      opt1 = opt0 ;
      assert ( *opt1 == static_cast<U>(v) ) ;

> `template<U> optional& optional<T` (not a ref)`>::operator= ( optional<U>&& rhs ) ;`

- Effect:

  | `*this` contains a value | `*this` does not contain a value
  --- | --- | ---
  `rhs` contains a value | assigns `std::move(*rhs)` to the contained value | initializes the contained value as if direct-initializing an object of type `T` with `std::move(*rhs)`
  `rhs` does not contain a value | destroys the contained value by calling `val->T::~T()` | no effect

- Returns: `*this`.
- Postconditions: `bool(rhs) == bool(*this)`.
- Exception Safety: If any exception is thrown, the result of the expression `bool(*this)` remains unchanged. If an exception is thrown during the call to `T`'s constructor, no effect. If an exception is thrown during the call to `T`'s assignment, the state of its contained value is as defined by the exception safety guarantee of `T`'s copy assignment.
- Example:

      T v;
      optional<T> opt0(v);
      optional<U> opt1;

      opt1 = std::move(opt0) ;
      assert ( opt0 );
      assert ( opt1 )
      assert ( *opt1 == static_cast<U>(v) ) ;

> `template<class... Args> void optional<T` (not a ref)`>::emplace( Args...&& args );`

- Requires: The compiler supports rvalue references and variadic templates.
- Effect: If `*this` is initialized calls `*this = none`. Then initializes in-place the contained value as if direct-initializing an object of type `T` with `std::forward<Args>(args)...`.
- Postconditions: `*this` is initialized.
- Throws: Whatever the selected `T`'s constructor throws.
- Notes: `T` need not be `MoveConstructible` or `MoveAssignable`. On compilers that do not support variadic templates, the signature falls back to single-argument: `template<class Arg> void emplace(Arg&& arg)`. On compilers that do not support rvalue references, the signature falls back to two overloads: taking `const` and non-`const` lvalue reference.
- Exception Safety: If an exception is thrown during the initialization of `T`, `*this` is uninitialized.
- Example:

      T v;
      optional<const T> opt;
      opt.emplace(0);  // create in-place using ctor T(int)
      opt.emplace();   // destroy previous and default-construct another T
      opt.emplace(v);  // destroy and copy-construct in-place (no assignment called)

> `template<InPlaceFactory> optional<T>& optional<T` (not a ref)`>::operator=( InPlaceFactory const& f );`

> `template<TypedInPlaceFactory> optional<T>& optional<T` (not a ref)`>::operator=( TypedInPlaceFactory const& f );`

- Effect: Assigns an `optional` with a value of `T` obtained from the factory.
- Postconditions: `*this` is initialized and its value is directly given from the factory `f` (i.e., the value is not copied).
- Throws: Whatever the `T` constructor called by the factory throws.
- Notes: See In-Place Factories
- Exception Safety: Exceptions can only be thrown during the call to the `T` constructor used by the factory; in that case, the `optional` object will be reset to be uninitialized.

> `void optional<T` (not a ref)`>::reset( T const& v ) ;`

- Deprecated: same as `operator= ( T const& v) ;`

> `void optional<T>::reset() noexcept ;`

- Deprecated: Same as `operator=( none_t );`

> `T const& optional<T` (not a ref)`>::get() const ;`

> `T& optional<T` (not a ref)`>::get() ;`

> `inline T const& get ( optional<T` (not a ref)`> const& ) ;`

> `inline T& get ( optional<T` (not a ref)`> &) ;`

- Requires: `*this` is initialized
- Returns: A reference to the contained value
- Throws: Nothing.
- Notes: The requirement is asserted via `BOOST_ASSERT()`.

> `T const& optional<T&>::get() const ;`

> `T& optional<T&>::get() ;`

> `inline T const& get ( optional<T&> const& ) ;`

> `inline T& get ( optional<T&> &) ;`

- Requires: `*this` is initialized
- Returns: The reference contained.
- Throws: Nothing.
- Notes: The requirement is asserted via `BOOST_ASSERT()`.

> `T const& optional<T` (not a ref)`>::operator*() const& ;`

> `T& optional<T` (not a ref)`>::operator*() &;`

- Requires: `*this` is initialized
- Returns: A reference to the contained value
- Throws: Nothing.
- Notes: The requirement is asserted via `BOOST_ASSERT()`. On compilers that do not support ref-qualifiers on member functions these two overloads are replaced with the classical two: a `const` and non-`const` member functions.
- Example:

      T v ;
      optional<T> opt ( v );
      T const& u = *opt;
      assert ( u == v ) ;
      T w ;
      *opt = w ;
      assert ( *opt == w ) ;

> `T&& optional<T` (not a ref)`>::operator*() &&;`

- Requires: `*this` contains a value.
- Effects: Equivalent to `return std::move(*val);`.
- Notes: The requirement is asserted via `BOOST_ASSERT()`. On compilers that do not support ref-qualifiers on member functions this overload is not present.

> `T & optional<T&>::operator*() const& ;`

> `T & optional<T&>::operator*() & ;`

> `T & optional<T&>::operator*() && ;`

- Requires: `*this` is initialized
- Returns: The reference contained.
- Throws: Nothing.
- Notes: The requirement is asserted via `BOOST_ASSERT()`. On compilers that do not support ref-qualifiers on member functions these three overloads are replaced with the classical two: a `const` and non-`const` member functions.
- Example:

      T v ;
      T& vref = v ;
      optional<T&> opt ( vref );
      T const& vref2 = *opt;
      assert ( vref2 == v ) ;
      ++ v ;
      assert ( *opt == v ) ;

> `T const& optional<T>::value() const& ;`

> `T& optional<T>::value() & ;`

- Effects: Equivalent to `return bool(*this) ? *val : throw bad_optional_access();`.
- Notes: On compilers that do not support ref-qualifiers on member functions these two overloads are replaced with the classical two: a `const` and non-`const` member functions.
- Example:

      T v ;
      optional<T> o0, o1 ( v );
      assert ( o1.value() == v );

      try {
        o0.value(); // throws
        assert ( false );
      }
      catch(bad_optional_access&) {
        assert ( true );
      }

> `T&& optional<T>::value() && ;`

- Effects: Equivalent to `return bool(*this) ? std::move(*val) : throw bad_optional_access();`.
- Notes: On compilers that do not support ref-qualifiers on member functions this overload is not present.

> `template<class U> T optional<T>::value_or(U && v) const& ;`

- Effects: Equivalent to `if (*this) return **this; else return std::forward<U>(v);`.
- Remarks: If `T` is not `CopyConstructible` or `U &&` is not convertible to `T`, the program is ill-formed.
- Notes: On compilers that do not support ref-qualifiers on member functions this overload is replaced with the `const`-qualified member function. On compilers without rvalue reference support the type of `v` becomes `U const&`.

> `template<class U> T optional<T>::value_or(U && v) && ;`

- Effects: Equivalent to `if (*this) return std::move(**this); else return std::forward<U>(v);`.
- Remarks: If `T` is not `MoveConstructible` or `U &&` is not convertible to `T`, the program is ill-formed.
- Notes: On compilers that do not support ref-qualifiers on member functions this overload is not present.

> `template<class F> T optional<T>::value_or_eval(F f) const& ;`

- Requires: `T` is `CopyConstructible` and `F` models a `Generator` whose result type is convertible to `T`.
- Effects: `if (*this) return **this; else return f();`.
- Notes: On compilers that do not support ref-qualifiers on member functions this overload is replaced with the `const`-qualified member function.
- Example:

      int complain_and_0()
      {
        clog << "no value returned, using default" << endl;
        return 0;
      }

      optional<int> o1 = 1;
      optional<int> oN = none;

      int i = o1.value_or_eval(complain_and_0); // fun not called
      assert (i == 1);

      int j = oN.value_or_eval(complain_and_0); // fun called
      assert (i == 0);

> `template<class F> T optional<T>::value_or_eval(F f) && ;`

- Requires: `T` is `MoveConstructible` and `F` models a `Generator` whose result type is convertible to `T`.
- Effects: `if (*this) return std::move(**this); else return f();`.
- Notes: On compilers that do not support ref-qualifiers on member functions this overload is not present.

> `T const& optional<T` (not a ref)`>::get_value_or( T const& default) const ;`

> `T& optional<T` (not a ref)`>::get_value_or( T& default ) ;`

> `inline T const& get_optional_value_or ( optional<T` (not a ref)`> const& o, T const& default ) ;`

> `inline T& get_optional_value_or ( optional<T` (not a ref)`>& o, T& default ) ;`

- Deprecated: Use `value_or()` instead.
- Returns: A reference to the contained value, if any, or `default`.
- Throws: Nothing.
- Example:

      T v, z ;
      optional<T> def;
      T const& y = def.get_value_or(z);
      assert ( y == z ) ;

      optional<T> opt ( v );
      T const& u = get_optional_value_or(opt,z);
      assert ( u == v ) ;
      assert ( u != z ) ;

> `T const* optional<T` (not a ref)`>::get_ptr() const ;`

> `T* optional<T` (not a ref)`>::get_ptr() ;`

> `inline T const* get_pointer ( optional<T` (not a ref)`> const& ) ;`

> `inline T* get_pointer ( optional<T` (not a ref)`> &) ;`

- Returns: If `*this` is initialized, a pointer to the contained value; else `0` (null).
- Throws: Nothing.
- Notes: The contained value is permanently stored within `*this`, so you should not hold nor delete this pointer
- Example:

      T v;
      optional<T> opt(v);
      optional<T> const copt(v);
      T* p = opt.get_ptr() ;
      T const* cp = copt.get_ptr();
      assert ( p == get_pointer(opt) );
      assert ( cp == get_pointer(copt) ) ;

> `T const* optional<T` (not a ref)`>::operator ->() const ;`

> `T* optional<T` (not a ref)`>::operator ->() ;`

- Requires: `*this` is initialized.
- Returns: A pointer to the contained value.
- Throws: Nothing.
- Notes: The requirement is asserted via `BOOST_ASSERT()`.
- Example:

      struct X { int mdata ; } ;
      X x ;
      optional<X> opt (x);
      opt->mdata = 2 ;

> `explicit optional<T>::operator bool() const noexcept ;`

- Returns: `get_ptr() != 0`.
- Notes: On compilers that do not support explicit conversion operators this falls back to safe-bool idiom.
- Example:

      optional<T> def ;
      assert ( def == 0 );
      optional<T> opt ( v ) ;
      assert ( opt );
      assert ( opt != 0 );

> `bool optional<T>::operator!() noexcept ;`

- Returns: If `*this` is uninitialized, `true`; else `false`.
- Notes: This operator is provided for those compilers which can't use the unspecified-bool-type operator in certain boolean contexts.
- Example:

      optional<T> opt ;
      assert ( !opt );
      *opt = some_T ;

      // Notice the "double-bang" idiom here.
      assert ( !!opt ) ;

> `bool optional<T>::is_initialized() const ;`

- Deprecated: Same as `explicit operator bool () ;`

###### Free functions

> `optional<T` (not a ref)`> make_optional( T const& v )`

- Returns: `optional<T>(v)` for the deduced type `T` of `v`.
- Example:

      template<class T> void foo ( optional<T> const& opt ) ;

      foo ( make_optional(1+1) ) ; // Creates an optional<int>

> `optional<T` (not a ref)`> make_optional( bool condition, T const& v )`

- Returns: `optional<T>(condition,v)` for the deduced type `T` of `v`.
- Example:

      optional<double> calculate_foo()
      {
        double val = compute_foo();
        return make_optional(is_not_nan_and_finite(val),val);
      }

      optional<double> v = calculate_foo();
      if ( !v )
        error("foo wasn't computed");

> `bool operator == ( optional<T> const& x, optional<T> const& y );`

- Requires: `T` shall meet requirements of `EqualityComparable`.
- Returns: If both `x` and `y` are initialized, `(*x == *y)`. If only `x` or `y` is initialized, `false`. If both are uninitialized, `true`.
- Notes: This definition guarantees that `optional<T>` not containing a value is compared unequal to any `optional<T>` containing any value, and equal to any other `optional<T>` not containing a value. Pointers have shallow relational operators while `optional` has deep relational operators. Do not use `operator==` directly in generic code which expect to be given either an `optional<T>` or a pointer; use `equal_pointees()` instead
- Example:

      optional<T> oN, oN_;
      optional<T> o1(T(1)), o1_(T(1));
      optional<T> o2(T(2));

      assert ( oN == oN );  // Identity implies equality
      assert ( o1 == o1 );  //

      assert ( oN == oN_ ); // Both uninitialized compare equal

      assert ( oN != o1 );  // Initialized unequal to initialized.

      assert ( o1 == o1_ ); // Both initialized compare as (*lhs == *rhs)
      assert ( o1 != o2 );  //

> `bool operator < ( optional<T> const& x, optional<T> const& y );`

- Requires: Expression `*x < *y` shall be well-formed and its result shall be convertible to `bool`.
- Returns: `(!y) ? false : (!x) ? true : *x < *y`.
- Notes: This definition guarantees that `optional<T>` not containing a value is ordered as less than any `optional<T>` containing any value, and equivalent to any other `optional<T>` not containing a value. Pointers have shallow relational operators while `optional` has deep relational operators. Do not use `operator<` directly in generic code which expect to be given either an `optional<T>` or a pointer; use `less_pointees()` instead. `T` need not be `LessThanComparable`. Only single `operator<` is required. Other relational operations are defined in terms of this one. If `T`'s `operator<` satisfies the axioms of `LessThanComparable` (transitivity, antisymmetry and irreflexivity), `optinal<T>` is `LessThanComparable`.
- Example:

      optional<T> oN, oN_;
      optional<T> o0(T(0));
      optional<T> o1(T(1));

      assert ( !(oN < oN) );  // Identity implies equivalence
      assert ( !(o1 < o1) );

      assert ( !(oN < oN_) ); // Two uninitialized are equivalent
      assert ( !(oN_ < oN) );

      assert ( oN < o0 );     // Uninitialized is less than initialized
      assert ( !(o0 < oN) );

      assert ( o1 < o2 ) ;    // Two initialized compare as (*lhs < *rhs)
      assert ( !(o2 < o1) ) ;
      assert ( !(o2 < o2) ) ;

> `bool operator != ( optional<T> const& x, optional<T> const& y );`

- Returns: `!( x == y );`

> `bool operator > ( optional<T> const& x, optional<T> const& y );`

- Returns: `( y < x );`

> `bool operator <= ( optional<T> const& x, optional<T> const& y );`

- Returns: `!( y < x );`

> `bool operator >= ( optional<T> const& x, optional<T> const& y );`

- Returns: `!( x < y );`

> `bool operator == ( optional<T> const& x, none_t ) noexcept;`

> `bool operator == ( none_t, optional<T> const& x ) noexcept;`

- Returns: `!x`.
- Notes: `T` need not meet requirements of `EqualityComparable`.

> `bool operator != ( optional<T> const& x, none_t ) noexcept;`

> `bool operator != ( none_t, optional<T> const& x ) noexcept;`

- Returns: `!( x == y );`

> `void swap ( optional<T>& x, optional<T>& y ) ;`

- Requires: Lvalues of type `T` shall be swappable and `T` shall be `MoveConstructible`.

- Effects:

  | `*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-initializing an object of type `T` with the expression `std::move(*rhs)`, followed by `rhs.val->T::~T()`, `*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-initializing an object of type `T` with the expression `std::move(*(*this))`, followed by `val->T::~T()`, `*this` does not contain a value and `rhs` contains a value | no effect

- Postconditions: The states of `x` and `y` interchanged.
- Throws: If both are initialized, whatever `swap(T&,T&)` throws. If only one is initialized, whatever `T::T ( T&& )` throws.
- Example:

      T x(12);
      T y(21);
      optional<T> def0 ;
      optional<T> def1 ;
      optional<T> optX(x);
      optional<T> optY(y);

      boost::swap(def0,def1); // no-op

      boost::swap(def0,optX);
      assert ( *def0 == x );
      assert ( !optX );

      boost::swap(def0,optX); // Get back to original values

      boost::swap(optX,optY);
      assert ( *optX == y );
      assert ( *optY == x );