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