diff options
author | swarmer <[email protected]> | 2024-06-14 21:25:18 +0300 |
---|---|---|
committer | swarmer <[email protected]> | 2024-06-14 21:39:47 +0300 |
commit | 7d673060f61f85b3e440fa45df26795d3653c8d2 (patch) | |
tree | adfbbd425d54d2d433dc04dd8c791e4b2260d0b0 | |
parent | c5cde75c98daf20325555a404da8534e6364a5c6 (diff) |
[util] Check lifetime of the move-only type passed through the TMaybe::GetOrElse method
03109df768118daa8c95e373de082712a2362407
-rw-r--r-- | util/generic/maybe.h | 8 | ||||
-rw-r--r-- | util/generic/maybe_ut.cpp | 26 |
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> { |