summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorswarmer <[email protected]>2024-06-14 21:25:18 +0300
committerswarmer <[email protected]>2024-06-14 21:39:47 +0300
commit7d673060f61f85b3e440fa45df26795d3653c8d2 (patch)
treeadfbbd425d54d2d433dc04dd8c791e4b2260d0b0
parentc5cde75c98daf20325555a404da8534e6364a5c6 (diff)
[util] Check lifetime of the move-only type passed through the TMaybe::GetOrElse method
03109df768118daa8c95e373de082712a2362407
-rw-r--r--util/generic/maybe.h8
-rw-r--r--util/generic/maybe_ut.cpp26
2 files changed, 34 insertions, 0 deletions
diff --git a/util/generic/maybe.h b/util/generic/maybe.h
index 4b002fb8ab8..ba15c7d7e44 100644
--- a/util/generic/maybe.h
+++ b/util/generic/maybe.h
@@ -395,6 +395,10 @@ public:
return Defined() ? *Data() : elseValue;
}
+ constexpr T&& GetOrElse(T&& elseValue Y_LIFETIME_BOUND) && Y_LIFETIME_BOUND {
+ return Defined() ? std::move(*Data()) : std::move(elseValue);
+ }
+
constexpr const TMaybe& OrElse(const TMaybe& elseValue Y_LIFETIME_BOUND) const noexcept Y_LIFETIME_BOUND {
return Defined() ? *this : elseValue;
}
@@ -403,6 +407,10 @@ public:
return Defined() ? *this : elseValue;
}
+ constexpr TMaybe&& OrElse(TMaybe&& elseValue Y_LIFETIME_BOUND) && Y_LIFETIME_BOUND {
+ return Defined() ? std::move(*this) : std::move(elseValue);
+ }
+
template <typename F>
constexpr auto AndThen(F&& func) & {
using ReturnType = TCallResult<F, T&>;
diff --git a/util/generic/maybe_ut.cpp b/util/generic/maybe_ut.cpp
index a7c5407e812..84964b8e8b1 100644
--- a/util/generic/maybe_ut.cpp
+++ b/util/generic/maybe_ut.cpp
@@ -239,6 +239,32 @@ Y_UNIT_TEST_SUITE(TMaybeTest) {
}
}
+ Y_UNIT_TEST(TestGetOrElseMove) {
+ struct TData {
+ int Value = 0;
+
+ TData(int value)
+ : Value(value)
+ {
+ }
+
+ TData(TData&&) = default;
+ TData& operator=(TData&&) = default;
+ };
+
+ TData d5 = MakeMaybe(TData{5}).GetOrElse(TData{6});
+ UNIT_ASSERT_VALUES_EQUAL(d5.Value, 5);
+ TData d6 = TMaybe<TData>{}.GetOrElse(TData{6});
+ UNIT_ASSERT_VALUES_EQUAL(d6.Value, 6);
+
+ TMaybe<TData> d7 = MakeMaybe(TData{7}).OrElse(MakeMaybe(TData{8}));
+ UNIT_ASSERT_VALUES_EQUAL(d7.GetRef().Value, 7);
+ TMaybe<TData> d8 = TMaybe<TData>{}.OrElse(MakeMaybe(TData{8}));
+ UNIT_ASSERT_VALUES_EQUAL(d8.GetRef().Value, 8);
+ TMaybe<TData> d9 = TMaybe<TData>{}.OrElse(TMaybe<TData>{});
+ UNIT_ASSERT(d9.Empty());
+ }
+
Y_UNIT_TEST(TestAndThen) {
{
auto f = [](int i) -> TMaybe<int> {