forked from TartanLlama/optional
Change bind overload into or_else
This commit is contained in:
151
optional.hpp
151
optional.hpp
@ -113,24 +113,24 @@ using invoke_result_t = typename invoke_result<F, Us...>::type;
|
|||||||
template <class U>
|
template <class U>
|
||||||
using fixup_void = conditional_t<std::is_void<U>::value, monostate, U>;
|
using fixup_void = conditional_t<std::is_void<U>::value, monostate, U>;
|
||||||
|
|
||||||
template <class F, class U> struct get_invoke_optional_ret {
|
template <class F, class... U> struct get_invoke_optional_ret {
|
||||||
using type = invoke_result_t<
|
using type = invoke_result_t<
|
||||||
conditional_t<std::is_lvalue_reference<F>::value,
|
conditional_t<std::is_lvalue_reference<F>::value,
|
||||||
typename remove_reference_t<F>::value_type &,
|
typename remove_reference_t<F>::value_type &,
|
||||||
typename remove_reference_t<F>::value_type &&>,
|
typename remove_reference_t<F>::value_type &&>,
|
||||||
U>;
|
U...>;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class F, class U>
|
template <class F, class... U>
|
||||||
using get_invoke_ret =
|
using get_invoke_ret = typename conditional_t<is_optional<F>::value,
|
||||||
typename conditional_t<is_optional<F>::value, get_invoke_optional_ret<F, U>,
|
get_invoke_optional_ret<F, U...>,
|
||||||
invoke_result<F, U>>::type;
|
invoke_result<F, U...>>::type;
|
||||||
|
|
||||||
template <class F, class U>
|
template <class F, class U>
|
||||||
using get_map_return = optional<fixup_void<get_invoke_ret<F, U>>>;
|
using get_map_return = optional<fixup_void<get_invoke_ret<F, U>>>;
|
||||||
|
|
||||||
template <class F, class U>
|
template <class F, class... U>
|
||||||
using returns_void = std::is_void<get_invoke_ret<F, U>>;
|
using returns_void = std::is_void<get_invoke_ret<F, U...>>;
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
using disable_if_optional = enable_if_t<!is_optional<T>::value>;
|
using disable_if_optional = enable_if_t<!is_optional<T>::value>;
|
||||||
@ -138,11 +138,11 @@ using disable_if_optional = enable_if_t<!is_optional<T>::value>;
|
|||||||
template <class T>
|
template <class T>
|
||||||
using enable_if_optional = enable_if_t<is_optional<T>::value>;
|
using enable_if_optional = enable_if_t<is_optional<T>::value>;
|
||||||
|
|
||||||
template <class T, class U>
|
template <class T, class... U>
|
||||||
using enable_if_ret_void = enable_if_t<returns_void<T &&, U>::value>;
|
using enable_if_ret_void = enable_if_t<returns_void<T &&, U...>::value>;
|
||||||
|
|
||||||
template <class T, class U>
|
template <class T, class... U>
|
||||||
using disable_if_ret_void = enable_if_t<!returns_void<T &&, U>::value>;
|
using disable_if_ret_void = enable_if_t<!returns_void<T &&, U...>::value>;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct in_place_t {
|
struct in_place_t {
|
||||||
@ -766,7 +766,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <class F>
|
template <class F>
|
||||||
TL_OPTIONAL_11_CONSTEXPR detail::invoke_result_t<F, T> bind(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>;
|
||||||
static_assert(detail::is_optional<result>::value,
|
static_assert(detail::is_optional<result>::value,
|
||||||
"F must return an optional");
|
"F must return an optional");
|
||||||
@ -776,7 +776,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <class F>
|
template <class F>
|
||||||
TL_OPTIONAL_11_CONSTEXPR detail::invoke_result_t<F, T> bind(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>;
|
||||||
static_assert(detail::is_optional<result>::value,
|
static_assert(detail::is_optional<result>::value,
|
||||||
"F must return an optional");
|
"F must return an optional");
|
||||||
@ -786,7 +786,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <class F>
|
template <class F>
|
||||||
constexpr detail::invoke_result_t<F, T> bind(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>;
|
||||||
static_assert(detail::is_optional<result>::value,
|
static_assert(detail::is_optional<result>::value,
|
||||||
"F must return an optional");
|
"F must return an optional");
|
||||||
@ -796,7 +796,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <class F>
|
template <class F>
|
||||||
constexpr detail::invoke_result_t<F, T> bind(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>;
|
||||||
static_assert(detail::is_optional<result>::value,
|
static_assert(detail::is_optional<result>::value,
|
||||||
"F must return an optional");
|
"F must return an optional");
|
||||||
@ -805,69 +805,6 @@ public:
|
|||||||
: result(nullopt);
|
: result(nullopt);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class F, class E>
|
|
||||||
detail::invoke_result_t<F, T> bind(F &&f, E &&e) &
|
|
||||||
noexcept(noexcept(detail::invoke(std::forward<F>(f),
|
|
||||||
std::declval<T &>())) &&
|
|
||||||
noexcept(std::forward<E>(e)())) {
|
|
||||||
using result = detail::invoke_result_t<F, T>;
|
|
||||||
static_assert(detail::is_optional<result>::value,
|
|
||||||
"F must return an optional");
|
|
||||||
|
|
||||||
if (!has_value())
|
|
||||||
return result(nullopt);
|
|
||||||
|
|
||||||
auto ret = detail::invoke(std::forward<F>(f), **this);
|
|
||||||
if (!ret)
|
|
||||||
detail::invoke(e);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class F, class E>
|
|
||||||
detail::invoke_result_t<F, T> bind(F &&f, E &&e) && {
|
|
||||||
using result = detail::invoke_result_t<F, T>;
|
|
||||||
static_assert(detail::is_optional<result>::value,
|
|
||||||
"F must return an optional");
|
|
||||||
|
|
||||||
if (!has_value())
|
|
||||||
return result(nullopt);
|
|
||||||
|
|
||||||
auto ret = detail::invoke(std::forward<F>(f), std::move(**this));
|
|
||||||
if (!ret)
|
|
||||||
detail::invoke(e);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class F, class E>
|
|
||||||
detail::invoke_result_t<F, T> bind(F &&f, E &&e) const & {
|
|
||||||
using result = detail::invoke_result_t<F, T>;
|
|
||||||
static_assert(detail::is_optional<result>::value,
|
|
||||||
"F must return an optional");
|
|
||||||
|
|
||||||
if (!has_value())
|
|
||||||
return result(nullopt);
|
|
||||||
|
|
||||||
auto ret = detail::invoke(std::forward<F>(f), **this);
|
|
||||||
if (!ret)
|
|
||||||
detail::invoke(e);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class F, class E>
|
|
||||||
detail::invoke_result_t<F, T> bind(F &&f, E &&e) const && {
|
|
||||||
using result = detail::invoke_result_t<F, T>;
|
|
||||||
static_assert(detail::is_optional<result>::value,
|
|
||||||
"F must return an optional");
|
|
||||||
|
|
||||||
if (!has_value())
|
|
||||||
return result(nullopt);
|
|
||||||
|
|
||||||
auto ret = detail::invoke(std::forward<F>(f), std::move(**this));
|
|
||||||
if (!ret)
|
|
||||||
detail::invoke(e);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
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) &
|
||||||
@ -1019,6 +956,62 @@ public:
|
|||||||
return monostate{};
|
return monostate{};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <class F, detail::enable_if_ret_void<F> * = nullptr>
|
||||||
|
optional<T> constexpr or_else(F &&f) & {
|
||||||
|
if (has_value())
|
||||||
|
return *this;
|
||||||
|
|
||||||
|
std::forward<F>(f)();
|
||||||
|
return nullopt;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class F, detail::disable_if_ret_void<F> * = nullptr>
|
||||||
|
optional<T> constexpr or_else(F &&f) & {
|
||||||
|
return has_value() ? *this : std::forward<F>(f)();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class F, detail::enable_if_ret_void<F> * = nullptr>
|
||||||
|
optional<T> or_else(F &&f) && {
|
||||||
|
if (has_value())
|
||||||
|
return std::move(*this);
|
||||||
|
|
||||||
|
std::forward<F>(f)();
|
||||||
|
return nullopt;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class F, detail::disable_if_ret_void<F> * = nullptr>
|
||||||
|
optional<T> constexpr or_else(F &&f) && {
|
||||||
|
return has_value() ? std::move(*this) : std::forward<F>(f)();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class F, detail::enable_if_ret_void<F> * = nullptr>
|
||||||
|
optional<T> or_else(F &&f) const & {
|
||||||
|
if (has_value())
|
||||||
|
return *this;
|
||||||
|
|
||||||
|
std::forward<F>(f)();
|
||||||
|
return nullopt;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class F, detail::disable_if_ret_void<F> * = nullptr>
|
||||||
|
optional<T> constexpr or_else(F &&f) const & {
|
||||||
|
return has_value() ? *this : std::forward<F>(f)();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class F, detail::enable_if_ret_void<F> * = nullptr>
|
||||||
|
optional<T> or_else(F &&f) const && {
|
||||||
|
if (has_value())
|
||||||
|
return std::move(*this);
|
||||||
|
|
||||||
|
std::forward<F>(f)();
|
||||||
|
return nullopt;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class F, detail::disable_if_ret_void<F> * = nullptr>
|
||||||
|
optional<T> or_else(F &&f) const && {
|
||||||
|
return has_value() ? std::move(*this) : std::forward<F>(f)();
|
||||||
|
}
|
||||||
|
|
||||||
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);
|
||||||
|
@ -10,7 +10,6 @@
|
|||||||
constexpr int get_int(int) { return 42; }
|
constexpr int get_int(int) { return 42; }
|
||||||
constexpr tl::optional<int> get_opt_int(int) { return 42; }
|
constexpr tl::optional<int> get_opt_int(int) { return 42; }
|
||||||
|
|
||||||
|
|
||||||
// What is Clang Format up to?!
|
// What is Clang Format up to?!
|
||||||
TEST_CASE("Monadic operations",
|
TEST_CASE("Monadic operations",
|
||||||
"[monadic]"){SECTION("map"){// lhs is empty
|
"[monadic]"){SECTION("map"){// lhs is empty
|
||||||
@ -58,7 +57,8 @@ REQUIRE(o6r.value() == 42);
|
|||||||
tl::optional<int> o7 = 40;
|
tl::optional<int> o7 = 40;
|
||||||
auto f7 = tl::make_optional([](const int &i) { return; });
|
auto f7 = tl::make_optional([](const int &i) { return; });
|
||||||
auto o7r = o7.map(f7);
|
auto o7r = o7.map(f7);
|
||||||
STATIC_REQUIRE((std::is_same<decltype(o7r), tl::optional<tl::monostate>>::value));
|
STATIC_REQUIRE(
|
||||||
|
(std::is_same<decltype(o7r), tl::optional<tl::monostate>>::value));
|
||||||
REQUIRE(o6r.has_value());
|
REQUIRE(o6r.has_value());
|
||||||
|
|
||||||
// test each overload in turn
|
// test each overload in turn
|
||||||
@ -191,7 +191,6 @@ auto o39r = std::move(o39).map(tl::make_optional([](int){return;}));
|
|||||||
REQUIRE(!o39r);
|
REQUIRE(!o39r);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
SECTION("map constexpr") {
|
SECTION("map constexpr") {
|
||||||
// test each overload in turn
|
// test each overload in turn
|
||||||
constexpr tl::optional<int> o16 = 42;
|
constexpr tl::optional<int> o16 = 42;
|
||||||
@ -228,170 +227,115 @@ constexpr auto o38r = std::move(o38).map(opt_int);
|
|||||||
STATIC_REQUIRE(!o38r);
|
STATIC_REQUIRE(!o38r);
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("bind") {
|
SECTION("and_then") {
|
||||||
|
|
||||||
// lhs is empty
|
// lhs is empty
|
||||||
tl::optional<int> o1;
|
tl::optional<int> o1;
|
||||||
auto o1r = o1.bind([](int i) { return tl::optional<float>{42}; });
|
auto o1r = o1.and_then([](int i) { return tl::optional<float>{42}; });
|
||||||
STATIC_REQUIRE((std::is_same<decltype(o1r), tl::optional<float>>::value));
|
STATIC_REQUIRE((std::is_same<decltype(o1r), tl::optional<float>>::value));
|
||||||
REQUIRE(!o1r);
|
REQUIRE(!o1r);
|
||||||
|
|
||||||
// lhs has value
|
// lhs has value
|
||||||
tl::optional<int> o2 = 12;
|
tl::optional<int> o2 = 12;
|
||||||
auto o2r = o2.bind([](int i) { return tl::optional<float>{42}; });
|
auto o2r = o2.and_then([](int i) { return tl::optional<float>{42}; });
|
||||||
STATIC_REQUIRE((std::is_same<decltype(o2r), tl::optional<float>>::value));
|
STATIC_REQUIRE((std::is_same<decltype(o2r), tl::optional<float>>::value));
|
||||||
REQUIRE(o2r.value() == 42.f);
|
REQUIRE(o2r.value() == 42.f);
|
||||||
|
|
||||||
// lhs is empty, rhs returns empty
|
// lhs is empty, rhs returns empty
|
||||||
tl::optional<int> o3;
|
tl::optional<int> o3;
|
||||||
auto o3r = o3.bind([](int i) { return tl::optional<float>{}; });
|
auto o3r = o3.and_then([](int i) { return tl::optional<float>{}; });
|
||||||
STATIC_REQUIRE((std::is_same<decltype(o3r), tl::optional<float>>::value));
|
STATIC_REQUIRE((std::is_same<decltype(o3r), tl::optional<float>>::value));
|
||||||
REQUIRE(!o3r);
|
REQUIRE(!o3r);
|
||||||
|
|
||||||
// rhs returns empty
|
// rhs returns empty
|
||||||
tl::optional<int> o4 = 12;
|
tl::optional<int> o4 = 12;
|
||||||
auto o4r = o4.bind([](int i) { return tl::optional<float>{}; });
|
auto o4r = o4.and_then([](int i) { return tl::optional<float>{}; });
|
||||||
STATIC_REQUIRE((std::is_same<decltype(o4r), tl::optional<float>>::value));
|
STATIC_REQUIRE((std::is_same<decltype(o4r), tl::optional<float>>::value));
|
||||||
REQUIRE(!o4r);
|
REQUIRE(!o4r);
|
||||||
|
|
||||||
struct rval_call_bind {
|
struct rval_call_and_then {
|
||||||
tl::optional<double> operator()(int) && { return tl::optional<double>(42.0); };
|
tl::optional<double> operator()(int) && {
|
||||||
|
return tl::optional<double>(42.0);
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
// ensure that function object is forwarded
|
// ensure that function object is forwarded
|
||||||
tl::optional<int> o5 = 42;
|
tl::optional<int> o5 = 42;
|
||||||
auto o5r = o5.bind(rval_call_bind{});
|
auto o5r = o5.and_then(rval_call_and_then{});
|
||||||
STATIC_REQUIRE((std::is_same<decltype(o5r), tl::optional<double>>::value));
|
STATIC_REQUIRE((std::is_same<decltype(o5r), tl::optional<double>>::value));
|
||||||
REQUIRE(o5r.value() == 42);
|
REQUIRE(o5r.value() == 42);
|
||||||
|
|
||||||
// ensure that lhs is forwarded
|
// ensure that lhs is forwarded
|
||||||
tl::optional<int> o6 = 42;
|
tl::optional<int> o6 = 42;
|
||||||
auto o6r =
|
auto o6r =
|
||||||
std::move(o6).bind([](int &&i) { return tl::optional<double>(i); });
|
std::move(o6).and_then([](int &&i) { return tl::optional<double>(i); });
|
||||||
STATIC_REQUIRE((std::is_same<decltype(o6r), tl::optional<double>>::value));
|
STATIC_REQUIRE((std::is_same<decltype(o6r), tl::optional<double>>::value));
|
||||||
REQUIRE(o6r.value() == 42);
|
REQUIRE(o6r.value() == 42);
|
||||||
|
|
||||||
// ensure that function object is const-propagated
|
// ensure that function object is const-propagated
|
||||||
const tl::optional<int> o7 = 42;
|
const tl::optional<int> o7 = 42;
|
||||||
auto o7r = o7.bind([](const int &i) { return tl::optional<double>(i); });
|
auto o7r = o7.and_then([](const int &i) { return tl::optional<double>(i); });
|
||||||
STATIC_REQUIRE((std::is_same<decltype(o7r), tl::optional<double>>::value));
|
STATIC_REQUIRE((std::is_same<decltype(o7r), tl::optional<double>>::value));
|
||||||
REQUIRE(o7r.value() == 42);
|
REQUIRE(o7r.value() == 42);
|
||||||
|
|
||||||
// test each overload in turn
|
// test each overload in turn
|
||||||
tl::optional<int> o8 = 42;
|
tl::optional<int> o8 = 42;
|
||||||
auto o8r = o8.bind([](int i) { return tl::make_optional(42); });
|
auto o8r = o8.and_then([](int i) { return tl::make_optional(42); });
|
||||||
REQUIRE(*o8r == 42);
|
REQUIRE(*o8r == 42);
|
||||||
|
|
||||||
tl::optional<int> o9 = 42;
|
tl::optional<int> o9 = 42;
|
||||||
auto o9r = std::move(o9).bind([](int i) { return tl::make_optional(42); });
|
auto o9r =
|
||||||
|
std::move(o9).and_then([](int i) { return tl::make_optional(42); });
|
||||||
REQUIRE(*o9r == 42);
|
REQUIRE(*o9r == 42);
|
||||||
|
|
||||||
const tl::optional<int> o10 = 42;
|
const tl::optional<int> o10 = 42;
|
||||||
auto o10r = o10.bind([](int i) { return tl::make_optional(42); });
|
auto o10r = o10.and_then([](int i) { return tl::make_optional(42); });
|
||||||
REQUIRE(*o10r == 42);
|
REQUIRE(*o10r == 42);
|
||||||
|
|
||||||
const tl::optional<int> o11 = 42;
|
const tl::optional<int> o11 = 42;
|
||||||
auto o11r = std::move(o11).bind([](int i) { return tl::make_optional(42); });
|
auto o11r =
|
||||||
|
std::move(o11).and_then([](int i) { return tl::make_optional(42); });
|
||||||
REQUIRE(*o11r == 42);
|
REQUIRE(*o11r == 42);
|
||||||
|
|
||||||
tl::optional<int> o12 = 42;
|
|
||||||
auto o12r = o12.bind([](int i) { return tl::make_optional(42); }, []{return;});
|
|
||||||
REQUIRE(*o12r == 42);
|
|
||||||
|
|
||||||
tl::optional<int> o13 = 42;
|
|
||||||
auto o13r = std::move(o13).bind([](int i) { return tl::make_optional(42); }, []{return;});
|
|
||||||
REQUIRE(*o13r == 42);
|
|
||||||
|
|
||||||
const tl::optional<int> o14 = 42;
|
|
||||||
auto o14r = o14.bind([](int i) { return tl::make_optional(42); }, []{return;});
|
|
||||||
REQUIRE(*o14r == 42);
|
|
||||||
|
|
||||||
const tl::optional<int> o15 = 42;
|
|
||||||
auto o15r = std::move(o15).bind([](int i) { return tl::make_optional(42); }, []{return;});
|
|
||||||
REQUIRE(*o15r == 42);
|
|
||||||
|
|
||||||
tl::optional<int> o16 = tl::nullopt;
|
tl::optional<int> o16 = tl::nullopt;
|
||||||
auto o16r = o16.bind([](int i) { return tl::make_optional(42); });
|
auto o16r = o16.and_then([](int i) { return tl::make_optional(42); });
|
||||||
REQUIRE(!o16r);
|
REQUIRE(!o16r);
|
||||||
|
|
||||||
tl::optional<int> o17 = tl::nullopt;
|
tl::optional<int> o17 = tl::nullopt;
|
||||||
auto o17r = std::move(o17).bind([](int i) { return tl::make_optional(42); });
|
auto o17r =
|
||||||
|
std::move(o17).and_then([](int i) { return tl::make_optional(42); });
|
||||||
REQUIRE(!o17r);
|
REQUIRE(!o17r);
|
||||||
|
|
||||||
const tl::optional<int> o18 = tl::nullopt;
|
const tl::optional<int> o18 = tl::nullopt;
|
||||||
auto o18r = o18.bind([](int i) { return tl::make_optional(42); });
|
auto o18r = o18.and_then([](int i) { return tl::make_optional(42); });
|
||||||
REQUIRE(!o18r);
|
REQUIRE(!o18r);
|
||||||
|
|
||||||
const tl::optional<int> o19 = tl::nullopt;
|
const tl::optional<int> o19 = tl::nullopt;
|
||||||
auto o19r = std::move(o19).bind([](int i) { return tl::make_optional(42); });
|
auto o19r =
|
||||||
|
std::move(o19).and_then([](int i) { return tl::make_optional(42); });
|
||||||
REQUIRE(!o19r);
|
REQUIRE(!o19r);
|
||||||
|
|
||||||
tl::optional<int> o20 = tl::nullopt;
|
|
||||||
bool c20 = false;
|
|
||||||
auto o20r = o20.bind([](int i) { return tl::make_optional(42); }, [&]{c20 = true;});
|
|
||||||
REQUIRE(!o20r);
|
|
||||||
REQUIRE(!c20);
|
|
||||||
|
|
||||||
tl::optional<int> o21 = tl::nullopt;
|
|
||||||
bool c21 = false;
|
|
||||||
auto o21r = std::move(o21).bind([](int i) { return tl::make_optional(42); }, [&]{c21 = true;});
|
|
||||||
REQUIRE(!o21r);
|
|
||||||
REQUIRE(!c21);
|
|
||||||
|
|
||||||
const tl::optional<int> o22 = tl::nullopt;
|
|
||||||
bool c22 = false;
|
|
||||||
auto o22r = o22.bind([](int i) { return tl::make_optional(42); }, [&]{c22 = true;});
|
|
||||||
REQUIRE(!o22r);
|
|
||||||
REQUIRE(!c22);
|
|
||||||
|
|
||||||
const tl::optional<int> o23 = tl::nullopt;
|
|
||||||
bool c23 = false;
|
|
||||||
auto o23r = std::move(o23).bind([](int i) { return tl::make_optional(42); }, [&]{c23 = true;});
|
|
||||||
REQUIRE(!o23r);
|
|
||||||
REQUIRE(!c23);
|
|
||||||
|
|
||||||
tl::optional<int> o24 = 42;
|
|
||||||
bool c24 = false;
|
|
||||||
auto o24r = o24.bind([](int i) { return tl::optional<int>{tl::nullopt}; }, [&]{c24 = true;});
|
|
||||||
REQUIRE(!o24r);
|
|
||||||
REQUIRE(c24);
|
|
||||||
|
|
||||||
tl::optional<int> o25 = 42;
|
|
||||||
bool c25 = false;
|
|
||||||
auto o25r = std::move(o25).bind([](int i) { return tl::optional<int>{tl::nullopt}; }, [&]{c25 = true;});
|
|
||||||
REQUIRE(!o25r);
|
|
||||||
REQUIRE(c25);
|
|
||||||
|
|
||||||
const tl::optional<int> o26 = 42;
|
|
||||||
bool c26 = false;
|
|
||||||
auto o26r = o26.bind([](int i) { return tl::optional<int>{tl::nullopt};}, [&]{c26 = true;});
|
|
||||||
REQUIRE(!o26r);
|
|
||||||
REQUIRE(c26);
|
|
||||||
|
|
||||||
const tl::optional<int> o27 = 42;
|
|
||||||
bool c27 = false;
|
|
||||||
auto o27r = std::move(o27).bind([](int i) { return tl::optional<int>{tl::nullopt};}, [&]{c27 = true;});
|
|
||||||
REQUIRE(!o27r);
|
|
||||||
REQUIRE(c27);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("constexpr bind") {
|
SECTION("constexpr and_then") {
|
||||||
constexpr tl::optional<int> o10 = 42;
|
constexpr tl::optional<int> o10 = 42;
|
||||||
constexpr auto o10r = o10.bind(get_opt_int);
|
constexpr auto o10r = o10.and_then(get_opt_int);
|
||||||
REQUIRE(*o10r == 42);
|
REQUIRE(*o10r == 42);
|
||||||
|
|
||||||
constexpr tl::optional<int> o11 = 42;
|
constexpr tl::optional<int> o11 = 42;
|
||||||
constexpr auto o11r = std::move(o11).bind(get_opt_int);
|
constexpr auto o11r = std::move(o11).and_then(get_opt_int);
|
||||||
REQUIRE(*o11r == 42);
|
REQUIRE(*o11r == 42);
|
||||||
|
|
||||||
constexpr tl::optional<int> o18 = tl::nullopt;
|
constexpr tl::optional<int> o18 = tl::nullopt;
|
||||||
constexpr auto o18r = o18.bind(get_opt_int);
|
constexpr auto o18r = o18.and_then(get_opt_int);
|
||||||
REQUIRE(!o18r);
|
REQUIRE(!o18r);
|
||||||
|
|
||||||
constexpr tl::optional<int> o19 = tl::nullopt;
|
constexpr tl::optional<int> o19 = tl::nullopt;
|
||||||
constexpr auto o19r = std::move(o19).bind(get_opt_int);
|
constexpr auto o19r = std::move(o19).and_then(get_opt_int);
|
||||||
REQUIRE(!o19r);
|
REQUIRE(!o19r);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SECTION("or else") {
|
||||||
|
//TODO
|
||||||
|
}
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
Reference in New Issue
Block a user