aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar Michael Case <mikecase@google.com>2018-06-26 13:05:25 -0700
committerGravatar TensorFlower Gardener <gardener@tensorflow.org>2018-06-26 13:08:05 -0700
commit69a895b76736ebc7bd748218827ab452e9082d86 (patch)
tree02a57eb9c86a5a085421b7096f79f0f486ca4b27
parent623513f26579d04a1eb8a836b9d78896abfb599c (diff)
Moving StatusOr from XLA to stream_executor.
PiperOrigin-RevId: 202179928
-rw-r--r--tensorflow/compiler/xla/BUILD17
-rw-r--r--tensorflow/compiler/xla/service/gpu/BUILD1
-rw-r--r--tensorflow/compiler/xla/service/gpu/stream_executor_util.h1
-rw-r--r--tensorflow/compiler/xla/statusor.h286
-rw-r--r--tensorflow/stream_executor/BUILD2
-rw-r--r--tensorflow/stream_executor/lib/statusor.cc (renamed from tensorflow/compiler/xla/statusor.cc)8
-rw-r--r--tensorflow/stream_executor/lib/statusor.h290
-rw-r--r--tensorflow/stream_executor/lib/statusor_internals.h (renamed from tensorflow/compiler/xla/statusor_internals.h)15
-rw-r--r--tensorflow/stream_executor/lib/statusor_test.cc (renamed from tensorflow/compiler/xla/statusor_test.cc)11
9 files changed, 310 insertions, 321 deletions
diff --git a/tensorflow/compiler/xla/BUILD b/tensorflow/compiler/xla/BUILD
index 95bd725850..03e542855b 100644
--- a/tensorflow/compiler/xla/BUILD
+++ b/tensorflow/compiler/xla/BUILD
@@ -142,30 +142,15 @@ cc_library(
cc_library(
name = "statusor",
- srcs = ["statusor.cc"],
hdrs = [
"statusor.h",
- "statusor_internals.h",
],
visibility = ["//visibility:public"],
deps = [
":status",
"//tensorflow/core:lib",
"//tensorflow/core:lib_internal",
- ],
-)
-
-tf_cc_test(
- name = "statusor_test",
- size = "small",
- srcs = ["statusor_test.cc"],
- deps = [
- ":statusor",
- ":test",
- ":types",
- "//tensorflow/core:lib",
- "//tensorflow/core:test",
- "//tensorflow/core:test_main",
+ "//tensorflow/stream_executor",
],
)
diff --git a/tensorflow/compiler/xla/service/gpu/BUILD b/tensorflow/compiler/xla/service/gpu/BUILD
index 2508755e4c..88f994786a 100644
--- a/tensorflow/compiler/xla/service/gpu/BUILD
+++ b/tensorflow/compiler/xla/service/gpu/BUILD
@@ -770,6 +770,7 @@ cc_library(
hdrs = ["stream_executor_util.h"],
deps = [
"//tensorflow/compiler/xla:shape_util",
+ "//tensorflow/compiler/xla:statusor",
"//tensorflow/compiler/xla:xla_data_proto",
"//tensorflow/core:stream_executor_no_cuda",
],
diff --git a/tensorflow/compiler/xla/service/gpu/stream_executor_util.h b/tensorflow/compiler/xla/service/gpu/stream_executor_util.h
index 8218f4fd11..39a6a38d00 100644
--- a/tensorflow/compiler/xla/service/gpu/stream_executor_util.h
+++ b/tensorflow/compiler/xla/service/gpu/stream_executor_util.h
@@ -16,6 +16,7 @@ limitations under the License.
#ifndef TENSORFLOW_COMPILER_XLA_SERVICE_GPU_STREAM_EXECUTOR_UTIL_H_
#define TENSORFLOW_COMPILER_XLA_SERVICE_GPU_STREAM_EXECUTOR_UTIL_H_
+#include "tensorflow/compiler/xla/statusor.h"
#include "tensorflow/compiler/xla/xla_data.pb.h"
#include "tensorflow/core/platform/stream_executor_no_cuda.h"
diff --git a/tensorflow/compiler/xla/statusor.h b/tensorflow/compiler/xla/statusor.h
index 0e1387c939..a32e2ad985 100644
--- a/tensorflow/compiler/xla/statusor.h
+++ b/tensorflow/compiler/xla/statusor.h
@@ -12,297 +12,17 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
==============================================================================*/
-
-// StatusOr<T> is the union of a Status object and a T object. StatusOr models
-// the concept of an object that is either a value, or an error Status
-// explaining why such a value is not present. To this end, StatusOr<T> does not
-// allow its Status value to be Status::OK.
-//
-// The primary use-case for StatusOr<T> is as the return value of a
-// function which may fail.
-//
-// Example client usage for a StatusOr<T>, where T is not a pointer:
-//
-// StatusOr<float> result = DoBigCalculationThatCouldFail();
-// if (result.ok()) {
-// float answer = result.ValueOrDie();
-// printf("Big calculation yielded: %f", answer);
-// } else {
-// LOG(ERROR) << result.status();
-// }
-//
-// Example client usage for a StatusOr<T*>:
-//
-// StatusOr<Foo*> result = FooFactory::MakeNewFoo(arg);
-// if (result.ok()) {
-// std::unique_ptr<Foo> foo(result.ValueOrDie());
-// foo->DoSomethingCool();
-// } else {
-// LOG(ERROR) << result.status();
-// }
-//
-// Example client usage for a StatusOr<std::unique_ptr<T>>:
-//
-// StatusOr<std::unique_ptr<Foo>> result = FooFactory::MakeNewFoo(arg);
-// if (result.ok()) {
-// std::unique_ptr<Foo> foo = std::move(result.ValueOrDie());
-// foo->DoSomethingCool();
-// } else {
-// LOG(ERROR) << result.status();
-// }
-//
-// Example factory implementation returning StatusOr<T*>:
-//
-// StatusOr<Foo*> FooFactory::MakeNewFoo(int arg) {
-// if (arg <= 0) {
-// return tensorflow::InvalidArgument("Arg must be positive");
-// } else {
-// return new Foo(arg);
-// }
-// }
-//
-// Note that the assignment operators require that destroying the currently
-// stored value cannot invalidate the argument; in other words, the argument
-// cannot be an alias for the current value, or anything owned by the current
-// value.
#ifndef TENSORFLOW_COMPILER_XLA_STATUSOR_H_
#define TENSORFLOW_COMPILER_XLA_STATUSOR_H_
#include "tensorflow/compiler/xla/status.h"
-#include "tensorflow/compiler/xla/statusor_internals.h"
-#include "tensorflow/core/platform/macros.h"
+#include "tensorflow/stream_executor/lib/statusor.h"
namespace xla {
-#if defined(__clang__)
-// Only clang supports warn_unused_result as a type annotation.
-template <typename T>
-class TF_MUST_USE_RESULT StatusOr;
-#endif
-
-template <typename T>
-class StatusOr : private internal_statusor::StatusOrData<T>,
- private internal_statusor::TraitsBase<
- std::is_copy_constructible<T>::value,
- std::is_move_constructible<T>::value> {
- template <typename U>
- friend class StatusOr;
-
- typedef internal_statusor::StatusOrData<T> Base;
-
- public:
- typedef T element_type;
-
- // Constructs a new StatusOr with Status::UNKNOWN status. This is marked
- // 'explicit' to try to catch cases like 'return {};', where people think
- // StatusOr<std::vector<int>> will be initialized with an empty vector,
- // instead of a Status::UNKNOWN status.
- explicit StatusOr();
-
- // StatusOr<T> will be copy constructible/assignable if T is copy
- // constructible.
- StatusOr(const StatusOr&) = default;
- StatusOr& operator=(const StatusOr&) = default;
-
- // StatusOr<T> will be move constructible/assignable if T is move
- // constructible.
- StatusOr(StatusOr&&) = default;
- StatusOr& operator=(StatusOr&&) = default;
-
- // Conversion copy/move constructor, T must be convertible from U.
- template <typename U, typename std::enable_if<
- std::is_convertible<U, T>::value>::type* = nullptr>
- StatusOr(const StatusOr<U>& other);
- template <typename U, typename std::enable_if<
- std::is_convertible<U, T>::value>::type* = nullptr>
- StatusOr(StatusOr<U>&& other);
-
- // Conversion copy/move assignment operator, T must be convertible from U.
- template <typename U, typename std::enable_if<
- std::is_convertible<U, T>::value>::type* = nullptr>
- StatusOr& operator=(const StatusOr<U>& other);
- template <typename U, typename std::enable_if<
- std::is_convertible<U, T>::value>::type* = nullptr>
- StatusOr& operator=(StatusOr<U>&& other);
-
- // Constructs a new StatusOr with the given value. After calling this
- // constructor, calls to ValueOrDie() will succeed, and calls to status() will
- // return OK.
- //
- // NOTE: Not explicit - we want to use StatusOr<T> as a return type
- // so it is convenient and sensible to be able to do 'return T()'
- // when the return type is StatusOr<T>.
- //
- // REQUIRES: T is copy constructible.
- StatusOr(const T& value);
-
- // Constructs a new StatusOr with the given non-ok status. After calling
- // this constructor, calls to ValueOrDie() will CHECK-fail.
- //
- // NOTE: Not explicit - we want to use StatusOr<T> as a return
- // value, so it is convenient and sensible to be able to do 'return
- // Status()' when the return type is StatusOr<T>.
- //
- // REQUIRES: !status.ok(). This requirement is DCHECKed.
- // In optimized builds, passing Status::OK() here will have the effect
- // of passing tensorflow::error::INTERNAL as a fallback.
- StatusOr(const Status& status);
- StatusOr& operator=(const Status& status);
-
- // TODO(b/62186997): Add operator=(T) overloads.
-
- // Similar to the `const T&` overload.
- //
- // REQUIRES: T is move constructible.
- StatusOr(T&& value);
-
- // RValue versions of the operations declared above.
- StatusOr(Status&& status);
- StatusOr& operator=(Status&& status);
-
- // Returns this->status().ok()
- bool ok() const { return this->status_.ok(); }
-
- // Returns a reference to our status. If this contains a T, then
- // returns Status::OK().
- const Status& status() const &;
- Status status() &&;
-
- // Returns a reference to our current value, or CHECK-fails if !this->ok().
- //
- // Note: for value types that are cheap to copy, prefer simple code:
- //
- // T value = statusor.ValueOrDie();
- //
- // Otherwise, if the value type is expensive to copy, but can be left
- // in the StatusOr, simply assign to a reference:
- //
- // T& value = statusor.ValueOrDie(); // or `const T&`
- //
- // Otherwise, if the value type supports an efficient move, it can be
- // used as follows:
- //
- // T value = std::move(statusor).ValueOrDie();
- //
- // The std::move on statusor instead of on the whole expression enables
- // warnings about possible uses of the statusor object after the move.
- // C++ style guide waiver for ref-qualified overloads granted in cl/143176389
- // See go/ref-qualifiers for more details on such overloads.
- const T& ValueOrDie() const &;
- T& ValueOrDie() &;
- const T&& ValueOrDie() const &&;
- T&& ValueOrDie() &&;
-
- T ConsumeValueOrDie() { return std::move(ValueOrDie()); }
-
- // Ignores any errors. This method does nothing except potentially suppress
- // complaints from any tools that are checking that errors are not dropped on
- // the floor.
- void IgnoreError() const;
-};
-
-////////////////////////////////////////////////////////////////////////////////
-// Implementation details for StatusOr<T>
-
-template <typename T>
-StatusOr<T>::StatusOr() : Base(Status(tensorflow::error::UNKNOWN, "")) {}
-
-template <typename T>
-StatusOr<T>::StatusOr(const T& value) : Base(value) {}
-
-template <typename T>
-StatusOr<T>::StatusOr(const Status& status) : Base(status) {}
-
-template <typename T>
-StatusOr<T>& StatusOr<T>::operator=(const Status& status) {
- this->Assign(status);
- return *this;
-}
-
-template <typename T>
-StatusOr<T>::StatusOr(T&& value) : Base(std::move(value)) {}
-
-template <typename T>
-StatusOr<T>::StatusOr(Status&& status) : Base(std::move(status)) {}
-
-template <typename T>
-StatusOr<T>& StatusOr<T>::operator=(Status&& status) {
- this->Assign(std::move(status));
- return *this;
-}
-
-template <typename T>
-template <typename U,
- typename std::enable_if<std::is_convertible<U, T>::value>::type*>
-inline StatusOr<T>::StatusOr(const StatusOr<U>& other)
- : Base(static_cast<const typename StatusOr<U>::Base&>(other)) {}
-
-template <typename T>
-template <typename U,
- typename std::enable_if<std::is_convertible<U, T>::value>::type*>
-inline StatusOr<T>& StatusOr<T>::operator=(const StatusOr<U>& other) {
- if (other.ok())
- this->Assign(other.ValueOrDie());
- else
- this->Assign(other.status());
- return *this;
-}
-
-template <typename T>
-template <typename U,
- typename std::enable_if<std::is_convertible<U, T>::value>::type*>
-inline StatusOr<T>::StatusOr(StatusOr<U>&& other)
- : Base(static_cast<typename StatusOr<U>::Base&&>(other)) {}
-
-template <typename T>
-template <typename U,
- typename std::enable_if<std::is_convertible<U, T>::value>::type*>
-inline StatusOr<T>& StatusOr<T>::operator=(StatusOr<U>&& other) {
- if (other.ok()) {
- this->Assign(std::move(other).ValueOrDie());
- } else {
- this->Assign(std::move(other).status());
- }
- return *this;
-}
-
-template <typename T>
-const Status& StatusOr<T>::status() const & {
- return this->status_;
-}
-template <typename T>
-Status StatusOr<T>::status() && {
- return ok() ? Status::OK() : std::move(this->status_);
-}
-
-template <typename T>
-const T& StatusOr<T>::ValueOrDie() const & {
- this->EnsureOk();
- return this->data_;
-}
-
-template <typename T>
-T& StatusOr<T>::ValueOrDie() & {
- this->EnsureOk();
- return this->data_;
-}
-
-template <typename T>
-const T&& StatusOr<T>::ValueOrDie() const && {
- this->EnsureOk();
- return std::move(this->data_);
-}
-
-template <typename T>
-T&& StatusOr<T>::ValueOrDie() && {
- this->EnsureOk();
- return std::move(this->data_);
-}
-
+// Use steam_executor's StatusOr so we don't duplicate code.
template <typename T>
-void StatusOr<T>::IgnoreError() const {
- // no-op
-}
+using StatusOr = ::stream_executor::port::StatusOr<T>;
} // namespace xla
diff --git a/tensorflow/stream_executor/BUILD b/tensorflow/stream_executor/BUILD
index c68cda0100..21295abed1 100644
--- a/tensorflow/stream_executor/BUILD
+++ b/tensorflow/stream_executor/BUILD
@@ -33,7 +33,6 @@ cc_library(
}),
visibility = ["//visibility:public"],
deps = [
- "//tensorflow/compiler/xla:statusor",
"//tensorflow/core:lib",
"//tensorflow/core:ptr_util",
"@local_config_cuda//cuda:cuda_headers",
@@ -48,7 +47,6 @@ cc_library(
deps = [
"//tensorflow/core:lib",
"//tensorflow/core:ptr_util",
- "//tensorflow/compiler/xla:statusor",
"@local_config_cuda//cuda:cuda_headers",
] + if_static([":stream_executor_impl"]),
)
diff --git a/tensorflow/compiler/xla/statusor.cc b/tensorflow/stream_executor/lib/statusor.cc
index 72ab67ff81..e0e851f96e 100644
--- a/tensorflow/compiler/xla/statusor.cc
+++ b/tensorflow/stream_executor/lib/statusor.cc
@@ -13,12 +13,13 @@ See the License for the specific language governing permissions and
limitations under the License.
==============================================================================*/
-#include "tensorflow/compiler/xla/statusor.h"
+#include "tensorflow/stream_executor/lib/statusor.h"
#include "tensorflow/core/lib/core/errors.h"
#include "tensorflow/core/platform/logging.h"
-namespace xla {
+namespace stream_executor {
+namespace port {
namespace internal_statusor {
void Helper::HandleInvalidStatusCtorArg(Status* status) {
@@ -35,4 +36,5 @@ void Helper::Crash(const Status& status) {
}
} // namespace internal_statusor
-} // namespace xla
+} // namespace port
+} // namespace stream_executor
diff --git a/tensorflow/stream_executor/lib/statusor.h b/tensorflow/stream_executor/lib/statusor.h
index dab5909674..3c716acb46 100644
--- a/tensorflow/stream_executor/lib/statusor.h
+++ b/tensorflow/stream_executor/lib/statusor.h
@@ -1,4 +1,4 @@
-/* Copyright 2015 The TensorFlow Authors. All Rights Reserved.
+/* Copyright 2017 The TensorFlow Authors. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -13,19 +13,297 @@ See the License for the specific language governing permissions and
limitations under the License.
==============================================================================*/
-// IWYU pragma: private, include "third_party/tensorflow/stream_executor/stream_executor.h"
-
+// StatusOr<T> is the union of a Status object and a T object. StatusOr models
+// the concept of an object that is either a value, or an error Status
+// explaining why such a value is not present. To this end, StatusOr<T> does not
+// allow its Status value to be Status::OK.
+//
+// The primary use-case for StatusOr<T> is as the return value of a
+// function which may fail.
+//
+// Example client usage for a StatusOr<T>, where T is not a pointer:
+//
+// StatusOr<float> result = DoBigCalculationThatCouldFail();
+// if (result.ok()) {
+// float answer = result.ValueOrDie();
+// printf("Big calculation yielded: %f", answer);
+// } else {
+// LOG(ERROR) << result.status();
+// }
+//
+// Example client usage for a StatusOr<T*>:
+//
+// StatusOr<Foo*> result = FooFactory::MakeNewFoo(arg);
+// if (result.ok()) {
+// std::unique_ptr<Foo> foo(result.ValueOrDie());
+// foo->DoSomethingCool();
+// } else {
+// LOG(ERROR) << result.status();
+// }
+//
+// Example client usage for a StatusOr<std::unique_ptr<T>>:
+//
+// StatusOr<std::unique_ptr<Foo>> result = FooFactory::MakeNewFoo(arg);
+// if (result.ok()) {
+// std::unique_ptr<Foo> foo = std::move(result.ValueOrDie());
+// foo->DoSomethingCool();
+// } else {
+// LOG(ERROR) << result.status();
+// }
+//
+// Example factory implementation returning StatusOr<T*>:
+//
+// StatusOr<Foo*> FooFactory::MakeNewFoo(int arg) {
+// if (arg <= 0) {
+// return tensorflow::InvalidArgument("Arg must be positive");
+// } else {
+// return new Foo(arg);
+// }
+// }
+//
+// Note that the assignment operators require that destroying the currently
+// stored value cannot invalidate the argument; in other words, the argument
+// cannot be an alias for the current value, or anything owned by the current
+// value.
#ifndef TENSORFLOW_STREAM_EXECUTOR_LIB_STATUSOR_H_
#define TENSORFLOW_STREAM_EXECUTOR_LIB_STATUSOR_H_
-#include "tensorflow/compiler/xla/statusor.h"
+#include "tensorflow/core/platform/macros.h"
+#include "tensorflow/stream_executor/lib/status.h"
+#include "tensorflow/stream_executor/lib/statusor_internals.h"
namespace stream_executor {
namespace port {
-// Use XLA's StatusOr so we don't duplicate code.
+#if defined(__clang__)
+// Only clang supports warn_unused_result as a type annotation.
+template <typename T>
+class TF_MUST_USE_RESULT StatusOr;
+#endif
+
+template <typename T>
+class StatusOr : private internal_statusor::StatusOrData<T>,
+ private internal_statusor::TraitsBase<
+ std::is_copy_constructible<T>::value,
+ std::is_move_constructible<T>::value> {
+ template <typename U>
+ friend class StatusOr;
+
+ typedef internal_statusor::StatusOrData<T> Base;
+
+ public:
+ typedef T element_type;
+
+ // Constructs a new StatusOr with Status::UNKNOWN status. This is marked
+ // 'explicit' to try to catch cases like 'return {};', where people think
+ // StatusOr<std::vector<int>> will be initialized with an empty vector,
+ // instead of a Status::UNKNOWN status.
+ explicit StatusOr();
+
+ // StatusOr<T> will be copy constructible/assignable if T is copy
+ // constructible.
+ StatusOr(const StatusOr&) = default;
+ StatusOr& operator=(const StatusOr&) = default;
+
+ // StatusOr<T> will be move constructible/assignable if T is move
+ // constructible.
+ StatusOr(StatusOr&&) = default;
+ StatusOr& operator=(StatusOr&&) = default;
+
+ // Conversion copy/move constructor, T must be convertible from U.
+ template <typename U, typename std::enable_if<
+ std::is_convertible<U, T>::value>::type* = nullptr>
+ StatusOr(const StatusOr<U>& other);
+ template <typename U, typename std::enable_if<
+ std::is_convertible<U, T>::value>::type* = nullptr>
+ StatusOr(StatusOr<U>&& other);
+
+ // Conversion copy/move assignment operator, T must be convertible from U.
+ template <typename U, typename std::enable_if<
+ std::is_convertible<U, T>::value>::type* = nullptr>
+ StatusOr& operator=(const StatusOr<U>& other);
+ template <typename U, typename std::enable_if<
+ std::is_convertible<U, T>::value>::type* = nullptr>
+ StatusOr& operator=(StatusOr<U>&& other);
+
+ // Constructs a new StatusOr with the given value. After calling this
+ // constructor, calls to ValueOrDie() will succeed, and calls to status() will
+ // return OK.
+ //
+ // NOTE: Not explicit - we want to use StatusOr<T> as a return type
+ // so it is convenient and sensible to be able to do 'return T()'
+ // when the return type is StatusOr<T>.
+ //
+ // REQUIRES: T is copy constructible.
+ StatusOr(const T& value);
+
+ // Constructs a new StatusOr with the given non-ok status. After calling
+ // this constructor, calls to ValueOrDie() will CHECK-fail.
+ //
+ // NOTE: Not explicit - we want to use StatusOr<T> as a return
+ // value, so it is convenient and sensible to be able to do 'return
+ // Status()' when the return type is StatusOr<T>.
+ //
+ // REQUIRES: !status.ok(). This requirement is DCHECKed.
+ // In optimized builds, passing Status::OK() here will have the effect
+ // of passing tensorflow::error::INTERNAL as a fallback.
+ StatusOr(const Status& status);
+ StatusOr& operator=(const Status& status);
+
+ // TODO(b/62186997): Add operator=(T) overloads.
+
+ // Similar to the `const T&` overload.
+ //
+ // REQUIRES: T is move constructible.
+ StatusOr(T&& value);
+
+ // RValue versions of the operations declared above.
+ StatusOr(Status&& status);
+ StatusOr& operator=(Status&& status);
+
+ // Returns this->status().ok()
+ bool ok() const { return this->status_.ok(); }
+
+ // Returns a reference to our status. If this contains a T, then
+ // returns Status::OK().
+ const Status& status() const &;
+ Status status() &&;
+
+ // Returns a reference to our current value, or CHECK-fails if !this->ok().
+ //
+ // Note: for value types that are cheap to copy, prefer simple code:
+ //
+ // T value = statusor.ValueOrDie();
+ //
+ // Otherwise, if the value type is expensive to copy, but can be left
+ // in the StatusOr, simply assign to a reference:
+ //
+ // T& value = statusor.ValueOrDie(); // or `const T&`
+ //
+ // Otherwise, if the value type supports an efficient move, it can be
+ // used as follows:
+ //
+ // T value = std::move(statusor).ValueOrDie();
+ //
+ // The std::move on statusor instead of on the whole expression enables
+ // warnings about possible uses of the statusor object after the move.
+ // C++ style guide waiver for ref-qualified overloads granted in cl/143176389
+ // See go/ref-qualifiers for more details on such overloads.
+ const T& ValueOrDie() const &;
+ T& ValueOrDie() &;
+ const T&& ValueOrDie() const &&;
+ T&& ValueOrDie() &&;
+
+ T ConsumeValueOrDie() { return std::move(ValueOrDie()); }
+
+ // Ignores any errors. This method does nothing except potentially suppress
+ // complaints from any tools that are checking that errors are not dropped on
+ // the floor.
+ void IgnoreError() const;
+};
+
+////////////////////////////////////////////////////////////////////////////////
+// Implementation details for StatusOr<T>
+
+template <typename T>
+StatusOr<T>::StatusOr() : Base(Status(tensorflow::error::UNKNOWN, "")) {}
+
+template <typename T>
+StatusOr<T>::StatusOr(const T& value) : Base(value) {}
+
+template <typename T>
+StatusOr<T>::StatusOr(const Status& status) : Base(status) {}
+
+template <typename T>
+StatusOr<T>& StatusOr<T>::operator=(const Status& status) {
+ this->Assign(status);
+ return *this;
+}
+
+template <typename T>
+StatusOr<T>::StatusOr(T&& value) : Base(std::move(value)) {}
+
+template <typename T>
+StatusOr<T>::StatusOr(Status&& status) : Base(std::move(status)) {}
+
+template <typename T>
+StatusOr<T>& StatusOr<T>::operator=(Status&& status) {
+ this->Assign(std::move(status));
+ return *this;
+}
+
+template <typename T>
+template <typename U,
+ typename std::enable_if<std::is_convertible<U, T>::value>::type*>
+inline StatusOr<T>::StatusOr(const StatusOr<U>& other)
+ : Base(static_cast<const typename StatusOr<U>::Base&>(other)) {}
+
+template <typename T>
+template <typename U,
+ typename std::enable_if<std::is_convertible<U, T>::value>::type*>
+inline StatusOr<T>& StatusOr<T>::operator=(const StatusOr<U>& other) {
+ if (other.ok())
+ this->Assign(other.ValueOrDie());
+ else
+ this->Assign(other.status());
+ return *this;
+}
+
+template <typename T>
+template <typename U,
+ typename std::enable_if<std::is_convertible<U, T>::value>::type*>
+inline StatusOr<T>::StatusOr(StatusOr<U>&& other)
+ : Base(static_cast<typename StatusOr<U>::Base&&>(other)) {}
+
+template <typename T>
+template <typename U,
+ typename std::enable_if<std::is_convertible<U, T>::value>::type*>
+inline StatusOr<T>& StatusOr<T>::operator=(StatusOr<U>&& other) {
+ if (other.ok()) {
+ this->Assign(std::move(other).ValueOrDie());
+ } else {
+ this->Assign(std::move(other).status());
+ }
+ return *this;
+}
+
+template <typename T>
+const Status& StatusOr<T>::status() const & {
+ return this->status_;
+}
+template <typename T>
+Status StatusOr<T>::status() && {
+ return ok() ? Status::OK() : std::move(this->status_);
+}
+
+template <typename T>
+const T& StatusOr<T>::ValueOrDie() const & {
+ this->EnsureOk();
+ return this->data_;
+}
+
+template <typename T>
+T& StatusOr<T>::ValueOrDie() & {
+ this->EnsureOk();
+ return this->data_;
+}
+
+template <typename T>
+const T&& StatusOr<T>::ValueOrDie() const && {
+ this->EnsureOk();
+ return std::move(this->data_);
+}
+
+template <typename T>
+T&& StatusOr<T>::ValueOrDie() && {
+ this->EnsureOk();
+ return std::move(this->data_);
+}
+
template <typename T>
-using StatusOr = ::xla::StatusOr<T>;
+void StatusOr<T>::IgnoreError() const {
+ // no-op
+}
} // namespace port
} // namespace stream_executor
diff --git a/tensorflow/compiler/xla/statusor_internals.h b/tensorflow/stream_executor/lib/statusor_internals.h
index 14636bd144..09f88f5825 100644
--- a/tensorflow/compiler/xla/statusor_internals.h
+++ b/tensorflow/stream_executor/lib/statusor_internals.h
@@ -13,13 +13,15 @@ See the License for the specific language governing permissions and
limitations under the License.
==============================================================================*/
-#ifndef TENSORFLOW_COMPILER_XLA_STATUSOR_INTERNALS_H_
-#define TENSORFLOW_COMPILER_XLA_STATUSOR_INTERNALS_H_
+#ifndef TENSORFLOW_STREAM_EXECUTOR_LIB_STATUSOR_INTERNALS_H_
+#define TENSORFLOW_STREAM_EXECUTOR_LIB_STATUSOR_INTERNALS_H_
+
-#include "tensorflow/compiler/xla/status.h"
#include "tensorflow/core/platform/macros.h"
+#include "tensorflow/stream_executor/lib/status.h"
-namespace xla {
+namespace stream_executor {
+namespace port {
namespace internal_statusor {
class Helper {
@@ -240,6 +242,7 @@ struct TraitsBase<false, false> {
};
} // namespace internal_statusor
-} // namespace xla
+} // namespace port
+} // namespace stream_executor
-#endif // TENSORFLOW_COMPILER_XLA_STATUSOR_INTERNALS_H_
+#endif // TENSORFLOW_STREAM_EXECUTOR_LIB_STATUSOR_INTERNALS_H_
diff --git a/tensorflow/compiler/xla/statusor_test.cc b/tensorflow/stream_executor/lib/statusor_test.cc
index 377a618ffb..56584e1892 100644
--- a/tensorflow/compiler/xla/statusor_test.cc
+++ b/tensorflow/stream_executor/lib/statusor_test.cc
@@ -15,18 +15,18 @@ limitations under the License.
// Unit tests for StatusOr
-#include "tensorflow/compiler/xla/statusor.h"
+#include "tensorflow/stream_executor/lib/statusor.h"
#include <memory>
#include <type_traits>
-#include "tensorflow/compiler/xla/test.h"
-#include "tensorflow/compiler/xla/types.h"
+#include "tensorflow/core/platform/test.h"
#include "tensorflow/core/lib/core/errors.h"
#include "tensorflow/core/platform/macros.h"
#include "tensorflow/core/platform/test_benchmark.h"
-namespace xla {
+namespace stream_executor {
+namespace port {
namespace {
class Base1 {
@@ -672,4 +672,5 @@ void BM_StatusOrFactoryFailLongMsg(int iters) {
BENCHMARK(BM_StatusOrFactoryFailLongMsg);
} // namespace
-} // namespace xla
+} // namespace port
+} // namespace stream_executor