From c6a4aa13c256a65123355636d30f4a7b38c4fccf Mon Sep 17 00:00:00 2001 From: Steven Le Rouzic Date: Sat, 2 Nov 2024 20:18:32 +0100 Subject: Add option::transform and option::or_else --- asl/option.hpp | 47 ++++++++++++++++++++++++++++++++++++++++++++++ asl/tests/option_tests.cpp | 35 ++++++++++++++++++++++++++++++++++ 2 files changed, 82 insertions(+) (limited to 'asl') 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>{}; } + + template + constexpr auto transform(F&& f) & + { + using U = un_cvref_t>; + if (has_value()) + { + return option{ invoke(ASL_FWD(f), value()) }; + } + return option{}; + } + + template + constexpr auto transform(F&& f) const& + { + using U = un_cvref_t>; + if (has_value()) + { + return option{ invoke(ASL_FWD(f), value()) }; + } + return option{}; + } + + template + constexpr auto transform(F&& f) && + { + using U = un_cvref_t>; + if (has_value()) + { + return option{ invoke(ASL_FWD(f), ASL_MOVE(value())) }; + } + return option{}; + } + + template + constexpr option or_else(F&& f) const& + requires is_same>, option> + { + return has_value() ? *this : invoke(ASL_FWD(f)); + } + + template + constexpr option or_else(F&& f) && + requires is_same>, option> + { + return has_value() ? ASL_MOVE(*this) : invoke(ASL_FWD(f)); + } }; template 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>); ASL_TEST_ASSERT(!b2.has_value()); } + +ASL_TEST(transform) +{ + asl::option a = 5; + asl::option b; + + auto fn = [](int x) -> float { return static_cast(x) + 0.5F; }; + + auto a2 = a.transform(fn); + static_assert(asl::is_same>); + ASL_TEST_ASSERT(a2.has_value()); + ASL_TEST_EXPECT(a2.value() == 5.5F); + + auto b2 = b.transform(fn); + static_assert(asl::is_same>); + ASL_TEST_ASSERT(!b2.has_value()); +} + +ASL_TEST(or_else) +{ + asl::option a = 5; + asl::option b; + + auto fn = []() -> asl::option { return 12; }; + + auto a2 = a.or_else(fn); + static_assert(asl::is_same>); + ASL_TEST_ASSERT(a2.has_value()); + ASL_TEST_EXPECT(a2.value() == 5); + + auto b2 = b.or_else(fn); + static_assert(asl::is_same>); + ASL_TEST_ASSERT(b2.has_value()); + ASL_TEST_EXPECT(b2.value() == 12); +} -- cgit