diff options
author | Steven Le Rouzic <steven.lerouzic@gmail.com> | 2024-11-02 20:18:32 +0100 |
---|---|---|
committer | Steven Le Rouzic <steven.lerouzic@gmail.com> | 2024-12-20 15:35:58 +0100 |
commit | c6a4aa13c256a65123355636d30f4a7b38c4fccf (patch) | |
tree | e8153a15297aafe02616733207ea76fa79b007c6 /asl | |
parent | 7e8e2ef0be2eebc7f872ea37620dc1b60d62197f (diff) |
Add option::transform and option::or_else
Diffstat (limited to 'asl')
-rw-r--r-- | asl/option.hpp | 47 | ||||
-rw-r--r-- | asl/tests/option_tests.cpp | 35 |
2 files changed, 82 insertions, 0 deletions
diff --git a/asl/option.hpp b/asl/option.hpp index ebb9eef..0c816f4 100644 --- a/asl/option.hpp +++ b/asl/option.hpp @@ -429,6 +429,53 @@ public: }
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>
diff --git a/asl/tests/option_tests.cpp b/asl/tests/option_tests.cpp index ea20b98..12b62ae 100644 --- a/asl/tests/option_tests.cpp +++ b/asl/tests/option_tests.cpp @@ -241,3 +241,38 @@ ASL_TEST(and_then) static_assert(asl::is_same<decltype(b2), asl::option<float>>);
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);
+}
|