Commit 04a6beac authored by Frank Liberato's avatar Frank Liberato Committed by Commit Bot

Rename media::ErrorOr to media::StatusOr.

Also adds StatusOr::code() as a convenience.

Change-Id: Id54fc2f2657b0589bad5b910b78022ac8cfef502
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2523541
Auto-Submit: Frank Liberato <liberato@chromium.org>
Reviewed-by: default avatarTed Meyer <tmathmeyer@chromium.org>
Reviewed-by: default avatarXiaohan Wang <xhwang@chromium.org>
Commit-Queue: Frank Liberato <liberato@chromium.org>
Cr-Commit-Position: refs/heads/master@{#825545}
parent 221a810e
......@@ -152,9 +152,14 @@ MEDIA_EXPORT Status OkStatus();
// TODO(liberato): Add more helper functions for common error returns.
// Helper class to allow returning a |T| or a Status. Typical usage:
// Helper class to allow returning a `T` or a Status.
//
// ErrorOr<std::unique_ptr<MyObject>> FactoryFn() {
// It is not okay to send a StatusOr with a status code of `kOk`. `kOk` is
// reserved for cases where there is a `T` rather than a Status.
//
// Typical usage:
//
// StatusOr<std::unique_ptr<MyObject>> FactoryFn() {
// if (success)
// return std::make_unique<MyObject>();
// return Status(StatusCodes::kSomethingBadHappened);
......@@ -164,12 +169,24 @@ MEDIA_EXPORT Status OkStatus();
// if (result.has_error()) return std::move(result.error());
// my_object_ = std::move(result.value());
//
// Can also be combined into a single switch using `code()`:
//
// switch (result.code()) {
// case StatusCode::kOk:
// // `kOk` is special; it means the StatusOr has a `T`.
// // Do something with result.value()
// break;
// // Maybe switch on specific non-kOk codes for special processing.
// default: // Send unknown errors upwards.
// return std::move(result.error());
// }
//
// Also useful if one would like to get an enum class return value, unless an
// error occurs:
//
// enum class ResultType { kNeedMoreInput, kOutputIsReady, kFormatChanged };
//
// ErrorOr<ResultType> Foo() { ... }
// StatusOr<ResultType> Foo() { ... }
//
// auto result = Foo();
// if (result.has_error()) return std::move(result.error());
......@@ -178,26 +195,32 @@ MEDIA_EXPORT Status OkStatus();
// ...
// }
template <typename T>
class ErrorOr {
class StatusOr {
public:
// All of these may be implicit, so that one may just return Status or
// the value in question.
ErrorOr(Status&& error) : error_(std::move(error)) {}
ErrorOr(const Status& error) : error_(error) {}
ErrorOr(StatusCode code,
const base::Location& location = base::Location::Current())
: error_(Status(code, "", location)) {}
StatusOr(Status&& error) : error_(std::move(error)) {
DCHECK(!this->error().is_ok());
}
StatusOr(const Status& error) : error_(error) {
DCHECK(!this->error().is_ok());
}
StatusOr(StatusCode code,
const base::Location& location = base::Location::Current())
: error_(Status(code, "", location)) {
DCHECK(!error().is_ok());
}
ErrorOr(T&& value) : value_(std::move(value)) {}
ErrorOr(const T& value) : value_(value) {}
StatusOr(T&& value) : value_(std::move(value)) {}
StatusOr(const T& value) : value_(value) {}
~ErrorOr() = default;
~StatusOr() = default;
// Move- and copy- construction and assignment are okay.
ErrorOr(const ErrorOr&) = default;
ErrorOr(ErrorOr&&) = default;
ErrorOr& operator=(ErrorOr&) = default;
ErrorOr& operator=(ErrorOr&&) = default;
StatusOr(const StatusOr&) = default;
StatusOr(StatusOr&&) = default;
StatusOr& operator=(StatusOr&) = default;
StatusOr& operator=(StatusOr&&) = default;
// Do we have a value?
bool has_value() const { return value_.has_value(); }
......@@ -209,10 +232,18 @@ class ErrorOr {
// have one via |!has_value()|.
Status& error() { return *error_; }
const Status& error() const { return *error_; }
// Return a ref to the value. It's up to the caller to verify that we have a
// value before calling this.
T& value() { return std::get<0>(*value_); }
// Returns the error code we have, if any, or `kOk` if we have a value. If
// this returns `kOk`, then it is equivalent to has_value().
StatusCode code() const {
return has_error() ? error().code() : StatusCode::kOk;
}
private:
base::Optional<Status> error_;
// We wrap |T| in a container so that windows COM wrappers work. They
......
......@@ -65,8 +65,8 @@ class StatusTest : public testing::Test {
return me;
}
// Make sure that the typical usage of ErrorOr actually compiles.
ErrorOr<std::unique_ptr<int>> TypicalErrorOrUsage(bool succeed) {
// Make sure that the typical usage of StatusOr actually compiles.
StatusOr<std::unique_ptr<int>> TypicalStatusOrUsage(bool succeed) {
if (succeed)
return std::make_unique<int>(123);
return Status(StatusCode::kCodeOnlyForTesting);
......@@ -192,16 +192,16 @@ TEST_F(StatusTest, CanCopyEasily) {
ASSERT_EQ(actual.FindDictPath("data")->DictSize(), 1ul);
}
TEST_F(StatusTest, ErrorOrTypicalUsage) {
TEST_F(StatusTest, StatusOrTypicalUsage) {
// Mostly so we have some code coverage on the default usage.
EXPECT_TRUE(TypicalErrorOrUsage(true).has_value());
EXPECT_FALSE(TypicalErrorOrUsage(true).has_error());
EXPECT_FALSE(TypicalErrorOrUsage(false).has_value());
EXPECT_TRUE(TypicalErrorOrUsage(false).has_error());
EXPECT_TRUE(TypicalStatusOrUsage(true).has_value());
EXPECT_FALSE(TypicalStatusOrUsage(true).has_error());
EXPECT_FALSE(TypicalStatusOrUsage(false).has_value());
EXPECT_TRUE(TypicalStatusOrUsage(false).has_error());
}
TEST_F(StatusTest, ErrorOrWithMoveOnlyType) {
ErrorOr<std::unique_ptr<int>> error_or(std::make_unique<int>(123));
TEST_F(StatusTest, StatusOrWithMoveOnlyType) {
StatusOr<std::unique_ptr<int>> error_or(std::make_unique<int>(123));
EXPECT_TRUE(error_or.has_value());
EXPECT_FALSE(error_or.has_error());
std::unique_ptr<int> result = std::move(error_or.value());
......@@ -210,8 +210,8 @@ TEST_F(StatusTest, ErrorOrWithMoveOnlyType) {
EXPECT_EQ(*result, 123);
}
TEST_F(StatusTest, ErrorOrWithCopyableType) {
ErrorOr<int> error_or(123);
TEST_F(StatusTest, StatusOrWithCopyableType) {
StatusOr<int> error_or(123);
EXPECT_TRUE(error_or.has_value());
EXPECT_FALSE(error_or.has_error());
int result = std::move(error_or.value());
......@@ -220,14 +220,14 @@ TEST_F(StatusTest, ErrorOrWithCopyableType) {
EXPECT_EQ(error_or.value(), 123);
}
TEST_F(StatusTest, ErrorOrMoveConstructionAndAssignment) {
TEST_F(StatusTest, StatusOrMoveConstructionAndAssignment) {
// Make sure that we can move-construct and move-assign a move-only value.
ErrorOr<std::unique_ptr<int>> error_or_0(std::make_unique<int>(123));
StatusOr<std::unique_ptr<int>> error_or_0(std::make_unique<int>(123));
ErrorOr<std::unique_ptr<int>> error_or_1(std::move(error_or_0));
StatusOr<std::unique_ptr<int>> error_or_1(std::move(error_or_0));
EXPECT_EQ(error_or_0.value(), nullptr);
ErrorOr<std::unique_ptr<int>> error_or_2 = std::move(error_or_1);
StatusOr<std::unique_ptr<int>> error_or_2 = std::move(error_or_1);
EXPECT_EQ(error_or_1.value(), nullptr);
// |error_or_2| should have gotten the original.
......@@ -235,12 +235,22 @@ TEST_F(StatusTest, ErrorOrMoveConstructionAndAssignment) {
EXPECT_EQ(*value, 123);
}
TEST_F(StatusTest, ErrorOrCopyWorks) {
TEST_F(StatusTest, StatusOrCopyWorks) {
// Make sure that we can move-construct and move-assign a move-only value.
ErrorOr<int> error_or_0(123);
ErrorOr<int> error_or_1(std::move(error_or_0));
ErrorOr<int> error_or_2 = std::move(error_or_1);
StatusOr<int> error_or_0(123);
StatusOr<int> error_or_1(std::move(error_or_0));
StatusOr<int> error_or_2 = std::move(error_or_1);
EXPECT_EQ(error_or_2.value(), 123);
}
TEST_F(StatusTest, StatusOrCodeIsOkWithValue) {
StatusOr<int> error_or(123);
EXPECT_EQ(error_or.code(), StatusCode::kOk);
}
TEST_F(StatusTest, StatusOrCodeIsNotOkWithoutValue) {
StatusOr<int> error_or(StatusCode::kCodeOnlyForTesting);
EXPECT_EQ(error_or.code(), StatusCode::kCodeOnlyForTesting);
}
} // namespace media
......@@ -73,7 +73,7 @@ bool D3D11DecoderConfigurator::SupportsDevice(
return false;
}
ErrorOr<ComD3D11Texture2D> D3D11DecoderConfigurator::CreateOutputTexture(
StatusOr<ComD3D11Texture2D> D3D11DecoderConfigurator::CreateOutputTexture(
ComD3D11Device device,
gfx::Size size,
uint32_t array_size) {
......
......@@ -41,9 +41,9 @@ class MEDIA_GPU_EXPORT D3D11DecoderConfigurator {
bool SupportsDevice(ComD3D11VideoDevice video_device);
// Create the decoder's output texture.
ErrorOr<ComD3D11Texture2D> CreateOutputTexture(ComD3D11Device device,
gfx::Size size,
uint32_t array_size);
StatusOr<ComD3D11Texture2D> CreateOutputTexture(ComD3D11Device device,
gfx::Size size,
uint32_t array_size);
const D3D11_VIDEO_DECODER_DESC* DecoderDescriptor() const {
return &decoder_desc_;
......
......@@ -187,7 +187,7 @@ HRESULT D3D11VideoDecoder::InitializeAcceleratedDecoder(
return hr;
}
ErrorOr<std::tuple<ComD3D11VideoDecoder>>
StatusOr<std::tuple<ComD3D11VideoDecoder>>
D3D11VideoDecoder::CreateD3D11Decoder() {
HRESULT hr;
......
......@@ -143,10 +143,10 @@ class MEDIA_GPU_EXPORT D3D11VideoDecoder : public VideoDecoder,
void CreatePictureBuffers();
// Create a D3D11VideoDecoder, if possible, based on the current config.
// TODO(liberato): we use a tuple only because ErrorOr<ComD3D111VideoDecoder>
// TODO(liberato): we use a tuple only because StatusOr<ComD3D111VideoDecoder>
// doesn't work. Something about base::Optional trying to convert to void*,
// but the conversion is ambiguous.
ErrorOr<std::tuple<ComD3D11VideoDecoder>> CreateD3D11Decoder();
StatusOr<std::tuple<ComD3D11VideoDecoder>> CreateD3D11Decoder();
enum class NotSupportedReason {
kVideoIsSupported = 0,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment