| Home | Libraries | People | FAQ | More

#### Detailed Semantics - Free Functions

> `optional<T> 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<std::decay_t<T>> make_optional( T && v )`

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

> `optional<T> 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");

> `optional<std::decay_t<T>> make_optional( bool condition, T && v )`

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

> `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), `optional<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: `bool(x);`

> `auto get_pointer ( optional<T>& o ) -> typename optional<T>::pointer_type ;`

> `auto get_pointer ( optional<T> const& o ) -> typename optional<T>::pointer_const_type ;`

- Returns: `o.get_ptr()`.
- Throws: Nothing.

> `auto get_optional_value_or ( optional<T>& o, typename optional<T>::reference_type def ) -> typename optional<T>::reference_type ;`

> `auto get_optional_value_or ( optional<T> const& o, typename optional<T>::reference_const_type def ) -> typename optional<T>::reference_const_type ;`

- Returns: `o.get_value_or(def)`.
- Throws: Nothing.
- Remarks: This function is deprecated.

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

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

- Postconditions: `x` refers to what `y` referred to before the swap (if anything). `y` refers to whatever `x` referred to before the swap.
- Example:

      T x(12);
      T y(21);

      optional<T&> opt0;
      optional<T&> optX (x);
      optional<T&> optY (y);

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

      boost::swap(opt0, optX);
      assert ( opt0 );
      assert ( !optX );
      assert (addressof(*opt0) == addressof(y));