| 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 reefer 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.
- Notes: If `rhs` is initialized, `T::T( T && )` is called. The expression inside `noexcept` is equivalent to `is_nothrow_move_constructible<T>::value`.
- 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::unique_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 reefer 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 ) ;`

- Effect: Assigns another `optional` to 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::operator( T const&)` or `T::T( T const& )` throws.
- Notes: If both `*this` and `rhs` are initially initialized, `T`'s assignment operator is used. If `*this` is initially initialized but `rhs` is uninitialized, `T`'s [destructor] is called. If `*this` is initially uninitialized but `rhs` is initialized, `T`'s copy constructor is called.
- 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 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`);`

- Effect: Move-assigns another `optional` to an `optional`.
- Postconditions: If `rhs` is initialized, `*this` is initialized and its value is moved from `*rhs`, `rhs` remains initialized; else `*this` is uninitialized.
- Throws: Whatever `T::operator( T&& )` or `T::T( T && )` throws.
- Notes: If both `*this` and `rhs` are initially initialized, `T`'s move assignment operator is used. If `*this` is initially initialized but `rhs` is uninitialized, `T`'s [destructor] is called. If `*this` is initially uninitialized but `rhs` is initialized, `T`'s move constructor is called. The expression inside `noexcept` is equivalent to `is_nothrow_move_constructible<T>::value && is_nothrow_move_assignable<T>::value`.
- 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:

      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: Assigns another convertible optional to 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::operator=( U const& )` or `T::T( U const& )` throws.
- Notes: If both `*this` and rhs are initially initialized, `T`'s assignment operator (from `U`) is used. If `*this` is initially initialized but `rhs` is uninitialized, `T`'s destructor is called. If `*this` is initially uninitialized but rhs is initialized, `T`'s converting constructor (from `U`) is called.
- 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 converting constructor fails, `*this` is left properly uninitialized.
- 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: Move-assigns another convertible optional to an optional.
- Postconditions: If `rhs` is initialized, `*this` is initialized and its value is moved from the value of `rhs`; else `*this` is uninitialized.
- Throws: Whatever `T::operator=( U&& )` or `T::T( U&& )` throws.
- Notes: If both `*this` and `rhs` are initially initialized, `T`'s assignment operator (from `U&&`) is used. If `*this` is initially initialized but `rhs` is uninitialized, `T`'s destructor is called. If `*this` is initially uninitialized but `rhs` is initialized, `T`'s converting constructor (from `U&&`) is called.
- 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 converting constructor fails, `*this` is left properly uninitialized.
- Example:

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

      opt1 = std::move(opt0) ;
      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`.
- Exception Safety: If an exception is thrown during the initialization of `T`, `*this` is uninitialized.

> `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*() &;`

> `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 three 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 const& 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() & ;`

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

- Returns: A reference to the contained value, if `*this` is initialized.
- Throws: An instance of `bad_optional_access`, if `*this` is not initialized.
- Notes: 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 ;
      optional<T> o0, o1 ( v );
      assert ( o1.value() == v );

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

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

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

- Requires: `T` is CopyConstructible.
- Returns: First overload: `bool(*this) ? **this : static_cast<T>(forward<U>(v))`. second overload: `bool(*this) ? std::move(**this) : static_cast<T>(forward<U>(v))`.
- Throws: Any exception thrown by the selected constructor of `T`.
- Notes: 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. On compilers without rvalue reference support the type of `v` becomes `U const&`.

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

- Returns: `get_ptr() != 0`.
- Throws: Nothing.
- 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`.
- Throws: Nothing.
- Notes: 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:

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

      // Identity always hold
      assert ( def0 == def0 );
      assert ( optX == optX );

      // Both uninitialized compare equal
      assert ( def0 == def1 );

      // Only one initialized compare unequal.
      assert ( def0 != optX );

      // Both initialized compare as (*lhs == *rhs)
      assert ( optX == optY ) ;
      assert ( optX != optZ ) ;

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

- Requires: `T` shall meet requirements of `LessThanComparable`.
- Returns: If `y` is not initialized, `false`. If `y` is initialized and `x` is not initialized, `true`. If both `x` and `y` are initialized, `(*x < *y)`.
- Throws: Nothing.
- Notes: 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.
- Example:

      T x(12);
      T y(34);
      optional<T> def ;
      optional<T> optX(x);
      optional<T> optY(y);

      // Identity always hold
      assert ( !(def < def) );
      assert ( optX == optX );

      // Both uninitialized compare equal
      assert ( def0 == def1 );

      // Only one initialized compare unequal.
      assert ( def0 != optX );

      // Both initialized compare as (*lhs == *rhs)
      assert ( optX == optY ) ;
      assert ( optX != optZ ) ;

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

- Returns: `!( x == y );`
- Throws: Nothing.

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

- Returns: `( y < x );`
- Throws: Nothing.

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

- Returns: `!( y < x );`
- Throws: Nothing.

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

- Returns: `!( x<y );`
- Throws: Nothing.

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

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

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

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

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

- Effect: If both `x` and `y` are initialized, calls `swap(*x,*y)` using `std::swap`. If only one is initialized, say `x`, calls: `y.reset(*x); x.reset();` If none is initialized, does nothing.
- 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.
- Notes: If both are initialized, `swap(T&,T&)` is used unqualified but with `std::swap` introduced in scope. If only one is initialized, `T::~T()` and `T::T( T&& )` is called.
- Exception Safety: If both are initialized, this operation has the exception safety guarantees of `swap(T&,T&)`. If only one is initialized, it has the same basic guarantee as `optional<T>::operator= ( T&& )`.
- 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 );