Add option::transform and option::or_else
This commit is contained in:
@ -429,6 +429,53 @@ public:
|
|||||||
}
|
}
|
||||||
return un_cvref_t<result_of_t<F(T)>>{};
|
return un_cvref_t<result_of_t<F(T)>>{};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename F>
|
||||||
|
constexpr auto transform(F&& f) &
|
||||||
|
{
|
||||||
|
using U = un_cvref_t<result_of_t<F(T&)>>;
|
||||||
|
if (has_value())
|
||||||
|
{
|
||||||
|
return option<U>{ invoke(ASL_FWD(f), value()) };
|
||||||
|
}
|
||||||
|
return option<U>{};
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename F>
|
||||||
|
constexpr auto transform(F&& f) const&
|
||||||
|
{
|
||||||
|
using U = un_cvref_t<result_of_t<F(const T&)>>;
|
||||||
|
if (has_value())
|
||||||
|
{
|
||||||
|
return option<U>{ invoke(ASL_FWD(f), value()) };
|
||||||
|
}
|
||||||
|
return option<U>{};
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename F>
|
||||||
|
constexpr auto transform(F&& f) &&
|
||||||
|
{
|
||||||
|
using U = un_cvref_t<result_of_t<F(T)>>;
|
||||||
|
if (has_value())
|
||||||
|
{
|
||||||
|
return option<U>{ invoke(ASL_FWD(f), ASL_MOVE(value())) };
|
||||||
|
}
|
||||||
|
return option<U>{};
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename F>
|
||||||
|
constexpr option or_else(F&& f) const&
|
||||||
|
requires is_same<un_cvref_t<result_of_t<F()>>, option>
|
||||||
|
{
|
||||||
|
return has_value() ? *this : invoke(ASL_FWD(f));
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename F>
|
||||||
|
constexpr option or_else(F&& f) &&
|
||||||
|
requires is_same<un_cvref_t<result_of_t<F()>>, option>
|
||||||
|
{
|
||||||
|
return has_value() ? ASL_MOVE(*this) : invoke(ASL_FWD(f));
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
|
@ -241,3 +241,38 @@ ASL_TEST(and_then)
|
|||||||
static_assert(asl::is_same<decltype(b2), asl::option<float>>);
|
static_assert(asl::is_same<decltype(b2), asl::option<float>>);
|
||||||
ASL_TEST_ASSERT(!b2.has_value());
|
ASL_TEST_ASSERT(!b2.has_value());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ASL_TEST(transform)
|
||||||
|
{
|
||||||
|
asl::option<int> a = 5;
|
||||||
|
asl::option<int> b;
|
||||||
|
|
||||||
|
auto fn = [](int x) -> float { return static_cast<float>(x) + 0.5F; };
|
||||||
|
|
||||||
|
auto a2 = a.transform(fn);
|
||||||
|
static_assert(asl::is_same<decltype(a2), asl::option<float>>);
|
||||||
|
ASL_TEST_ASSERT(a2.has_value());
|
||||||
|
ASL_TEST_EXPECT(a2.value() == 5.5F);
|
||||||
|
|
||||||
|
auto b2 = b.transform(fn);
|
||||||
|
static_assert(asl::is_same<decltype(b2), asl::option<float>>);
|
||||||
|
ASL_TEST_ASSERT(!b2.has_value());
|
||||||
|
}
|
||||||
|
|
||||||
|
ASL_TEST(or_else)
|
||||||
|
{
|
||||||
|
asl::option<int> a = 5;
|
||||||
|
asl::option<int> b;
|
||||||
|
|
||||||
|
auto fn = []() -> asl::option<int> { return 12; };
|
||||||
|
|
||||||
|
auto a2 = a.or_else(fn);
|
||||||
|
static_assert(asl::is_same<decltype(a2), asl::option<int>>);
|
||||||
|
ASL_TEST_ASSERT(a2.has_value());
|
||||||
|
ASL_TEST_EXPECT(a2.value() == 5);
|
||||||
|
|
||||||
|
auto b2 = b.or_else(fn);
|
||||||
|
static_assert(asl::is_same<decltype(b2), asl::option<int>>);
|
||||||
|
ASL_TEST_ASSERT(b2.has_value());
|
||||||
|
ASL_TEST_EXPECT(b2.value() == 12);
|
||||||
|
}
|
||||||
|
Reference in New Issue
Block a user