libbase: Add `expected<T, E>::operator bool`
This is a standard API helpful for this construct:
if (const auto expected = getExpected())
Bug: 185536303
Test: libbase_test
Change-Id: If73b9e4b6de18d0c2763b560443c8ef3a94b3519
diff --git a/expected_test.cpp b/expected_test.cpp
index 47e396a..d35cdee 100644
--- a/expected_test.cpp
+++ b/expected_test.cpp
@@ -812,7 +812,7 @@
}
TEST(Expected, testConstexpr) {
- // Compliation error will occur if these expressions can't be
+ // Compilation error will occur if these expressions can't be
// evaluated at compile time
constexpr exp_int e(3);
constexpr exp_int::unexpected_type err(3);
@@ -828,11 +828,13 @@
static_assert(exp_int(i).value() == 4);
// copy construct from unexpected
static_assert(exp_int(err).error() == 3);
- // move costruct from unexpected
+ // move construct from unexpected
static_assert(exp_int(unexpected(3)).error() == 3);
// observers
static_assert(*exp_int(3) == 3);
static_assert(exp_int(3).has_value() == true);
+ static_assert(static_cast<bool>(exp_int(3)));
+ static_assert(!static_cast<bool>(exp_int(err)));
static_assert(exp_int(3).value_or(4) == 3);
typedef expected<const char*, int> exp_s;
diff --git a/include/android-base/expected.h b/include/android-base/expected.h
index 3b9d45f..f9c03cf 100644
--- a/include/android-base/expected.h
+++ b/include/android-base/expected.h
@@ -253,7 +253,7 @@
~expected() = default;
// assignment
- // Note: SFNAIE doesn't work here because assignment operator should be
+ // Note: SFINAE doesn't work here because assignment operator should be
// non-template. We could workaround this by defining a templated parent class
// having the assignment operator. This incomplete implementation however
// doesn't allow us to copy assign expected<T,E> even when T is non-copy
@@ -261,7 +261,7 @@
// anyway though the error message won't be clear.
expected& operator=(const expected& rhs) = default;
- // Note for SFNAIE above applies to here as well
+ // Note for SFINAE above applies to here as well
expected& operator=(expected&& rhs) noexcept(
std::is_nothrow_move_assignable_v<T>&& std::is_nothrow_move_assignable_v<E>) = default;
@@ -332,6 +332,7 @@
constexpr bool has_value() const noexcept { return var_.index() == 0; }
constexpr bool ok() const noexcept { return has_value(); }
+ constexpr explicit operator bool() const noexcept { return has_value(); }
constexpr const T& value() const& { return std::get<T>(var_); }
constexpr T& value() & { return std::get<T>(var_); }
@@ -517,7 +518,7 @@
~expected() = default;
// assignment
- // Note: SFNAIE doesn't work here because assignment operator should be
+ // Note: SFINAE doesn't work here because assignment operator should be
// non-template. We could workaround this by defining a templated parent class
// having the assignment operator. This incomplete implementation however
// doesn't allow us to copy assign expected<T,E> even when T is non-copy
@@ -525,7 +526,7 @@
// anyway though the error message won't be clear.
expected& operator=(const expected& rhs) = default;
- // Note for SFNAIE above applies to here as well
+ // Note for SFINAE above applies to here as well
expected& operator=(expected&& rhs) noexcept(std::is_nothrow_move_assignable_v<E>) = default;
template<class G = E>
@@ -559,6 +560,7 @@
// observers
constexpr bool has_value() const noexcept { return var_.index() == 0; }
constexpr bool ok() const noexcept { return has_value(); }
+ constexpr explicit operator bool() const noexcept { return has_value(); }
constexpr void value() const& { if (!has_value()) std::get<0>(var_); }