mirror of
https://github.com/TartanLlama/optional.git
synced 2025-07-30 18:07:15 +02:00
More extensions
This commit is contained in:
@ -14,7 +14,7 @@ set(TEST_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/tests/main.cpp
|
|||||||
${CMAKE_CURRENT_SOURCE_DIR}/tests/in_place.cpp
|
${CMAKE_CURRENT_SOURCE_DIR}/tests/in_place.cpp
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/tests/relops.cpp
|
${CMAKE_CURRENT_SOURCE_DIR}/tests/relops.cpp
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/tests/observers.cpp
|
${CMAKE_CURRENT_SOURCE_DIR}/tests/observers.cpp
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/tests/monadic.cpp
|
${CMAKE_CURRENT_SOURCE_DIR}/tests/extensions.cpp
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/tests/constexpr.cpp
|
${CMAKE_CURRENT_SOURCE_DIR}/tests/constexpr.cpp
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/tests/nullopt.cpp)
|
${CMAKE_CURRENT_SOURCE_DIR}/tests/nullopt.cpp)
|
||||||
|
|
||||||
|
@ -177,16 +177,16 @@ public:
|
|||||||
U <a href='doc_optional.md#tl::optional-T-::map_or(F&&,U&&)&'>map_or</a>(F&& f, U&& u) const &&;
|
U <a href='doc_optional.md#tl::optional-T-::map_or(F&&,U&&)&'>map_or</a>(F&& f, U&& u) const &&;
|
||||||
|
|
||||||
template <class F, class U>
|
template <class F, class U>
|
||||||
U <a href='doc_optional.md#tl::optional-T-::map_or_else(F&&,U&&)&'>map_or_else</a>(F&& f, U&& u) &;
|
auto map_or_else(F &&f, U &&u) &;
|
||||||
template <class F, class U>
|
template <class F, class U>
|
||||||
U <a href='doc_optional.md#tl::optional-T-::map_or_else(F&&,U&&)&'>map_or_else</a>(F&& f, U&& u) &&;
|
auto map_or_else(F &&f, U &&u) &&;
|
||||||
template <class F, class U>
|
template <class F, class U>
|
||||||
U <a href='doc_optional.md#tl::optional-T-::map_or_else(F&&,U&&)&'>map_or_else</a>(F&& f, U&& u) const &;
|
auto map_or_else(F &&f, U &&u) const &;
|
||||||
template <class F, class U>
|
template <class F, class U>
|
||||||
U <a href='doc_optional.md#tl::optional-T-::map_or_else(F&&,U&&)&'>map_or_else</a>(F&& f, U&& u) const &&;
|
auto map_or_else(F &&f, U &&u) const &&;
|
||||||
|
|
||||||
template <class U>
|
template <class U>
|
||||||
constexpr <a href='doc_optional.md#tl::optional-T-'>optional<U></a> <a href='doc_optional.md#tl::optional-T-::conjunction(U&&)const'>conjunction</a>(U&& u) const;
|
constexpr <a href='doc_optional.md#tl::optional-T-'>optional<typename std::decay<U>::type></a> <a href='doc_optional.md#tl::optional-T-::conjunction(U&&)const'>conjunction</a>(U&& 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>& rhs) &;
|
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>& rhs) &;
|
||||||
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>& rhs) 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>& rhs) const &;
|
||||||
@ -333,16 +333,16 @@ 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 <class F, class U>
|
<pre><code class="language-cpp">(1) template <class F, class U>
|
||||||
U map_or_else(F&& f, U&& u) &;
|
auto map_or_else(F &&f, U &&u) &;
|
||||||
|
|
||||||
(2) template <class F, class U>
|
(2) template <class F, class U>
|
||||||
U map_or_else(F&& f, U&& u) &&;
|
auto map_or_else(F &&f, U &&u) &&;
|
||||||
|
|
||||||
(3) template <class F, class U>
|
(3) template <class F, class U>
|
||||||
U map_or_else(F&& f, U&& u) const &;
|
auto map_or_else(F &&f, U &&u) const &;
|
||||||
|
|
||||||
(4) template <class F, class U>
|
(4) template <class F, class U>
|
||||||
U map_or_else(F&& f, U&& u) const &&;</code></pre>
|
auto map_or_else(F &&f, U &&u) const &&;</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.
|
||||||
|
|
||||||
@ -351,7 +351,7 @@ If there is a value stored, then `f` is called with `**this` and the value is re
|
|||||||
### Function template `tl::optional::conjunction`<a id="tl::optional-T-::conjunction(U&&)const"></a>
|
### Function template `tl::optional::conjunction`<a id="tl::optional-T-::conjunction(U&&)const"></a>
|
||||||
|
|
||||||
<pre><code class="language-cpp">template <class U>
|
<pre><code class="language-cpp">template <class U>
|
||||||
constexpr <a href='doc_optional.md#tl::optional-T-'>optional<U></a> conjunction(U&& u) const;</code></pre>
|
constexpr <a href='doc_optional.md#tl::optional-T-'>optional<typename std::decay<U>::type></a> conjunction(U&& u) const;</code></pre>
|
||||||
|
|
||||||
*Returns*: `u` if `*this` has a value, otherwise an empty optional.
|
*Returns*: `u` if `*this` has a value, otherwise an empty optional.
|
||||||
|
|
||||||
|
22
optional.hpp
22
optional.hpp
@ -683,32 +683,42 @@ 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 `std::forward<U>(u)()` is returned.
|
/// Otherwise `std::forward<U>(u)()` is returned.
|
||||||
/// \group map_or_else
|
/// \group map_or_else
|
||||||
template <class F, class U> U map_or_else(F &&f, U &&u) & {
|
/// \synopsis template <class F, class U>\nauto map_or_else(F &&f, U &&u) &;
|
||||||
|
template <class F, class U>
|
||||||
|
detail::invoke_result_t<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)();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// \group map_or_else
|
/// \group map_or_else
|
||||||
template <class F, class U> U map_or_else(F &&f, U &&u) && {
|
/// \synopsis template <class F, class U>\nauto map_or_else(F &&f, U &&u) &&;
|
||||||
|
template <class F, class U>
|
||||||
|
detail::invoke_result_t<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
|
||||||
template <class F, class U> U map_or_else(F &&f, U &&u) const & {
|
/// \synopsis template <class F, class U>\nauto map_or_else(F &&f, U &&u) const &;
|
||||||
|
template <class F, class U>
|
||||||
|
detail::invoke_result_t<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)();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// \group map_or_else
|
/// \group map_or_else
|
||||||
template <class F, class U> U map_or_else(F &&f, U &&u) const && {
|
/// \synopsis template <class F, class U>\nauto map_or_else(F &&f, U &&u) const &&;
|
||||||
|
template <class F, class U>
|
||||||
|
detail::invoke_result_t<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.
|
/// \returns `u` if `*this` has a value, otherwise an empty optional.
|
||||||
template <class U> constexpr optional<U> conjunction (U &&u) const {
|
template <class U>
|
||||||
return has_value() ? u : nullopt;
|
constexpr optional<typename std::decay<U>::type> conjunction (U &&u) const {
|
||||||
|
using result = optional<detail::decay_t<U>>;
|
||||||
|
return has_value() ? result{u} : result{nullopt};
|
||||||
}
|
}
|
||||||
|
|
||||||
/// \returns `rhs` if `*this` is empty, otherwise the current value.
|
/// \returns `rhs` if `*this` is empty, otherwise the current value.
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
#include "catch.hpp"
|
#include "catch.hpp"
|
||||||
#include "optional.hpp"
|
#include "optional.hpp"
|
||||||
|
#include <string>
|
||||||
|
|
||||||
#define TOKENPASTE(x, y) x##y
|
#define TOKENPASTE(x, y) x##y
|
||||||
#define TOKENPASTE2(x, y) TOKENPASTE(x, y)
|
#define TOKENPASTE2(x, y) TOKENPASTE(x, y)
|
||||||
@ -339,7 +340,62 @@ SECTION("constexpr and_then") {
|
|||||||
}
|
}
|
||||||
|
|
||||||
SECTION("or else") {
|
SECTION("or else") {
|
||||||
//TODO
|
tl::optional<int> o1 = 42;
|
||||||
|
REQUIRE(*(o1.or_else([] { return tl::make_optional(13); })) == 42);
|
||||||
|
|
||||||
|
tl::optional<int> o2;
|
||||||
|
REQUIRE(*(o2.or_else([] { return tl::make_optional(13); })) == 13);
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("disjunction") {
|
||||||
|
tl::optional<int> o1 = 42;
|
||||||
|
tl::optional<int> o2 = 12;
|
||||||
|
tl::optional<int> o3;
|
||||||
|
|
||||||
|
REQUIRE(*o1.disjunction(o2) == 42);
|
||||||
|
REQUIRE(*o1.disjunction(o3) == 42);
|
||||||
|
REQUIRE(*o2.disjunction(o1) == 12);
|
||||||
|
REQUIRE(*o2.disjunction(o3) == 12);
|
||||||
|
REQUIRE(*o3.disjunction(o1) == 42);
|
||||||
|
REQUIRE(*o3.disjunction(o2) == 12);
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("conjunction") {
|
||||||
|
tl::optional<int> o1 = 42;
|
||||||
|
REQUIRE(*o1.conjunction(42.0) == 42.0);
|
||||||
|
REQUIRE(*o1.conjunction(std::string{"hello"}) == std::string{"hello"});
|
||||||
|
REQUIRE(!o1.conjunction(tl::nullopt));
|
||||||
|
|
||||||
|
tl::optional<int> o2;
|
||||||
|
REQUIRE(!o2.conjunction(42.0));
|
||||||
|
REQUIRE(!o2.conjunction(std::string{"hello"}));
|
||||||
|
REQUIRE(!o2.conjunction(tl::nullopt));
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("map_or") {
|
||||||
|
tl::optional<int> o1 = 21;
|
||||||
|
REQUIRE((o1.map_or([](auto x) { return x * 2; }, 13)) == 42);
|
||||||
|
|
||||||
|
tl::optional<int> o2;
|
||||||
|
REQUIRE((o2.map_or([](auto x) { return x * 2; }, 13)) == 13);
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("map_or_else") {
|
||||||
|
tl::optional<int> o1 = 21;
|
||||||
|
REQUIRE((o1.map_or_else([](auto x) { return x * 2; }, []{return 13;})) == 42);
|
||||||
|
|
||||||
|
tl::optional<int> o2;
|
||||||
|
REQUIRE((o2.map_or_else([](auto x) { return x * 2; }, []{return 13;})) == 13);
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("take") {
|
||||||
|
tl::optional<int> o1 = 42;
|
||||||
|
REQUIRE(*o1.take() == 42);
|
||||||
|
REQUIRE(!o1);
|
||||||
|
|
||||||
|
tl::optional<int> o2;
|
||||||
|
REQUIRE(!o2.take());
|
||||||
|
REQUIRE(!o2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
;
|
;
|
Reference in New Issue
Block a user