• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
16 #include <cstdlib>
17 #include <utility>
18 
19 #include "absl/base/call_once.h"
20 #include "absl/base/internal/raw_logging.h"
21 #include "absl/status/status.h"
22 #include "absl/strings/str_cat.h"
23 
24 namespace absl {
25 ABSL_NAMESPACE_BEGIN
26 
BadStatusOrAccess(absl::Status status)27 BadStatusOrAccess::BadStatusOrAccess(absl::Status status)
28     : status_(std::move(status)) {}
29 
BadStatusOrAccess(const BadStatusOrAccess & other)30 BadStatusOrAccess::BadStatusOrAccess(const BadStatusOrAccess& other)
31     : status_(other.status_) {}
32 
operator =(const BadStatusOrAccess & other)33 BadStatusOrAccess& BadStatusOrAccess::operator=(
34     const BadStatusOrAccess& other) {
35   // Ensure assignment is correct regardless of whether this->InitWhat() has
36   // already been called.
37   other.InitWhat();
38   status_ = other.status_;
39   what_ = other.what_;
40   return *this;
41 }
42 
operator =(BadStatusOrAccess && other)43 BadStatusOrAccess& BadStatusOrAccess::operator=(BadStatusOrAccess&& other) {
44   // Ensure assignment is correct regardless of whether this->InitWhat() has
45   // already been called.
46   other.InitWhat();
47   status_ = std::move(other.status_);
48   what_ = std::move(other.what_);
49   return *this;
50 }
51 
BadStatusOrAccess(BadStatusOrAccess && other)52 BadStatusOrAccess::BadStatusOrAccess(BadStatusOrAccess&& other)
53     : status_(std::move(other.status_)) {}
54 
what() const55 const char* BadStatusOrAccess::what() const noexcept {
56   InitWhat();
57   return what_.c_str();
58 }
59 
status() const60 const absl::Status& BadStatusOrAccess::status() const { return status_; }
61 
InitWhat() const62 void BadStatusOrAccess::InitWhat() const {
63   absl::call_once(init_what_, [this] {
64     what_ = absl::StrCat("Bad StatusOr access: ", status_.ToString());
65   });
66 }
67 
68 namespace internal_statusor {
69 
HandleInvalidStatusCtorArg(absl::Status * status)70 void Helper::HandleInvalidStatusCtorArg(absl::Status* status) {
71   const char* kMessage =
72       "An OK status is not a valid constructor argument to StatusOr<T>";
73 #ifdef NDEBUG
74   ABSL_INTERNAL_LOG(ERROR, kMessage);
75 #else
76   ABSL_INTERNAL_LOG(FATAL, kMessage);
77 #endif
78   // In optimized builds, we will fall back to InternalError.
79   *status = absl::InternalError(kMessage);
80 }
81 
Crash(const absl::Status & status)82 void Helper::Crash(const absl::Status& status) {
83   ABSL_INTERNAL_LOG(
84       FATAL,
85       absl::StrCat("Attempting to fetch value instead of handling error ",
86                    status.ToString()));
87 }
88 
ThrowBadStatusOrAccess(absl::Status status)89 void ThrowBadStatusOrAccess(absl::Status status) {
90 #ifdef ABSL_HAVE_EXCEPTIONS
91   throw absl::BadStatusOrAccess(std::move(status));
92 #else
93   ABSL_INTERNAL_LOG(
94       FATAL,
95       absl::StrCat("Attempting to fetch value instead of handling error ",
96                    status.ToString()));
97   std::abort();
98 #endif
99 }
100 
101 }  // namespace internal_statusor
102 ABSL_NAMESPACE_END
103 }  // namespace absl
104