[expected.void.monadic]

# 22 General utilities library [[utilities]](./#utilities)

## 22.8 Expected objects [[expected]](expected#void.monadic)

### 22.8.7 Partial specialization of expected for void types [[expected.void]](expected.void#monadic)

#### 22.8.7.7 Monadic operations [expected.void.monadic]

[ð](#lib:and_then,expected%3cvoid%3e)

`template<class F> constexpr auto and_then(F&& f) &;
template<class F> constexpr auto and_then(F&& f) const &;
`

[1](#1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L10077)

Let U be remove_cvref_t<invoke_result_t<F>>[.](#1.sentence-1)

[2](#2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L10080)

*Constraints*: is_constructible_v<E, decltype(error())>> is true[.](#2.sentence-1)

[3](#3)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L10084)

*Mandates*: U is a specialization of expected andis_same_v<U​::​error_type, E> is true[.](#3.sentence-1)

[4](#4)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L10089)

*Effects*: Equivalent to:if (has_value())return invoke(std::forward<F>(f));elsereturn U(unexpect, error());

[ð](#lib:and_then,expected%3cvoid%3e_)

`template<class F> constexpr auto and_then(F&& f) &&;
template<class F> constexpr auto and_then(F&& f) const &&;
`

[5](#5)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L10107)

Let U be remove_cvref_t<invoke_result_t<F>>[.](#5.sentence-1)

[6](#6)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L10110)

*Constraints*: is_constructible_v<E, decltype(std​::​move(error()))> is true[.](#6.sentence-1)

[7](#7)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L10114)

*Mandates*: U is a specialization of expected andis_same_v<U​::​error_type, E> is true[.](#7.sentence-1)

[8](#8)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L10119)

*Effects*: Equivalent to:if (has_value())return invoke(std::forward<F>(f));elsereturn U(unexpect, std::move(error()));

[ð](#lib:or_else,expected%3cvoid%3e)

`template<class F> constexpr auto or_else(F&& f) &;
template<class F> constexpr auto or_else(F&& f) const &;
`

[9](#9)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L10137)

Let G be remove_cvref_t<invoke_result_t<F, decltype(error())>>[.](#9.sentence-1)

[10](#10)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L10140)

*Mandates*: G is a specialization of expected andis_same_v<G​::​value_type, T> is true[.](#10.sentence-1)

[11](#11)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L10145)

*Effects*: Equivalent to:if (has_value())return G();elsereturn invoke(std::forward<F>(f), error());

[ð](#lib:or_else,expected%3cvoid%3e_)

`template<class F> constexpr auto or_else(F&& f) &&;
template<class F> constexpr auto or_else(F&& f) const &&;
`

[12](#12)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L10163)

Let G beremove_cvref_t<invoke_result_t<F, decltype(std​::​move(error()))>>[.](#12.sentence-1)

[13](#13)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L10167)

*Mandates*: G is a specialization of expected andis_same_v<G​::​value_type, T> is true[.](#13.sentence-1)

[14](#14)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L10172)

*Effects*: Equivalent to:if (has_value())return G();elsereturn invoke(std::forward<F>(f), std::move(error()));

[ð](#lib:transform,expected%3cvoid%3e)

`template<class F> constexpr auto transform(F&& f) &;
template<class F> constexpr auto transform(F&& f) const &;
`

[15](#15)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L10190)

Let U be remove_cv_t<invoke_result_t<F>>[.](#15.sentence-1)

[16](#16)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L10193)

*Constraints*: is_constructible_v<E, decltype(error())> is true[.](#16.sentence-1)

[17](#17)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L10197)

*Mandates*: U is a valid value type for expected[.](#17.sentence-1)

If is_void_v<U> isfalse, the declarationU u(invoke(std::forward<F>(f))); is well-formed[.](#17.sentence-2)

[18](#18)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L10206)

*Effects*: 

- [(18.1)](#18.1)

  If has_value() is false, returnsexpected<U, E>(unexpect, error())[.](#18.1.sentence-1)

- [(18.2)](#18.2)

  Otherwise, if is_void_v<U> is false, returns anexpected<U, E> object whose *has_val* member is true and*val* member is direct-non-list-initialized withinvoke(std​::​forward<F>(f))[.](#18.2.sentence-1)

- [(18.3)](#18.3)

  Otherwise, evaluates invoke(std​::​forward<F>(f)) and then returnsexpected<U, E>()[.](#18.3.sentence-1)

[ð](#lib:transform,expected%3cvoid%3e_)

`template<class F> constexpr auto transform(F&& f) &&;
template<class F> constexpr auto transform(F&& f) const &&;
`

[19](#19)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L10230)

Let U be remove_cv_t<invoke_result_t<F>>[.](#19.sentence-1)

[20](#20)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L10233)

*Constraints*: is_constructible_v<E, decltype(std​::​move(error()))> is true[.](#20.sentence-1)

[21](#21)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L10237)

*Mandates*: U is a valid value type for expected[.](#21.sentence-1)

If is_void_v<U> isfalse, the declarationU u(invoke(std::forward<F>(f))); is well-formed[.](#21.sentence-2)

[22](#22)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L10246)

*Effects*: 

- [(22.1)](#22.1)

  If has_value() is false, returnsexpected<U, E>(unexpect, std​::​move(error()))[.](#22.1.sentence-1)

- [(22.2)](#22.2)

  Otherwise, if is_void_v<U> is false, returns anexpected<U, E> object whose *has_val* member is true and*val* member is direct-non-list-initialized withinvoke(std​::​forward<F>(f))[.](#22.2.sentence-1)

- [(22.3)](#22.3)

  Otherwise, evaluates invoke(std​::​forward<F>(f)) and then returnsexpected<U, E>()[.](#22.3.sentence-1)

[ð](#lib:transform_error,expected%3cvoid%3e)

`template<class F> constexpr auto transform_error(F&& f) &;
template<class F> constexpr auto transform_error(F&& f) const &;
`

[23](#23)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L10270)

Let G be remove_cv_t<invoke_result_t<F, decltype(error())>>[.](#23.sentence-1)

[24](#24)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L10273)

*Mandates*: G is a valid template argument
for unexpected ([[expected.un.general]](expected.un.general "22.8.3.1 General")) and the declarationG g(invoke(std::forward<F>(f), error())); is well-formed[.](#24.sentence-1)

[25](#25)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L10282)

*Returns*: If has_value() is true, expected<T, G>(); otherwise, anexpected<T, G> object whose *has_val* member is false and *unex* member is direct-non-list-initialized withinvoke(std​::​forward<F>(f), error())[.](#25.sentence-1)

[ð](#lib:transform_error,expected%3cvoid%3e_)

`template<class F> constexpr auto transform_error(F&& f) &&;
template<class F> constexpr auto transform_error(F&& f) const &&;
`

[26](#26)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L10297)

Let G beremove_cv_t<invoke_result_t<F, decltype(std​::​move(error()))>>[.](#26.sentence-1)

[27](#27)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L10301)

*Mandates*: G is a valid template argument
for unexpected ([[expected.un.general]](expected.un.general "22.8.3.1 General")) and the declarationG g(invoke(std::forward<F>(f), std::move(error()))); is well-formed[.](#27.sentence-1)

[28](#28)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L10310)

*Returns*: If has_value() is true, expected<T, G>(); otherwise, anexpected<T, G> object whose *has_val* member is false and *unex* member is direct-non-list-initialized withinvoke(std​::​forward<F>(f), std​::​move(error()))[.](#28.sentence-1)
