From f79dbadc09255c91b9163449dfa8898a8be29744 Mon Sep 17 00:00:00 2001 From: terelius Date: Fri, 16 Jun 2017 06:48:13 -0700 Subject: [PATCH] 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} --- webrtc/base/optional.h | 9 +++++++ webrtc/base/optional_unittest.cc | 40 ++++++++++++++++++++++++++++---- 2 files changed, 45 insertions(+), 4 deletions(-) diff --git a/webrtc/base/optional.h b/webrtc/base/optional.h index c8ed069d55..4f883a8862 100644 --- a/webrtc/base/optional.h +++ b/webrtc/base/optional.h @@ -218,6 +218,7 @@ class Optional final { // 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 @@ class Optional final { 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 cc9d2f9164..1303552ff4 100644 --- a/webrtc/base/optional_unittest.cc +++ b/webrtc/base/optional_unittest.cc @@ -156,6 +156,7 @@ TEST(OptionalTest, TestConstructDefault) { { Optional x; EXPECT_FALSE(x); + EXPECT_FALSE(x.has_value()); } EXPECT_EQ(V(), *log); } @@ -165,8 +166,10 @@ TEST(OptionalTest, TestConstructCopyEmpty) { { Optional 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 @@ TEST(OptionalTest, TestConstructCopyFull) { Logger a; Optional 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 @@ TEST(OptionalTest, TestConstructMoveEmpty) { { Optional 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 @@ TEST(OptionalTest, TestConstructMoveFull) { { Optional 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 @@ TEST(OptionalTest, TestDereference) { (*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) {