statusor.cc 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. // Copyright 2020 The Abseil Authors.
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // https://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. #include "absl/status/statusor.h"
  15. #include <cstdlib>
  16. #include <utility>
  17. #include "absl/base/call_once.h"
  18. #include "absl/base/config.h"
  19. #include "absl/base/internal/raw_logging.h"
  20. #include "absl/base/nullability.h"
  21. #include "absl/status/internal/statusor_internal.h"
  22. #include "absl/status/status.h"
  23. #include "absl/strings/str_cat.h"
  24. namespace absl {
  25. ABSL_NAMESPACE_BEGIN
  26. BadStatusOrAccess::BadStatusOrAccess(absl::Status status)
  27. : status_(std::move(status)) {}
  28. BadStatusOrAccess::BadStatusOrAccess(const BadStatusOrAccess& other)
  29. : status_(other.status_) {}
  30. BadStatusOrAccess& BadStatusOrAccess::operator=(
  31. const BadStatusOrAccess& other) {
  32. // Ensure assignment is correct regardless of whether this->InitWhat() has
  33. // already been called.
  34. other.InitWhat();
  35. status_ = other.status_;
  36. what_ = other.what_;
  37. return *this;
  38. }
  39. BadStatusOrAccess& BadStatusOrAccess::operator=(BadStatusOrAccess&& other) {
  40. // Ensure assignment is correct regardless of whether this->InitWhat() has
  41. // already been called.
  42. other.InitWhat();
  43. status_ = std::move(other.status_);
  44. what_ = std::move(other.what_);
  45. return *this;
  46. }
  47. BadStatusOrAccess::BadStatusOrAccess(BadStatusOrAccess&& other)
  48. : status_(std::move(other.status_)) {}
  49. absl::Nonnull<const char*> BadStatusOrAccess::what() const noexcept {
  50. InitWhat();
  51. return what_.c_str();
  52. }
  53. const absl::Status& BadStatusOrAccess::status() const { return status_; }
  54. void BadStatusOrAccess::InitWhat() const {
  55. absl::call_once(init_what_, [this] {
  56. what_ = absl::StrCat("Bad StatusOr access: ", status_.ToString());
  57. });
  58. }
  59. namespace internal_statusor {
  60. void Helper::HandleInvalidStatusCtorArg(absl::Nonnull<absl::Status*> status) {
  61. const char* kMessage =
  62. "An OK status is not a valid constructor argument to StatusOr<T>";
  63. #ifdef NDEBUG
  64. ABSL_INTERNAL_LOG(ERROR, kMessage);
  65. #else
  66. ABSL_INTERNAL_LOG(FATAL, kMessage);
  67. #endif
  68. // In optimized builds, we will fall back to InternalError.
  69. *status = absl::InternalError(kMessage);
  70. }
  71. void Helper::Crash(const absl::Status& status) {
  72. ABSL_INTERNAL_LOG(
  73. FATAL,
  74. absl::StrCat("Attempting to fetch value instead of handling error ",
  75. status.ToString()));
  76. }
  77. void ThrowBadStatusOrAccess(absl::Status status) {
  78. #ifdef ABSL_HAVE_EXCEPTIONS
  79. throw absl::BadStatusOrAccess(std::move(status));
  80. #else
  81. ABSL_INTERNAL_LOG(
  82. FATAL,
  83. absl::StrCat("Attempting to fetch value instead of handling error ",
  84. status.ToString()));
  85. std::abort();
  86. #endif
  87. }
  88. } // namespace internal_statusor
  89. ABSL_NAMESPACE_END
  90. } // namespace absl