Skip to content

Commit 087cd3a

Browse files
committed
Add Result::unwrap_or_default
1 parent d9af868 commit 087cd3a

File tree

2 files changed

+47
-0
lines changed

2 files changed

+47
-0
lines changed

subspace/result/result.h

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -666,6 +666,28 @@ class [[nodiscard]] Result final {
666666
}
667667
}
668668

669+
/// Returns the contained Ok value or a default.
670+
///
671+
/// Consumes the Result and, if it held an Ok value, the value is returned.
672+
/// Otherwise the default value of the Ok value's type is returned.
673+
constexpr T unwrap_or_default() && noexcept
674+
requires(!std::is_reference_v<T> &&
675+
(std::is_void_v<T> || ::sus::construct::Default<T>))
676+
{
677+
ResultState was = ::sus::mem::replace(mref(state_), ResultState::IsMoved);
678+
check_with_message(
679+
was != ResultState::IsMoved,
680+
*"called `Result::unwrap_or_default()` on a moved Result");
681+
if constexpr (!std::is_void_v<T>) {
682+
if (was == ResultState::IsOk) {
683+
return ::sus::mem::take_and_destruct(::sus::marker::unsafe_fn,
684+
mref(storage_.ok_));
685+
} else {
686+
return T();
687+
}
688+
}
689+
}
690+
669691
/// Returns the contained `Ok` value, consuming the self value, without
670692
/// checking that the value is not an `Err`.
671693
///

subspace/result/result_unittest.cc

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -572,6 +572,31 @@ TEST(Result, Unwrap) {
572572
EXPECT_EQ(&cu, &m);
573573
}
574574

575+
TEST(Result, UnwrapOrDefault) {
576+
{
577+
constexpr auto a = Result<i32, Error>::with(3_i32).unwrap_or_default();
578+
static_assert(std::same_as<decltype(a), const i32>);
579+
EXPECT_EQ(a, 3_i32);
580+
581+
constexpr auto d =
582+
Result<i32, Error>::with_err(Error()).unwrap_or_default();
583+
static_assert(std::same_as<decltype(d), const i32>);
584+
EXPECT_EQ(d, 0_i32);
585+
}
586+
{
587+
// Returns void, doesn't panic.
588+
Result<void, Error>::with().unwrap_or_default();
589+
static_assert(
590+
std::same_as<decltype(Result<void, Error>::with().unwrap_or_default()),
591+
void>);
592+
// Returns void, doesn't panic.
593+
Result<void, Error>::with_err(Error()).unwrap_or_default();
594+
static_assert(
595+
std::same_as<decltype(Result<void, Error>::with().unwrap_or_default()),
596+
void>);
597+
}
598+
}
599+
575600
TEST(ResultDeathTest, UnwrapWithErr) {
576601
#if GTEST_HAS_DEATH_TEST
577602
auto r = Result<i32, Error>::with_err(Error());

0 commit comments

Comments
 (0)