19 #ifndef ASYLO_UTIL_STATUSOR_H_ 20 #define ASYLO_UTIL_STATUSOR_H_ 22 #include <type_traits> 25 #include "absl/base/attributes.h" 26 #include "absl/base/config.h" 27 #include "absl/meta/type_traits.h" 28 #include "absl/status/status.h" 29 #include "absl/status/statusor.h" 30 #include "asylo/util/logging.h" 31 #include "asylo/util/cleanup.h" 32 #include "asylo/util/status.h" 33 #include "asylo/util/status_error_space.h" 132 template <
typename U>
133 friend class StatusOr;
138 template <
class U,
typename V>
139 struct is_implicitly_constructible
140 : absl::conjunction<std::is_constructible<U, V>,
141 std::is_convertible<V, U> > {};
145 using value_type = T;
162 variant_.value_.~T();
164 variant_.status_.~Status();
181 LOG(FATAL) <<
"Cannot instantiate StatusOr with absl::OkStatus()";
199 LOG(FATAL) <<
"Cannot instantiate StatusOr with absl::OkStatus()";
222 template <
typename U,
223 typename E =
typename std::enable_if<
224 is_implicitly_constructible<T, U>::value &&
225 !std::is_same<
typename std::remove_reference<
226 typename std::remove_cv<U>::type>::type,
228 !std::is_same<
typename std::remove_reference<
229 typename std::remove_cv<U>::type>::type,
230 absl::Status>::value>::type>
231 StatusOr(U &&value) : variant_(std::forward<U>(value)), has_value_(
true) {}
243 StatusOr(
const StatusOr &other) : has_value_(other.has_value_) {
245 new (&variant_) variant(other.variant_.value_);
247 new (&variant_) variant(other.variant_.status_);
257 template <
typename U,
258 typename E =
typename std::enable_if<
259 is_implicitly_constructible<T,
const U &>::value>::type>
260 StatusOr(
const StatusOr<U> &other)
261 : has_value_(other.has_value_) {
263 new (&variant_) variant(other.variant_.value_);
265 new (&variant_) variant(other.variant_.status_);
275 template <
typename U,
276 typename E =
typename std::enable_if<
277 is_implicitly_constructible<T,
const U &>::value>::type>
278 StatusOr(
const absl::StatusOr<U> &other)
279 : has_value_(other.ok()) {
281 new (&variant_) variant(*other);
283 new (&variant_) variant(other.status());
290 StatusOr &operator=(
const StatusOr &other) {
292 if (
this == &other) {
297 if (other.has_value_) {
298 AssignValue(other.variant_.value_);
300 AssignStatus(other.variant_.status_);
312 template <
typename U,
typename E =
typename std::enable_if<
313 is_implicitly_constructible<T, U &&>::value>::type>
314 StatusOr(StatusOr<U> &&other) : has_value_(other.has_value_) {
316 new (&variant_) variant(std::move(other.variant_.value_));
317 other.OverwriteValueWithStatus(
318 Status(error::StatusError::MOVED, kValueMoveConstructorMsg));
320 new (&variant_) variant(std::move(other.variant_.status_));
325 other.variant_.status_ =
326 Status(error::StatusError::MOVED, kStatusMoveConstructorMsg);
336 template <
typename U,
typename E =
typename std::enable_if<
337 is_implicitly_constructible<T, U &&>::value>::type>
338 StatusOr(absl::StatusOr<U> &&other) : has_value_(other.ok()) {
340 new (&variant_) variant(*std::move(other));
342 new (&variant_) variant(std::move(other).status());
351 StatusOr &operator=(StatusOr &&other) {
353 if (
this == &other) {
358 if (other.has_value_) {
359 AssignValue(std::move(other.variant_.value_));
360 other.OverwriteValueWithStatus(
361 Status(error::StatusError::MOVED, kValueMoveAssignmentMsg));
363 AssignStatus(std::move(other.variant_.status_));
368 other.variant_.status_ =
369 Status(error::StatusError::MOVED, kStatusMoveAssignmentMsg);
379 template <
typename U,
typename E =
typename std::enable_if<
380 is_implicitly_constructible<U, T &&>::value>::type>
381 operator absl::StatusOr<U>()
const {
383 return variant_.value_;
385 return variant_.status_;
394 bool ok()
const {
return has_value_; }
400 Status status()
const {
return ok() ? OkStatus() : variant_.status_; }
409 const T &value()
const & {
411 HandleBadValueCall();
413 return variant_.value_;
425 HandleBadValueCall();
427 return variant_.value_;
442 HandleBadValueCall();
444 return std::move(*
this).MoveValue();
456 "Deprecated as part of Asylo's absl::Status migration. Use value(), " 457 "operator*(), or operator->() instead.")
458 const T &ValueOrDie()
const & {
return **
this; }
469 "Deprecated as part of Asylo's absl::Status migration. Use value(), " 470 "operator*(), or operator->() instead.")
471 T &ValueOrDie() & {
return **
this; }
484 "Deprecated as part of Asylo's absl::Status migration. Use value(), " 485 "operator*(), or operator->() instead.")
486 T ValueOrDie() && {
return *std::move(*
this); }
495 const T &operator*()
const & {
499 return variant_.value_;
513 return variant_.value_;
528 return std::move(*
this).MoveValue();
538 const T *operator->()
const {
542 return &variant_.value_;
556 return &variant_.value_;
562 void AssignStatus(U &&status) {
564 OverwriteValueWithStatus(std::forward<U>(status));
567 variant_.status_ = std::forward<U>(status);
575 void OverwriteValueWithStatus(U &&status) {
578 LOG(FATAL) <<
"Object does not have a value to change from";
581 variant_.value_.~T();
582 new (&variant_) variant(std::forward<U>(status));
590 void AssignValue(U &&value) {
593 variant_.value_.~T();
595 variant_.status_.~Status();
597 new (&variant_) variant(std::forward<U>(value));
605 void HandleBadValueCall()
const {
606 #ifdef ABSL_HAVE_EXCEPTIONS 607 throw absl::BadStatusOrAccess(status());
617 void DieOnBadAccess()
const {
619 <<
"Object does not have a usable value, instead contains status: " 626 Cleanup set_moved_status([
this] {
627 OverwriteValueWithStatus(
628 Status(error::StatusError::MOVED, kValueOrDieMovedMsg));
630 return std::move(variant_.value_);
642 variant(
const Status &status) : status_(status) {}
644 variant(Status &&status) : status_(std::move(status)) {}
646 template <
typename U,
typename E =
typename std::enable_if<
647 is_implicitly_constructible<T, U>::value>::type>
648 variant(U &&value) : value_(std::forward<U>(value)) {}
StatusOr()
Constructs a StatusOr object that contains a non-OK status.
Definition: statusor.h:156
StatusOr(const absl::Status &status)
Constructs a StatusOr object with the given non-OK absl::Status object.
Definition: statusor.h:196
ABSL_CONST_INIT const char kStatusMoveAssignmentMsg[]
~StatusOr()
Definition: statusor.h:160