Add has_value() and value() methods to rtc::Optional.
These methods have the same behavior as their counterparts in std::optional, except that rtc::Optional::value() requires that the value exists whereas std::optional::value() throws an exception.
BUG=webrtc:7843
Review-Url: https://codereview.webrtc.org/2942203002
Cr-Commit-Position: refs/heads/master@{#18631}
diff --git a/webrtc/base/optional.h b/webrtc/base/optional.h
index c8ed069..4f883a8 100644
--- a/webrtc/base/optional.h
+++ b/webrtc/base/optional.h
@@ -218,6 +218,7 @@
// Conversion to bool to test if we have a value.
explicit operator bool() const { return has_value_; }
+ bool has_value() const { return has_value_; }
// Dereferencing. Only allowed if we have a value.
const T* operator->() const {
@@ -236,6 +237,14 @@
RTC_DCHECK(has_value_);
return value_;
}
+ const T& value() const {
+ RTC_DCHECK(has_value_);
+ return value_;
+ }
+ T& value() {
+ RTC_DCHECK(has_value_);
+ return value_;
+ }
// Dereference with a default value in case we don't have a value.
const T& value_or(const T& default_val) const {
diff --git a/webrtc/base/optional_unittest.cc b/webrtc/base/optional_unittest.cc
index cc9d2f9..1303552 100644
--- a/webrtc/base/optional_unittest.cc
+++ b/webrtc/base/optional_unittest.cc
@@ -156,6 +156,7 @@
{
Optional<Logger> x;
EXPECT_FALSE(x);
+ EXPECT_FALSE(x.has_value());
}
EXPECT_EQ(V(), *log);
}
@@ -165,8 +166,10 @@
{
Optional<Logger> x;
EXPECT_FALSE(x);
+ EXPECT_FALSE(x.has_value());
auto y = x;
EXPECT_FALSE(y);
+ EXPECT_FALSE(y.has_value());
}
EXPECT_EQ(V(), *log);
}
@@ -177,9 +180,11 @@
Logger a;
Optional<Logger> x(a);
EXPECT_TRUE(x);
+ EXPECT_TRUE(x.has_value());
log->push_back("---");
auto y = x;
EXPECT_TRUE(y);
+ EXPECT_TRUE(y.has_value());
log->push_back("---");
}
EXPECT_EQ(V("0:0. default constructor", "1:0. copy constructor (from 0:0)",
@@ -193,8 +198,10 @@
{
Optional<Logger> x;
EXPECT_FALSE(x);
+ EXPECT_FALSE(x.has_value());
auto y = std::move(x);
EXPECT_FALSE(y);
+ EXPECT_FALSE(y.has_value());
}
EXPECT_EQ(V(), *log);
}
@@ -204,10 +211,13 @@
{
Optional<Logger> x(Logger(17));
EXPECT_TRUE(x);
+ EXPECT_TRUE(x.has_value());
log->push_back("---");
auto y = std::move(x);
EXPECT_TRUE(x);
+ EXPECT_TRUE(x.has_value());
EXPECT_TRUE(y);
+ EXPECT_TRUE(y.has_value());
log->push_back("---");
}
EXPECT_EQ(
@@ -621,13 +631,35 @@
(*std::move(x)).Foo();
(*std::move(y)).Foo();
log->push_back("---");
+ x.value().Foo();
+ y.value().Foo();
+ std::move(x).value().Foo();
+ std::move(y).value().Foo();
+ log->push_back("---");
}
+ // clang-format off
EXPECT_EQ(V("0:42. explicit constructor",
- "1:42. move constructor (from 0:42)", "0:42. destructor", "---",
- "1:42. Foo()", "1:42. Foo() const", "1:42. Foo()",
- "1:42. Foo() const", "---", "1:42. Foo()", "1:42. Foo() const",
- "1:42. Foo()", "1:42. Foo() const", "---", "1:42. destructor"),
+ "1:42. move constructor (from 0:42)",
+ "0:42. destructor",
+ "---",
+ "1:42. Foo()",
+ "1:42. Foo() const",
+ "1:42. Foo()",
+ "1:42. Foo() const",
+ "---",
+ "1:42. Foo()",
+ "1:42. Foo() const",
+ "1:42. Foo()",
+ "1:42. Foo() const",
+ "---",
+ "1:42. Foo()",
+ "1:42. Foo() const",
+ "1:42. Foo()",
+ "1:42. Foo() const",
+ "---",
+ "1:42. destructor"),
*log);
+ // clang-format on
}
TEST(OptionalTest, TestDereferenceWithDefault) {