This commit is contained in:
Simon Brand
2017-10-21 19:41:18 +01:00
parent 8d1a8bc0ac
commit ed27d58e95
2 changed files with 226 additions and 43 deletions

View File

@@ -149,20 +149,58 @@ Represents an empty optional
class optional class optional
{ {
public: public:
template <class F> constexpr auto and_then(F &&f); template <class F>
template <class F> constexpr auto and_then(F &&f) const; constexpr auto and_then(F &&f) &;
template <class F>
constexpr auto and_then(F &&f) &&;
template <class F>
constexpr auto and_then(F &&f) const &;
template <class F>
constexpr auto and_then(F &&f) const &&;
template <class F> auto map(F &&f); template <class F> auto map(F &&f) &;
template <class F> auto map(F &&f) const; template <class F> auto map(F &&f) &&;
template <class F> auto map(F &&f) const &;
template <class F> auto map(F &&f) const &&;
template <class F> optional<T> or_else (F &&f); template <class F> optional<T> or_else (F &&f) &;
template <class F> optional<T> or_else (F &&f) const; template <class F> optional<T> or_else (F &&f) &&;
template <class F> optional<T> or_else (F &&f) const &;
template <class F, class U> U map_or(F &&f, U &&u); template <class F, class U>
template &lt;class F, class U&gt; U map_or(F &amp;&amp;f, U &amp;&amp;u) const; U <a href='doc_optional.md#tl::optional-T-::map_or(F&&,U&&)&'>map_or</a>(F&amp;&amp; f, U&amp;&amp; u) &amp;;
template &lt;class F, class U&gt;
U <a href='doc_optional.md#tl::optional-T-::map_or(F&&,U&&)&'>map_or</a>(F&amp;&amp; f, U&amp;&amp; u) &amp;&amp;;
template &lt;class F, class U&gt;
U <a href='doc_optional.md#tl::optional-T-::map_or(F&&,U&&)&'>map_or</a>(F&amp;&amp; f, U&amp;&amp; u) const &amp;;
template &lt;class F, class U&gt;
U <a href='doc_optional.md#tl::optional-T-::map_or(F&&,U&&)&'>map_or</a>(F&amp;&amp; f, U&amp;&amp; u) const &amp;&amp;;
template &lt;class F, class U&gt; U map_or_else(F &amp;&amp;f, U &amp;&amp;u); template &lt;class F, class U&gt;
template &lt;class F, class U&gt; U map_or_else(F &amp;&amp;f, U &amp;&amp;u) const; U <a href='doc_optional.md#tl::optional-T-::map_or_else(F&&,U&&)&'>map_or_else</a>(F&amp;&amp; f, U&amp;&amp; u) &amp;;
template &lt;class F, class U&gt;
U <a href='doc_optional.md#tl::optional-T-::map_or_else(F&&,U&&)&'>map_or_else</a>(F&amp;&amp; f, U&amp;&amp; u) &amp;&amp;;
template &lt;class F, class U&gt;
U <a href='doc_optional.md#tl::optional-T-::map_or_else(F&&,U&&)&'>map_or_else</a>(F&amp;&amp; f, U&amp;&amp; u) const &amp;;
template &lt;class F, class U&gt;
U <a href='doc_optional.md#tl::optional-T-::map_or_else(F&&,U&&)&'>map_or_else</a>(F&amp;&amp; f, U&amp;&amp; u) const &amp;&amp;;
template &lt;class U&gt;
constexpr <a href='doc_optional.md#tl::optional-T-'>optional&lt;U&gt;</a> <a href='doc_optional.md#tl::optional-T-::conjunction(U&&)const'>conjunction</a>(U&amp;&amp; u) const;
constexpr <a href='doc_optional.md#tl::optional-T-'>optional</a> <a href='doc_optional.md#tl::optional-T-::disjunction(constoptional-T-&)&'>disjunction</a>(const <a href='doc_optional.md#tl::optional-T-'>optional</a>&amp; rhs) &amp;;
constexpr <a href='doc_optional.md#tl::optional-T-'>optional</a> <a href='doc_optional.md#tl::optional-T-::disjunction(constoptional-T-&)&'>disjunction</a>(const <a href='doc_optional.md#tl::optional-T-'>optional</a>&amp; rhs) const &amp;;
constexpr <a href='doc_optional.md#tl::optional-T-'>optional</a> <a href='doc_optional.md#tl::optional-T-::disjunction(constoptional-T-&)&'>disjunction</a>(const <a href='doc_optional.md#tl::optional-T-'>optional</a>&amp; rhs) &amp;&amp;;
constexpr <a href='doc_optional.md#tl::optional-T-'>optional</a> <a href='doc_optional.md#tl::optional-T-::disjunction(constoptional-T-&)&'>disjunction</a>(const <a href='doc_optional.md#tl::optional-T-'>optional</a>&amp; rhs) const &amp;&amp;;
constexpr <a href='doc_optional.md#tl::optional-T-'>optional</a> <a href='doc_optional.md#tl::optional-T-::disjunction(constoptional-T-&)&'>disjunction</a>(<a href='doc_optional.md#tl::optional-T-'>optional</a>&amp;&amp; rhs) &amp;;
constexpr <a href='doc_optional.md#tl::optional-T-'>optional</a> <a href='doc_optional.md#tl::optional-T-::disjunction(constoptional-T-&)&'>disjunction</a>(<a href='doc_optional.md#tl::optional-T-'>optional</a>&amp;&amp; rhs) const &amp;;
constexpr <a href='doc_optional.md#tl::optional-T-'>optional</a> <a href='doc_optional.md#tl::optional-T-::disjunction(constoptional-T-&)&'>disjunction</a>(<a href='doc_optional.md#tl::optional-T-'>optional</a>&amp;&amp; rhs) &amp;&amp;;
constexpr <a href='doc_optional.md#tl::optional-T-'>optional</a> <a href='doc_optional.md#tl::optional-T-::disjunction(constoptional-T-&)&'>disjunction</a>(<a href='doc_optional.md#tl::optional-T-'>optional</a>&amp;&amp; rhs) const &amp;&amp;;
<a href='doc_optional.md#tl::optional-T-'>optional</a> <a href='doc_optional.md#tl::optional-T-::take()&'>take</a>() &amp;;
<a href='doc_optional.md#tl::optional-T-'>optional</a> <a href='doc_optional.md#tl::optional-T-::take()&'>take</a>() const &amp;;
<a href='doc_optional.md#tl::optional-T-'>optional</a> <a href='doc_optional.md#tl::optional-T-::take()&'>take</a>() &amp;&amp;;
<a href='doc_optional.md#tl::optional-T-'>optional</a> <a href='doc_optional.md#tl::optional-T-::take()&'>take</a>() const &amp;&amp;;
using <a href='doc_optional.md#tl::optional-T-'>value_type</a> = T; using <a href='doc_optional.md#tl::optional-T-'>value_type</a> = T;
@@ -228,9 +266,17 @@ An optional object is an object that contains the storage for another object and
### Function template `tl::optional::and_then`<a id="tl::optional-T-::and_then(F&&)&"></a> ### Function template `tl::optional::and_then`<a id="tl::optional-T-::and_then(F&&)&"></a>
<pre><code class="language-cpp">(1) template &lt;class F&gt; constexpr auto and_then(F &amp;&amp;f); <pre><code class="language-cpp">(1) template &lt;class F&gt;
constexpr auto and_then(F &amp;&amp;f) &amp;;
(2) template &lt;class F&gt; constexpr auto and_then(F &amp;&amp;f) const;</code></pre> (2) template &lt;class F&gt;
constexpr auto and_then(F &amp;&amp;f) &amp;&amp;;
(3) template &lt;class F&gt;
constexpr auto and_then(F &amp;&amp;f) const &amp;;
(4) template &lt;class F&gt;
constexpr auto and_then(F &amp;&amp;f) const &amp;&amp;;</code></pre>
Carries out some operation which returns an optional on the stored object if there is one. Carries out some operation which returns an optional on the stored object if there is one.
@@ -240,9 +286,13 @@ Carries out some operation which returns an optional on the stored object if the
### Function template `tl::optional::map`<a id="tl::optional-T-::map(F&&)&"></a> ### Function template `tl::optional::map`<a id="tl::optional-T-::map(F&&)&"></a>
<pre><code class="language-cpp">(1) template &lt;class F&gt; auto map(F &amp;&amp;f); <pre><code class="language-cpp">(1) template &lt;class F&gt; auto map(F &amp;&amp;f) &amp;;
(2) template &lt;class F&gt; auto map(F &amp;&amp;f) const;</code></pre> (2) template &lt;class F&gt; auto map(F &amp;&amp;f) &amp;&amp;;
(3) template &lt;class F&gt; auto map(F &amp;&amp;f) const &amp;;
(4) template &lt;class F&gt; auto map(F &amp;&amp;f) const &amp;&amp;;</code></pre>
Carries out some operation on the stored object if there is one. Carries out some operation on the stored object if there is one.
@@ -250,9 +300,11 @@ Carries out some operation on the stored object if there is one.
### Function template `tl::optional::or_else`<a id="tl::optional-T-::or_else(F&&)&"></a> ### Function template `tl::optional::or_else`<a id="tl::optional-T-::or_else(F&&)&"></a>
<pre><code class="language-cpp">(1) template &lt;class F&gt; optional&lt;T&gt; or_else (F &amp;&amp;f); <pre><code class="language-cpp">(1) template &lt;class F&gt; optional&lt;T&gt; or_else (F &amp;&amp;f) &amp;;
(2) template &lt;class F&gt; optional&lt;T&gt; or_else (F &amp;&amp;f) const;</code></pre> (2) template &lt;class F&gt; optional&lt;T&gt; or_else (F &amp;&amp;f) &amp;&amp;;
(3) template &lt;class F&gt; optional&lt;T&gt; or_else (F &amp;&amp;f) const &amp;;</code></pre>
Calls `f` if the optional is empty Calls `f` if the optional is empty
@@ -262,9 +314,17 @@ Calls `f` if the optional is empty
### Function template `tl::optional::map_or`<a id="tl::optional-T-::map_or(F&&,U&&)&"></a> ### Function template `tl::optional::map_or`<a id="tl::optional-T-::map_or(F&&,U&&)&"></a>
<pre><code class="language-cpp">(1) template &lt;class F, class U&gt; U map_or(F &amp;&amp;f, U &amp;&amp;u); <pre><code class="language-cpp">(1) template &lt;class F, class U&gt;
U map_or(F&amp;&amp; f, U&amp;&amp; u) &amp;;
(2) template &lt;class F, class U&gt; U map_or(F &amp;&amp;f, U &amp;&amp;u) const;</code></pre> (2) template &lt;class F, class U&gt;
U map_or(F&amp;&amp; f, U&amp;&amp; u) &amp;&amp;;
(3) template &lt;class F, class U&gt;
U map_or(F&amp;&amp; f, U&amp;&amp; u) const &amp;;
(4) template &lt;class F, class U&gt;
U map_or(F&amp;&amp; f, U&amp;&amp; u) const &amp;&amp;;</code></pre>
Maps the stored value with `f` if there is one, otherwise returns `u` Maps the stored value with `f` if there is one, otherwise returns `u`
@@ -272,14 +332,61 @@ If there is a value stored, then `f` is called with `**this` and the value is re
### Function template `tl::optional::map_or_else`<a id="tl::optional-T-::map_or_else(F&&,U&&)&"></a> ### Function template `tl::optional::map_or_else`<a id="tl::optional-T-::map_or_else(F&&,U&&)&"></a>
<pre><code class="language-cpp">(1) template &lt;class F, class U&gt; U map_or_else(F &amp;&amp;f, U &amp;&amp;u); <pre><code class="language-cpp">(1) template &lt;class F, class U&gt;
U map_or_else(F&amp;&amp; f, U&amp;&amp; u) &amp;;
(2) template &lt;class F, class U&gt; U map_or_else(F &amp;&amp;f, U &amp;&amp;u) const;</code></pre> (2) template &lt;class F, class U&gt;
U map_or_else(F&amp;&amp; f, U&amp;&amp; u) &amp;&amp;;
(3) template &lt;class F, class U&gt;
U map_or_else(F&amp;&amp; f, U&amp;&amp; u) const &amp;;
(4) template &lt;class F, class U&gt;
U map_or_else(F&amp;&amp; f, U&amp;&amp; u) const &amp;&amp;;</code></pre>
Maps the stored value with `f` if there is one, otherwise calls `u` and returns the result. Maps the stored value with `f` if there is one, otherwise calls `u` and returns the result.
If there is a value stored, then `f` is called with `**this` and the value is returned. Otherwise `std::forward<U>(u)()` is returned. If there is a value stored, then `f` is called with `**this` and the value is returned. Otherwise `std::forward<U>(u)()` is returned.
### Function template `tl::optional::conjunction`<a id="tl::optional-T-::conjunction(U&&)const"></a>
<pre><code class="language-cpp">template &lt;class U&gt;
constexpr <a href='doc_optional.md#tl::optional-T-'>optional&lt;U&gt;</a> conjunction(U&amp;&amp; u) const;</code></pre>
*Returns*: `u` if `*this` has a value, otherwise an empty optional.
### Function `tl::optional::disjunction`<a id="tl::optional-T-::disjunction(constoptional-T-&)&"></a>
<pre><code class="language-cpp">(1) constexpr <a href='doc_optional.md#tl::optional-T-'>optional</a> disjunction(const <a href='doc_optional.md#tl::optional-T-'>optional</a>&amp; rhs) &amp;;
(2) constexpr <a href='doc_optional.md#tl::optional-T-'>optional</a> disjunction(const <a href='doc_optional.md#tl::optional-T-'>optional</a>&amp; rhs) const &amp;;
(3) constexpr <a href='doc_optional.md#tl::optional-T-'>optional</a> disjunction(const <a href='doc_optional.md#tl::optional-T-'>optional</a>&amp; rhs) &amp;&amp;;
(4) constexpr <a href='doc_optional.md#tl::optional-T-'>optional</a> disjunction(const <a href='doc_optional.md#tl::optional-T-'>optional</a>&amp; rhs) const &amp;&amp;;
(5) constexpr <a href='doc_optional.md#tl::optional-T-'>optional</a> disjunction(<a href='doc_optional.md#tl::optional-T-'>optional</a>&amp;&amp; rhs) &amp;;
(6) constexpr <a href='doc_optional.md#tl::optional-T-'>optional</a> disjunction(<a href='doc_optional.md#tl::optional-T-'>optional</a>&amp;&amp; rhs) const &amp;;
(7) constexpr <a href='doc_optional.md#tl::optional-T-'>optional</a> disjunction(<a href='doc_optional.md#tl::optional-T-'>optional</a>&amp;&amp; rhs) &amp;&amp;;
(8) constexpr <a href='doc_optional.md#tl::optional-T-'>optional</a> disjunction(<a href='doc_optional.md#tl::optional-T-'>optional</a>&amp;&amp; rhs) const &amp;&amp;;</code></pre>
*Returns*: `rhs` if `*this` is empty, otherwise the current value.
### Function `tl::optional::take`<a id="tl::optional-T-::take()&"></a>
<pre><code class="language-cpp">(1) <a href='doc_optional.md#tl::optional-T-'>optional</a> take() &amp;;
(2) <a href='doc_optional.md#tl::optional-T-'>optional</a> take() const &amp;;
(3) <a href='doc_optional.md#tl::optional-T-'>optional</a> take() &amp;&amp;;
(4) <a href='doc_optional.md#tl::optional-T-'>optional</a> take() const &amp;&amp;;</code></pre>
Takes the value out of the optional, leaving it empty
### Default constructor `tl::optional::optional`<a id="tl::optional-T-::optional()"></a> ### Default constructor `tl::optional::optional`<a id="tl::optional-T-::optional()"></a>
<pre><code class="language-cpp">(1) constexpr optional() noexcept = default; <pre><code class="language-cpp">(1) constexpr optional() noexcept = default;
@@ -335,7 +442,7 @@ Converting move constructor.
<pre><code class="language-cpp">~optional() = default;</code></pre> <pre><code class="language-cpp">~optional() = default;</code></pre>
Destructor. Destroys the stored value if there is one.
### Assignment operator `tl::optional::operator=`<a id="tl::optional-T-::operator=(tl::nullopt_t)"></a> ### Assignment operator `tl::optional::operator=`<a id="tl::optional-T-::operator=(tl::nullopt_t)"></a>

View File

@@ -361,7 +361,7 @@ public:
/// \requires `std::invoke(std::forward<F>(f), value())` returns a `std::optional<U>` for some `U`. /// \requires `std::invoke(std::forward<F>(f), value())` returns a `std::optional<U>` for some `U`.
/// \returns Let `U` be the result of `std::invoke(std::forward<F>(f), value())`. Returns a `std::optional<U>`. The return value is empty if `*this` is empty, otherwise the return value of `std::invoke(std::forward<F>(f), value())` is returned. /// \returns Let `U` be the result of `std::invoke(std::forward<F>(f), value())`. Returns a `std::optional<U>`. The return value is empty if `*this` is empty, otherwise the return value of `std::invoke(std::forward<F>(f), value())` is returned.
/// \group and_then /// \group and_then
/// \synopsis template <class F> constexpr auto and_then(F &&f); /// \synopsis template <class F>\nconstexpr auto and_then(F &&f) &;
template <class F> template <class F>
TL_OPTIONAL_11_CONSTEXPR detail::invoke_result_t<F, T> and_then(F &&f) & { TL_OPTIONAL_11_CONSTEXPR detail::invoke_result_t<F, T> and_then(F &&f) & {
using result = detail::invoke_result_t<F, T>; using result = detail::invoke_result_t<F, T>;
@@ -372,7 +372,8 @@ public:
: result(nullopt); : result(nullopt);
} }
/// \exclude /// \group and_then
/// \synopsis template <class F>\nconstexpr auto and_then(F &&f) &&;
template <class F> template <class F>
TL_OPTIONAL_11_CONSTEXPR detail::invoke_result_t<F, T> and_then(F &&f) && { TL_OPTIONAL_11_CONSTEXPR detail::invoke_result_t<F, T> and_then(F &&f) && {
using result = detail::invoke_result_t<F, T>; using result = detail::invoke_result_t<F, T>;
@@ -384,7 +385,7 @@ public:
} }
/// \group and_then /// \group and_then
/// \synopsis template <class F> constexpr auto and_then(F &&f) const; /// \synopsis template <class F>\nconstexpr auto and_then(F &&f) const &;
template <class F> template <class F>
constexpr detail::invoke_result_t<F, T> and_then(F &&f) const & { constexpr detail::invoke_result_t<F, T> and_then(F &&f) const & {
using result = detail::invoke_result_t<F, T>; using result = detail::invoke_result_t<F, T>;
@@ -395,7 +396,8 @@ public:
: result(nullopt); : result(nullopt);
} }
/// \exclude /// \group and_then
/// \synopsis template <class F>\nconstexpr auto and_then(F &&f) const &&;
template <class F> template <class F>
constexpr detail::invoke_result_t<F, T> and_then(F &&f) const && { constexpr detail::invoke_result_t<F, T> and_then(F &&f) const && {
using result = detail::invoke_result_t<F, T>; using result = detail::invoke_result_t<F, T>;
@@ -409,7 +411,7 @@ public:
/// \brief Carries out some operation on the stored object if there is one. /// \brief Carries out some operation on the stored object if there is one.
/// \returns Let `U` be the result of `std::invoke(std::forward<F>(f), value())`. Returns a `std::optional<U>`. The return value is empty if `*this` is empty, otherwise an `optional<U>` is constructed from the return value of `std::invoke(std::forward<F>(f), value())` and is returned. /// \returns Let `U` be the result of `std::invoke(std::forward<F>(f), value())`. Returns a `std::optional<U>`. The return value is empty if `*this` is empty, otherwise an `optional<U>` is constructed from the return value of `std::invoke(std::forward<F>(f), value())` and is returned.
/// \group map /// \group map
/// \synopsis template <class F> auto map(F &&f); /// \synopsis template <class F> auto map(F &&f) &;
template <class F, detail::disable_if_optional<F> * = nullptr, template <class F, detail::disable_if_optional<F> * = nullptr,
detail::disable_if_ret_void<F, T &> * = nullptr> detail::disable_if_ret_void<F, T &> * = nullptr>
detail::get_map_return<F, T &> map(F &&f) & detail::get_map_return<F, T &> map(F &&f) &
@@ -452,7 +454,8 @@ public:
return monostate{}; return monostate{};
} }
/// \exclude /// \group map
/// \synopsis template <class F> auto map(F &&f) &&;
template <class F, detail::disable_if_optional<F> * = nullptr, template <class F, detail::disable_if_optional<F> * = nullptr,
detail::disable_if_ret_void<F, T &&> * = nullptr> detail::disable_if_ret_void<F, T &&> * = nullptr>
detail::get_map_return<F, T &&> map(F &&f) && { detail::get_map_return<F, T &&> map(F &&f) && {
@@ -494,7 +497,7 @@ public:
} }
/// \group map /// \group map
/// \synopsis template <class F> auto map(F &&f) const; /// \synopsis template <class F> auto map(F &&f) const &;
template <class F, detail::disable_if_optional<F> * = nullptr, template <class F, detail::disable_if_optional<F> * = nullptr,
detail::disable_if_ret_void<F, T const &> * = nullptr> detail::disable_if_ret_void<F, T const &> * = nullptr>
constexpr detail::get_map_return<F, T const &> map(F &&f) const & { constexpr detail::get_map_return<F, T const &> map(F &&f) const & {
@@ -536,7 +539,8 @@ public:
return monostate{}; return monostate{};
} }
/// \exclude /// \group map
/// \synopsis template <class F> auto map(F &&f) const &&;
template <class F, detail::disable_if_optional<F> * = nullptr, template <class F, detail::disable_if_optional<F> * = nullptr,
detail::disable_if_ret_void<F, T const &&> * = nullptr> detail::disable_if_ret_void<F, T const &&> * = nullptr>
constexpr detail::get_map_return<F, T const &&> map(F &&f) const && { constexpr detail::get_map_return<F, T const &&> map(F &&f) const && {
@@ -581,7 +585,7 @@ public:
/// \requires `std::invoke_result_t<F>` must be void or convertible to `optional<T>`. /// \requires `std::invoke_result_t<F>` must be void or convertible to `optional<T>`.
/// \effects If `*this` has a value, returns `*this`. Otherwise, if `f` returns `void`, calls `std::forward<F>(f)` and returns `std::nullopt`. Otherwise, returns `std::forward<F>(f)()`. /// \effects If `*this` has a value, returns `*this`. Otherwise, if `f` returns `void`, calls `std::forward<F>(f)` and returns `std::nullopt`. Otherwise, returns `std::forward<F>(f)()`.
/// \group or_else /// \group or_else
/// \synopsis template <class F> optional<T> or_else (F &&f); /// \synopsis template <class F> optional<T> or_else (F &&f) &;
template <class F, detail::enable_if_ret_void<F> * = nullptr> template <class F, detail::enable_if_ret_void<F> * = nullptr>
optional<T> TL_OPTIONAL_MSVC_2015_CONSTEXPR or_else(F &&f) & { optional<T> TL_OPTIONAL_MSVC_2015_CONSTEXPR or_else(F &&f) & {
if (has_value()) if (has_value())
@@ -597,7 +601,8 @@ public:
return has_value() ? *this : std::forward<F>(f)(); return has_value() ? *this : std::forward<F>(f)();
} }
/// \exclude /// \group or_else
/// \synopsis template <class F> optional<T> or_else (F &&f) &&;
template <class F, detail::enable_if_ret_void<F> * = nullptr> template <class F, detail::enable_if_ret_void<F> * = nullptr>
optional<T> or_else(F &&f) && { optional<T> or_else(F &&f) && {
if (has_value()) if (has_value())
@@ -613,7 +618,8 @@ public:
return has_value() ? std::move(*this) : std::forward<F>(f)(); return has_value() ? std::move(*this) : std::forward<F>(f)();
} }
/// \exclude /// \group or_else
/// \synopsis template <class F> optional<T> or_else (F &&f) const &;
template <class F, detail::enable_if_ret_void<F> * = nullptr> template <class F, detail::enable_if_ret_void<F> * = nullptr>
optional<T> or_else(F &&f) const & { optional<T> or_else(F &&f) const & {
if (has_value()) if (has_value())
@@ -623,8 +629,7 @@ public:
return nullopt; return nullopt;
} }
/// \group or_else /// \exclude
/// \synopsis template <class F> optional<T> or_else (F &&f) const;
template <class F, detail::disable_if_ret_void<F> * = nullptr> template <class F, detail::disable_if_ret_void<F> * = nullptr>
optional<T> TL_OPTIONAL_MSVC_2015_CONSTEXPR or_else(F &&f) const & { optional<T> TL_OPTIONAL_MSVC_2015_CONSTEXPR or_else(F &&f) const & {
return has_value() ? *this : std::forward<F>(f)(); return has_value() ? *this : std::forward<F>(f)();
@@ -651,26 +656,24 @@ public:
/// \details If there is a value stored, then `f` is called with `**this` and the value is returned. /// \details If there is a value stored, then `f` is called with `**this` and the value is returned.
/// Otherwise `u` is returned. /// Otherwise `u` is returned.
/// \group map_or /// \group map_or
/// \synopsis template <class F, class U> U map_or(F &&f, U &&u);
template <class F, class U> U map_or(F &&f, U &&u) & { template <class F, class U> U map_or(F &&f, U &&u) & {
return has_value() ? detail::invoke(std::forward<F>(f), **this) return has_value() ? detail::invoke(std::forward<F>(f), **this)
: std::forward<U>(u); : std::forward<U>(u);
} }
/// \exclude /// \group map_or
template <class F, class U> U map_or(F &&f, U &&u) && { template <class F, class U> U map_or(F &&f, U &&u) && {
return has_value() ? detail::invoke(std::forward<F>(f), std::move(**this)) return has_value() ? detail::invoke(std::forward<F>(f), std::move(**this))
: std::forward<U>(u); : std::forward<U>(u);
} }
/// \group map_or /// \group map_or
/// \synopsis template <class F, class U> U map_or(F &&f, U &&u) const;
template <class F, class U> U map_or(F &&f, U &&u) const & { template <class F, class U> U map_or(F &&f, U &&u) const & {
return has_value() ? detail::invoke(std::forward<F>(f), **this) return has_value() ? detail::invoke(std::forward<F>(f), **this)
: std::forward<U>(u); : std::forward<U>(u);
} }
/// \exclude /// \group map_or
template <class F, class U> U map_or(F &&f, U &&u) const && { template <class F, class U> U map_or(F &&f, U &&u) const && {
return has_value() ? detail::invoke(std::forward<F>(f), std::move(**this)) return has_value() ? detail::invoke(std::forward<F>(f), std::move(**this))
: std::forward<U>(u); : std::forward<U>(u);
@@ -679,32 +682,105 @@ public:
/// \brief Maps the stored value with `f` if there is one, otherwise calls `u` and returns the result. /// \brief Maps the stored value with `f` if there is one, otherwise calls `u` and returns the result.
/// \details If there is a value stored, then `f` is called with `**this` and the value is returned. /// \details If there is a value stored, then `f` is called with `**this` and the value is returned.
/// Otherwise `std::forward<U>(u)()` is returned. /// Otherwise `std::forward<U>(u)()` is returned.
/// \synopsis template <class F, class U> U map_or_else(F &&f, U &&u);
/// \group map_or_else /// \group map_or_else
template <class F, class U> U map_or_else(F &&f, U &&u) & { template <class F, class U> U map_or_else(F &&f, U &&u) & {
return has_value() ? detail::invoke(std::forward<F>(f), **this) return has_value() ? detail::invoke(std::forward<F>(f), **this)
: std::forward<U>(u)(); : std::forward<U>(u)();
} }
/// \exclude /// \group map_or_else
template <class F, class U> U map_or_else(F &&f, U &&u) && { template <class F, class U> U map_or_else(F &&f, U &&u) && {
return has_value() ? detail::invoke(std::forward<F>(f), std::move(**this)) return has_value() ? detail::invoke(std::forward<F>(f), std::move(**this))
: std::forward<U>(u)(); : std::forward<U>(u)();
} }
/// \group map_or_else /// \group map_or_else
/// \synopsis template <class F, class U> U map_or_else(F &&f, U &&u) const;
template <class F, class U> U map_or_else(F &&f, U &&u) const & { template <class F, class U> U map_or_else(F &&f, U &&u) const & {
return has_value() ? detail::invoke(std::forward<F>(f), **this) return has_value() ? detail::invoke(std::forward<F>(f), **this)
: std::forward<U>(u)(); : std::forward<U>(u)();
} }
/// \exclude /// \group map_or_else
template <class F, class U> U map_or_else(F &&f, U &&u) const && { template <class F, class U> U map_or_else(F &&f, U &&u) const && {
return has_value() ? detail::invoke(std::forward<F>(f), std::move(**this)) return has_value() ? detail::invoke(std::forward<F>(f), std::move(**this))
: std::forward<U>(u)(); : std::forward<U>(u)();
} }
/// \returns `u` if `*this` has a value, otherwise an empty optional.
template <class U> constexpr optional<U> conjunction (U &&u) const {
return has_value() ? u : nullopt;
}
/// \returns `rhs` if `*this` is empty, otherwise the current value.
/// \group disjunction
constexpr optional disjunction (const optional &rhs) & {
return has_value() ? *this : rhs;
}
/// \group disjunction
constexpr optional disjunction (const optional &rhs) const & {
return has_value() ? *this : rhs;
}
/// \group disjunction
constexpr optional disjunction (const optional &rhs) && {
return has_value() ? std::move(*this) : rhs;
}
/// \group disjunction
constexpr optional disjunction (const optional &rhs) const && {
return has_value() ? std::move(*this) : rhs;
}
/// \group disjunction
constexpr optional disjunction (optional &&rhs) & {
return has_value() ? *this : std::move(rhs);
}
/// \group disjunction
constexpr optional disjunction (optional &&rhs) const & {
return has_value() ? *this : std::move(rhs);
}
/// \group disjunction
constexpr optional disjunction (optional &&rhs) && {
return has_value() ? std::move(*this) : std::move(rhs);
}
/// \group disjunction
constexpr optional disjunction (optional &&rhs) const && {
return has_value() ? std::move(*this) : std::move(rhs);
}
/// Takes the value out of the optional, leaving it empty
/// \group take
optional take() & {
optional ret = *this;
reset();
return ret;
}
/// \group take
optional take() const & {
optional ret = *this;
reset();
return ret;
}
/// \group take
optional take() && {
optional ret = std::move(*this);
reset();
return ret;
}
/// \group take
optional take() const && {
optional ret = std::move(*this);
reset();
return ret;
}
using value_type = T; using value_type = T;
/// Constructs an optional that does not contain a value. /// Constructs an optional that does not contain a value.
@@ -813,7 +889,7 @@ public:
new (std::addressof(this->m_value)) T(std::move(*rhs)); new (std::addressof(this->m_value)) T(std::move(*rhs));
} }
/// Destructor. /// Destroys the stored value if there is one.
~optional() = default; ~optional() = default;
/// Assignment to empty. /// Assignment to empty.