diff options
Diffstat (limited to 'third_party/abseil_cpp/absl/status')
-rw-r--r-- | third_party/abseil_cpp/absl/status/BUILD.bazel | 66 | ||||
-rw-r--r-- | third_party/abseil_cpp/absl/status/CMakeLists.txt | 85 | ||||
-rw-r--r-- | third_party/abseil_cpp/absl/status/status.cc | 445 | ||||
-rw-r--r-- | third_party/abseil_cpp/absl/status/status.h | 428 | ||||
-rw-r--r-- | third_party/abseil_cpp/absl/status/status_payload_printer.cc | 38 | ||||
-rw-r--r-- | third_party/abseil_cpp/absl/status/status_payload_printer.h | 51 | ||||
-rw-r--r-- | third_party/abseil_cpp/absl/status/status_test.cc | 458 | ||||
-rw-r--r-- | third_party/abseil_cpp/absl/status/statusor.cc | 48 | ||||
-rw-r--r-- | third_party/abseil_cpp/absl/status/statusor.h | 394 | ||||
-rw-r--r-- | third_party/abseil_cpp/absl/status/statusor_internals.h | 250 | ||||
-rw-r--r-- | third_party/abseil_cpp/absl/status/statusor_test.cc | 753 |
11 files changed, 0 insertions, 3016 deletions
diff --git a/third_party/abseil_cpp/absl/status/BUILD.bazel b/third_party/abseil_cpp/absl/status/BUILD.bazel deleted file mode 100644 index d164252da9..0000000000 --- a/third_party/abseil_cpp/absl/status/BUILD.bazel +++ /dev/null @@ -1,66 +0,0 @@ -# -# Copyright 2017 The Abseil Authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# https://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# 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. - -# This package contains `absl::Status`. -# It will expand later to have utilities around `Status` like `StatusOr`, -# `StatusBuilder` and macros. - -load("@rules_cc//cc:defs.bzl", "cc_library", "cc_test") -load( - "//absl:copts/configure_copts.bzl", - "ABSL_DEFAULT_COPTS", - "ABSL_TEST_COPTS", -) - -package(default_visibility = ["//visibility:public"]) - -licenses(["notice"]) # Apache 2.0 - -cc_library( - name = "status", - srcs = [ - "status.cc", - "status_payload_printer.cc", - ], - hdrs = [ - "status.h", - "status_payload_printer.h", - ], - copts = ABSL_DEFAULT_COPTS, - deps = [ - "//absl/base:atomic_hook", - "//absl/base:config", - "//absl/base:core_headers", - "//absl/base:raw_logging_internal", - "//absl/container:inlined_vector", - "//absl/debugging:stacktrace", - "//absl/debugging:symbolize", - "//absl/strings", - "//absl/strings:cord", - "//absl/strings:str_format", - "//absl/types:optional", - ], -) - -cc_test( - name = "status_test", - srcs = ["status_test.cc"], - copts = ABSL_TEST_COPTS, - deps = [ - ":status", - "//absl/strings", - "@com_google_googletest//:gtest_main", - ], -) diff --git a/third_party/abseil_cpp/absl/status/CMakeLists.txt b/third_party/abseil_cpp/absl/status/CMakeLists.txt deleted file mode 100644 index 3b8917e030..0000000000 --- a/third_party/abseil_cpp/absl/status/CMakeLists.txt +++ /dev/null @@ -1,85 +0,0 @@ -# -# Copyright 2020 The Abseil Authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# https://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# 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. -# -absl_cc_library( - NAME - status - HDRS - "status.h" - SRCS - "status.cc" - "status_payload_printer.h" - "status_payload_printer.cc" - COPTS - ${ABSL_DEFAULT_COPTS} - DEPS - absl::atomic_hook - absl::config - absl::core_headers - absl::raw_logging_internal - absl::inlined_vector - absl::stacktrace - absl::symbolize - absl::strings - absl::cord - absl::str_format - absl::optional - PUBLIC -) - -absl_cc_library( - NAME - statusor - HDRS - "statusor.h" - SRCS - "statusor.cc" - "statusor_internals.h" - COPTS - ${ABSL_DEFAULT_COPTS} - DEPS - absl::status - absl::atomic_hook - absl::raw_logging_internal - absl::strings - PUBLIC -) - -absl_cc_test( - NAME - status_test - SRCS - "status_test.cc" - COPTS - ${ABSL_TEST_COPTS} - DEPS - absl::status - absl::strings - gmock_main -) - -absl_cc_test( - NAME - statusor_test - SRCS - "statusor_test.cc" - COPTS - ${ABSL_TEST_COPTS} - DEPS - absl::status - absl::statusor - absl::strings - gmock_main -) diff --git a/third_party/abseil_cpp/absl/status/status.cc b/third_party/abseil_cpp/absl/status/status.cc deleted file mode 100644 index 0a655736e5..0000000000 --- a/third_party/abseil_cpp/absl/status/status.cc +++ /dev/null @@ -1,445 +0,0 @@ -// Copyright 2019 The Abseil Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// 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. -#include "absl/status/status.h" - -#include <cassert> - -#include "absl/base/internal/raw_logging.h" -#include "absl/debugging/stacktrace.h" -#include "absl/debugging/symbolize.h" -#include "absl/status/status_payload_printer.h" -#include "absl/strings/escaping.h" -#include "absl/strings/str_cat.h" -#include "absl/strings/str_format.h" -#include "absl/strings/str_split.h" - -namespace absl { -ABSL_NAMESPACE_BEGIN - -std::string StatusCodeToString(StatusCode code) { - switch (code) { - case StatusCode::kOk: - return "OK"; - case StatusCode::kCancelled: - return "CANCELLED"; - case StatusCode::kUnknown: - return "UNKNOWN"; - case StatusCode::kInvalidArgument: - return "INVALID_ARGUMENT"; - case StatusCode::kDeadlineExceeded: - return "DEADLINE_EXCEEDED"; - case StatusCode::kNotFound: - return "NOT_FOUND"; - case StatusCode::kAlreadyExists: - return "ALREADY_EXISTS"; - case StatusCode::kPermissionDenied: - return "PERMISSION_DENIED"; - case StatusCode::kUnauthenticated: - return "UNAUTHENTICATED"; - case StatusCode::kResourceExhausted: - return "RESOURCE_EXHAUSTED"; - case StatusCode::kFailedPrecondition: - return "FAILED_PRECONDITION"; - case StatusCode::kAborted: - return "ABORTED"; - case StatusCode::kOutOfRange: - return "OUT_OF_RANGE"; - case StatusCode::kUnimplemented: - return "UNIMPLEMENTED"; - case StatusCode::kInternal: - return "INTERNAL"; - case StatusCode::kUnavailable: - return "UNAVAILABLE"; - case StatusCode::kDataLoss: - return "DATA_LOSS"; - default: - return ""; - } -} - -std::ostream& operator<<(std::ostream& os, StatusCode code) { - return os << StatusCodeToString(code); -} - -namespace status_internal { - -static int FindPayloadIndexByUrl(const Payloads* payloads, - absl::string_view type_url) { - if (payloads == nullptr) return -1; - - for (int i = 0; i < payloads->size(); ++i) { - if ((*payloads)[i].type_url == type_url) return i; - } - - return -1; -} - -// Convert canonical code to a value known to this binary. -absl::StatusCode MapToLocalCode(int value) { - absl::StatusCode code = static_cast<absl::StatusCode>(value); - switch (code) { - case absl::StatusCode::kOk: - case absl::StatusCode::kCancelled: - case absl::StatusCode::kUnknown: - case absl::StatusCode::kInvalidArgument: - case absl::StatusCode::kDeadlineExceeded: - case absl::StatusCode::kNotFound: - case absl::StatusCode::kAlreadyExists: - case absl::StatusCode::kPermissionDenied: - case absl::StatusCode::kResourceExhausted: - case absl::StatusCode::kFailedPrecondition: - case absl::StatusCode::kAborted: - case absl::StatusCode::kOutOfRange: - case absl::StatusCode::kUnimplemented: - case absl::StatusCode::kInternal: - case absl::StatusCode::kUnavailable: - case absl::StatusCode::kDataLoss: - case absl::StatusCode::kUnauthenticated: - return code; - default: - return absl::StatusCode::kUnknown; - } -} -} // namespace status_internal - -absl::optional<absl::Cord> Status::GetPayload( - absl::string_view type_url) const { - const auto* payloads = GetPayloads(); - int index = status_internal::FindPayloadIndexByUrl(payloads, type_url); - if (index != -1) return (*payloads)[index].payload; - - return absl::nullopt; -} - -void Status::SetPayload(absl::string_view type_url, absl::Cord payload) { - if (ok()) return; - - PrepareToModify(); - - status_internal::StatusRep* rep = RepToPointer(rep_); - if (!rep->payloads) { - rep->payloads = absl::make_unique<status_internal::Payloads>(); - } - - int index = - status_internal::FindPayloadIndexByUrl(rep->payloads.get(), type_url); - if (index != -1) { - (*rep->payloads)[index].payload = std::move(payload); - return; - } - - rep->payloads->push_back({std::string(type_url), std::move(payload)}); -} - -bool Status::ErasePayload(absl::string_view type_url) { - int index = status_internal::FindPayloadIndexByUrl(GetPayloads(), type_url); - if (index != -1) { - PrepareToModify(); - GetPayloads()->erase(GetPayloads()->begin() + index); - if (GetPayloads()->empty() && message().empty()) { - // Special case: If this can be represented inlined, it MUST be - // inlined (EqualsSlow depends on this behavior). - StatusCode c = static_cast<StatusCode>(raw_code()); - Unref(rep_); - rep_ = CodeToInlinedRep(c); - } - return true; - } - - return false; -} - -void Status::ForEachPayload( - const std::function<void(absl::string_view, const absl::Cord&)>& visitor) - const { - if (auto* payloads = GetPayloads()) { - bool in_reverse = - payloads->size() > 1 && reinterpret_cast<uintptr_t>(payloads) % 13 > 6; - - for (int index = 0; index < payloads->size(); ++index) { - const auto& elem = - (*payloads)[in_reverse ? payloads->size() - 1 - index : index]; - -#ifdef NDEBUG - visitor(elem.type_url, elem.payload); -#else - // In debug mode invalidate the type url to prevent users from relying on - // this string lifetime. - - // NOLINTNEXTLINE intentional extra conversion to force temporary. - visitor(std::string(elem.type_url), elem.payload); -#endif // NDEBUG - } - } -} - -const std::string* Status::EmptyString() { - static std::string* empty_string = new std::string(); - return empty_string; -} - -constexpr const char Status::kMovedFromString[]; - -const std::string* Status::MovedFromString() { - static std::string* moved_from_string = new std::string(kMovedFromString); - return moved_from_string; -} - -void Status::UnrefNonInlined(uintptr_t rep) { - status_internal::StatusRep* r = RepToPointer(rep); - // Fast path: if ref==1, there is no need for a RefCountDec (since - // this is the only reference and therefore no other thread is - // allowed to be mucking with r). - if (r->ref.load(std::memory_order_acquire) == 1 || - r->ref.fetch_sub(1, std::memory_order_acq_rel) - 1 == 0) { - delete r; - } -} - -uintptr_t Status::NewRep(absl::StatusCode code, absl::string_view msg, - std::unique_ptr<status_internal::Payloads> payloads) { - status_internal::StatusRep* rep = new status_internal::StatusRep; - rep->ref.store(1, std::memory_order_relaxed); - rep->code = code; - rep->message.assign(msg.data(), msg.size()); - rep->payloads = std::move(payloads); - return PointerToRep(rep); -} - -Status::Status(absl::StatusCode code, absl::string_view msg) - : rep_(CodeToInlinedRep(code)) { - if (code != absl::StatusCode::kOk && !msg.empty()) { - rep_ = NewRep(code, msg, nullptr); - } -} - -int Status::raw_code() const { - if (IsInlined(rep_)) { - return static_cast<int>(InlinedRepToCode(rep_)); - } - status_internal::StatusRep* rep = RepToPointer(rep_); - return static_cast<int>(rep->code); -} - -absl::StatusCode Status::code() const { - return status_internal::MapToLocalCode(raw_code()); -} - -void Status::PrepareToModify() { - ABSL_RAW_CHECK(!ok(), "PrepareToModify shouldn't be called on OK status."); - if (IsInlined(rep_)) { - rep_ = NewRep(static_cast<absl::StatusCode>(raw_code()), - absl::string_view(), nullptr); - return; - } - - uintptr_t rep_i = rep_; - status_internal::StatusRep* rep = RepToPointer(rep_); - if (rep->ref.load(std::memory_order_acquire) != 1) { - std::unique_ptr<status_internal::Payloads> payloads; - if (rep->payloads) { - payloads = absl::make_unique<status_internal::Payloads>(*rep->payloads); - } - rep_ = NewRep(rep->code, message(), std::move(payloads)); - UnrefNonInlined(rep_i); - } -} - -bool Status::EqualsSlow(const absl::Status& a, const absl::Status& b) { - if (IsInlined(a.rep_) != IsInlined(b.rep_)) return false; - if (a.message() != b.message()) return false; - if (a.raw_code() != b.raw_code()) return false; - if (a.GetPayloads() == b.GetPayloads()) return true; - - const status_internal::Payloads no_payloads; - const status_internal::Payloads* larger_payloads = - a.GetPayloads() ? a.GetPayloads() : &no_payloads; - const status_internal::Payloads* smaller_payloads = - b.GetPayloads() ? b.GetPayloads() : &no_payloads; - if (larger_payloads->size() < smaller_payloads->size()) { - std::swap(larger_payloads, smaller_payloads); - } - if ((larger_payloads->size() - smaller_payloads->size()) > 1) return false; - // Payloads can be ordered differently, so we can't just compare payload - // vectors. - for (const auto& payload : *larger_payloads) { - - bool found = false; - for (const auto& other_payload : *smaller_payloads) { - if (payload.type_url == other_payload.type_url) { - if (payload.payload != other_payload.payload) { - return false; - } - found = true; - break; - } - } - if (!found) return false; - } - return true; -} - -std::string Status::ToStringSlow() const { - std::string text; - absl::StrAppend(&text, absl::StatusCodeToString(code()), ": ", message()); - status_internal::StatusPayloadPrinter printer = - status_internal::GetStatusPayloadPrinter(); - this->ForEachPayload([&](absl::string_view type_url, - const absl::Cord& payload) { - absl::optional<std::string> result; - if (printer) result = printer(type_url, payload); - absl::StrAppend( - &text, " [", type_url, "='", - result.has_value() ? *result : absl::CHexEscape(std::string(payload)), - "']"); - }); - - return text; -} - -std::ostream& operator<<(std::ostream& os, const Status& x) { - os << x.ToString(); - return os; -} - -Status AbortedError(absl::string_view message) { - return Status(absl::StatusCode::kAborted, message); -} - -Status AlreadyExistsError(absl::string_view message) { - return Status(absl::StatusCode::kAlreadyExists, message); -} - -Status CancelledError(absl::string_view message) { - return Status(absl::StatusCode::kCancelled, message); -} - -Status DataLossError(absl::string_view message) { - return Status(absl::StatusCode::kDataLoss, message); -} - -Status DeadlineExceededError(absl::string_view message) { - return Status(absl::StatusCode::kDeadlineExceeded, message); -} - -Status FailedPreconditionError(absl::string_view message) { - return Status(absl::StatusCode::kFailedPrecondition, message); -} - -Status InternalError(absl::string_view message) { - return Status(absl::StatusCode::kInternal, message); -} - -Status InvalidArgumentError(absl::string_view message) { - return Status(absl::StatusCode::kInvalidArgument, message); -} - -Status NotFoundError(absl::string_view message) { - return Status(absl::StatusCode::kNotFound, message); -} - -Status OutOfRangeError(absl::string_view message) { - return Status(absl::StatusCode::kOutOfRange, message); -} - -Status PermissionDeniedError(absl::string_view message) { - return Status(absl::StatusCode::kPermissionDenied, message); -} - -Status ResourceExhaustedError(absl::string_view message) { - return Status(absl::StatusCode::kResourceExhausted, message); -} - -Status UnauthenticatedError(absl::string_view message) { - return Status(absl::StatusCode::kUnauthenticated, message); -} - -Status UnavailableError(absl::string_view message) { - return Status(absl::StatusCode::kUnavailable, message); -} - -Status UnimplementedError(absl::string_view message) { - return Status(absl::StatusCode::kUnimplemented, message); -} - -Status UnknownError(absl::string_view message) { - return Status(absl::StatusCode::kUnknown, message); -} - -bool IsAborted(const Status& status) { - return status.code() == absl::StatusCode::kAborted; -} - -bool IsAlreadyExists(const Status& status) { - return status.code() == absl::StatusCode::kAlreadyExists; -} - -bool IsCancelled(const Status& status) { - return status.code() == absl::StatusCode::kCancelled; -} - -bool IsDataLoss(const Status& status) { - return status.code() == absl::StatusCode::kDataLoss; -} - -bool IsDeadlineExceeded(const Status& status) { - return status.code() == absl::StatusCode::kDeadlineExceeded; -} - -bool IsFailedPrecondition(const Status& status) { - return status.code() == absl::StatusCode::kFailedPrecondition; -} - -bool IsInternal(const Status& status) { - return status.code() == absl::StatusCode::kInternal; -} - -bool IsInvalidArgument(const Status& status) { - return status.code() == absl::StatusCode::kInvalidArgument; -} - -bool IsNotFound(const Status& status) { - return status.code() == absl::StatusCode::kNotFound; -} - -bool IsOutOfRange(const Status& status) { - return status.code() == absl::StatusCode::kOutOfRange; -} - -bool IsPermissionDenied(const Status& status) { - return status.code() == absl::StatusCode::kPermissionDenied; -} - -bool IsResourceExhausted(const Status& status) { - return status.code() == absl::StatusCode::kResourceExhausted; -} - -bool IsUnauthenticated(const Status& status) { - return status.code() == absl::StatusCode::kUnauthenticated; -} - -bool IsUnavailable(const Status& status) { - return status.code() == absl::StatusCode::kUnavailable; -} - -bool IsUnimplemented(const Status& status) { - return status.code() == absl::StatusCode::kUnimplemented; -} - -bool IsUnknown(const Status& status) { - return status.code() == absl::StatusCode::kUnknown; -} - -ABSL_NAMESPACE_END -} // namespace absl diff --git a/third_party/abseil_cpp/absl/status/status.h b/third_party/abseil_cpp/absl/status/status.h deleted file mode 100644 index 967e60644f..0000000000 --- a/third_party/abseil_cpp/absl/status/status.h +++ /dev/null @@ -1,428 +0,0 @@ -// Copyright 2019 The Abseil Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// 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. -#ifndef ABSL_STATUS_STATUS_H_ -#define ABSL_STATUS_STATUS_H_ - -#include <iostream> -#include <string> - -#include "absl/container/inlined_vector.h" -#include "absl/strings/cord.h" -#include "absl/types/optional.h" - -namespace absl { -ABSL_NAMESPACE_BEGIN - -enum class StatusCode : int { - kOk = 0, - kCancelled = 1, - kUnknown = 2, - kInvalidArgument = 3, - kDeadlineExceeded = 4, - kNotFound = 5, - kAlreadyExists = 6, - kPermissionDenied = 7, - kResourceExhausted = 8, - kFailedPrecondition = 9, - kAborted = 10, - kOutOfRange = 11, - kUnimplemented = 12, - kInternal = 13, - kUnavailable = 14, - kDataLoss = 15, - kUnauthenticated = 16, - kDoNotUseReservedForFutureExpansionUseDefaultInSwitchInstead_ = 20 -}; - -// Returns the name for the status code, or "" if it is an unknown value. -std::string StatusCodeToString(StatusCode code); - -// Streams StatusCodeToString(code) to `os`. -std::ostream& operator<<(std::ostream& os, StatusCode code); - -namespace status_internal { - -// Container for status payloads. -struct Payload { - std::string type_url; - absl::Cord payload; -}; - -using Payloads = absl::InlinedVector<Payload, 1>; - -// Reference-counted representation of Status data. -struct StatusRep { - std::atomic<int32_t> ref; - absl::StatusCode code; - std::string message; - std::unique_ptr<status_internal::Payloads> payloads; -}; - -absl::StatusCode MapToLocalCode(int value); -} // namespace status_internal - -class ABSL_MUST_USE_RESULT Status final { - public: - // Creates an OK status with no message or payload. - Status(); - - // Create a status in the canonical error space with the specified code and - // error message. If `code == absl::StatusCode::kOk`, `msg` is ignored and an - // object identical to an OK status is constructed. - // - // `msg` must be in UTF-8. The implementation may complain (e.g., - // by printing a warning) if it is not. - Status(absl::StatusCode code, absl::string_view msg); - - Status(const Status&); - Status& operator=(const Status& x); - - // Move operations. - // The moved-from state is valid but unspecified. - Status(Status&&) noexcept; - Status& operator=(Status&&); - - ~Status(); - - // If `this->ok()`, stores `new_status` into *this. If `!this->ok()`, - // preserves the current data. May, in the future, augment the current status - // with additional information about `new_status`. - // - // Convenient way of keeping track of the first error encountered. - // Instead of: - // if (overall_status.ok()) overall_status = new_status - // Use: - // overall_status.Update(new_status); - // - // Style guide exception for rvalue reference granted in CL 153567220. - void Update(const Status& new_status); - void Update(Status&& new_status); - - // Returns true if the Status is OK. - ABSL_MUST_USE_RESULT bool ok() const; - - // Returns the (canonical) error code. - absl::StatusCode code() const; - - // Returns the raw (canonical) error code which could be out of the range of - // the local `absl::StatusCode` enum. NOTE: This should only be called when - // converting to wire format. Use `code` for error handling. - int raw_code() const; - - // Returns the error message. Note: prefer ToString() for debug logging. - // This message rarely describes the error code. It is not unusual for the - // error message to be the empty string. - absl::string_view message() const; - - friend bool operator==(const Status&, const Status&); - friend bool operator!=(const Status&, const Status&); - - // Returns a combination of the error code name, the message and the payloads. - // You can expect the code name and the message to be substrings of the - // result, and the payloads to be printed by the registered printer extensions - // if they are recognized. - // WARNING: Do not depend on the exact format of the result of `ToString()` - // which is subject to change. - std::string ToString() const; - - // 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; - - // Swap the contents of `a` with `b` - friend void swap(Status& a, Status& b); - - // Payload management APIs - - // Type URL should be unique and follow the naming convention below: - // The idea of type URL comes from `google.protobuf.Any` - // (https://developers.google.com/protocol-buffers/docs/proto3#any). The - // type URL should be globally unique and follow the format of URL - // (https://en.wikipedia.org/wiki/URL). The default type URL for a given - // protobuf message type is "type.googleapis.com/packagename.messagename". For - // other custom wire formats, users should define the format of type URL in a - // similar practice so as to minimize the chance of conflict between type - // URLs. Users should make sure that the type URL can be mapped to a concrete - // C++ type if they want to deserialize the payload and read it effectively. - - // Gets the payload based for `type_url` key, if it is present. - absl::optional<absl::Cord> GetPayload(absl::string_view type_url) const; - - // Sets the payload for `type_url` key for a non-ok status, overwriting any - // existing payload for `type_url`. - // - // NOTE: Does nothing if the Status is ok. - void SetPayload(absl::string_view type_url, absl::Cord payload); - - // Erases the payload corresponding to the `type_url` key. Returns true if - // the payload was present. - bool ErasePayload(absl::string_view type_url); - - // Iterates over the stored payloads and calls `visitor(type_key, payload)` - // for each one. - // - // NOTE: The order of calls to `visitor` is not specified and may change at - // any time. - // - // NOTE: Any mutation on the same 'Status' object during visitation is - // forbidden and could result in undefined behavior. - void ForEachPayload( - const std::function<void(absl::string_view, const absl::Cord&)>& visitor) - const; - - private: - friend Status CancelledError(); - - // Creates a status in the canonical error space with the specified - // code, and an empty error message. - explicit Status(absl::StatusCode code); - - static void UnrefNonInlined(uintptr_t rep); - static void Ref(uintptr_t rep); - static void Unref(uintptr_t rep); - - // REQUIRES: !ok() - // Ensures rep_ is not shared with any other Status. - void PrepareToModify(); - - const status_internal::Payloads* GetPayloads() const; - status_internal::Payloads* GetPayloads(); - - // Takes ownership of payload. - static uintptr_t NewRep(absl::StatusCode code, absl::string_view msg, - std::unique_ptr<status_internal::Payloads> payload); - static bool EqualsSlow(const absl::Status& a, const absl::Status& b); - - // MSVC 14.0 limitation requires the const. - static constexpr const char kMovedFromString[] = - "Status accessed after move."; - - static const std::string* EmptyString(); - static const std::string* MovedFromString(); - - // Returns whether rep contains an inlined representation. - // See rep_ for details. - static bool IsInlined(uintptr_t rep); - - // Indicates whether this Status was the rhs of a move operation. See rep_ - // for details. - static bool IsMovedFrom(uintptr_t rep); - static uintptr_t MovedFromRep(); - - // Convert between error::Code and the inlined uintptr_t representation used - // by rep_. See rep_ for details. - static uintptr_t CodeToInlinedRep(absl::StatusCode code); - static absl::StatusCode InlinedRepToCode(uintptr_t rep); - - // Converts between StatusRep* and the external uintptr_t representation used - // by rep_. See rep_ for details. - static uintptr_t PointerToRep(status_internal::StatusRep* r); - static status_internal::StatusRep* RepToPointer(uintptr_t r); - - // Returns string for non-ok Status. - std::string ToStringSlow() const; - - // Status supports two different representations. - // - When the low bit is off it is an inlined representation. - // It uses the canonical error space, no message or payload. - // The error code is (rep_ >> 2). - // The (rep_ & 2) bit is the "moved from" indicator, used in IsMovedFrom(). - // - When the low bit is on it is an external representation. - // In this case all the data comes from a heap allocated Rep object. - // (rep_ - 1) is a status_internal::StatusRep* pointer to that structure. - uintptr_t rep_; -}; - -// Returns an OK status, equivalent to a default constructed instance. -Status OkStatus(); - -// Prints a human-readable representation of `x` to `os`. -std::ostream& operator<<(std::ostream& os, const Status& x); - -// ----------------------------------------------------------------- -// Implementation details follow - -inline Status::Status() : rep_(CodeToInlinedRep(absl::StatusCode::kOk)) {} - -inline Status::Status(absl::StatusCode code) : rep_(CodeToInlinedRep(code)) {} - -inline Status::Status(const Status& x) : rep_(x.rep_) { Ref(rep_); } - -inline Status& Status::operator=(const Status& x) { - uintptr_t old_rep = rep_; - if (x.rep_ != old_rep) { - Ref(x.rep_); - rep_ = x.rep_; - Unref(old_rep); - } - return *this; -} - -inline Status::Status(Status&& x) noexcept : rep_(x.rep_) { - x.rep_ = MovedFromRep(); -} - -inline Status& Status::operator=(Status&& x) { - uintptr_t old_rep = rep_; - rep_ = x.rep_; - x.rep_ = MovedFromRep(); - Unref(old_rep); - return *this; -} - -inline void Status::Update(const Status& new_status) { - if (ok()) { - *this = new_status; - } -} - -inline void Status::Update(Status&& new_status) { - if (ok()) { - *this = std::move(new_status); - } -} - -inline Status::~Status() { Unref(rep_); } - -inline bool Status::ok() const { - return rep_ == CodeToInlinedRep(absl::StatusCode::kOk); -} - -inline absl::string_view Status::message() const { - return !IsInlined(rep_) - ? RepToPointer(rep_)->message - : (IsMovedFrom(rep_) ? absl::string_view(kMovedFromString) - : absl::string_view()); -} - -inline bool operator==(const Status& lhs, const Status& rhs) { - return lhs.rep_ == rhs.rep_ || Status::EqualsSlow(lhs, rhs); -} - -inline bool operator!=(const Status& lhs, const Status& rhs) { - return !(lhs == rhs); -} - -inline std::string Status::ToString() const { - return ok() ? "OK" : ToStringSlow(); -} - -inline void Status::IgnoreError() const { - // no-op -} - -inline void swap(absl::Status& a, absl::Status& b) { - using std::swap; - swap(a.rep_, b.rep_); -} - -inline const status_internal::Payloads* Status::GetPayloads() const { - return IsInlined(rep_) ? nullptr : RepToPointer(rep_)->payloads.get(); -} - -inline status_internal::Payloads* Status::GetPayloads() { - return IsInlined(rep_) ? nullptr : RepToPointer(rep_)->payloads.get(); -} - -inline bool Status::IsInlined(uintptr_t rep) { return (rep & 1) == 0; } - -inline bool Status::IsMovedFrom(uintptr_t rep) { - return IsInlined(rep) && (rep & 2) != 0; -} - -inline uintptr_t Status::MovedFromRep() { - return CodeToInlinedRep(absl::StatusCode::kInternal) | 2; -} - -inline uintptr_t Status::CodeToInlinedRep(absl::StatusCode code) { - return static_cast<uintptr_t>(code) << 2; -} - -inline absl::StatusCode Status::InlinedRepToCode(uintptr_t rep) { - assert(IsInlined(rep)); - return static_cast<absl::StatusCode>(rep >> 2); -} - -inline status_internal::StatusRep* Status::RepToPointer(uintptr_t rep) { - assert(!IsInlined(rep)); - return reinterpret_cast<status_internal::StatusRep*>(rep - 1); -} - -inline uintptr_t Status::PointerToRep(status_internal::StatusRep* rep) { - return reinterpret_cast<uintptr_t>(rep) + 1; -} - -inline void Status::Ref(uintptr_t rep) { - if (!IsInlined(rep)) { - RepToPointer(rep)->ref.fetch_add(1, std::memory_order_relaxed); - } -} - -inline void Status::Unref(uintptr_t rep) { - if (!IsInlined(rep)) { - UnrefNonInlined(rep); - } -} - -inline Status OkStatus() { return Status(); } - -// Each of the functions below creates a Status object with a particular error -// code and the given message. The error code of the returned status object -// matches the name of the function. -Status AbortedError(absl::string_view message); -Status AlreadyExistsError(absl::string_view message); -Status CancelledError(absl::string_view message); -Status DataLossError(absl::string_view message); -Status DeadlineExceededError(absl::string_view message); -Status FailedPreconditionError(absl::string_view message); -Status InternalError(absl::string_view message); -Status InvalidArgumentError(absl::string_view message); -Status NotFoundError(absl::string_view message); -Status OutOfRangeError(absl::string_view message); -Status PermissionDeniedError(absl::string_view message); -Status ResourceExhaustedError(absl::string_view message); -Status UnauthenticatedError(absl::string_view message); -Status UnavailableError(absl::string_view message); -Status UnimplementedError(absl::string_view message); -Status UnknownError(absl::string_view message); - -// Creates a `Status` object with the `absl::StatusCode::kCancelled` error code -// and an empty message. It is provided only for efficiency, given that -// message-less kCancelled errors are common in the infrastructure. -inline Status CancelledError() { return Status(absl::StatusCode::kCancelled); } - -// Each of the functions below returns true if the given status matches the -// error code implied by the function's name. -ABSL_MUST_USE_RESULT bool IsAborted(const Status& status); -ABSL_MUST_USE_RESULT bool IsAlreadyExists(const Status& status); -ABSL_MUST_USE_RESULT bool IsCancelled(const Status& status); -ABSL_MUST_USE_RESULT bool IsDataLoss(const Status& status); -ABSL_MUST_USE_RESULT bool IsDeadlineExceeded(const Status& status); -ABSL_MUST_USE_RESULT bool IsFailedPrecondition(const Status& status); -ABSL_MUST_USE_RESULT bool IsInternal(const Status& status); -ABSL_MUST_USE_RESULT bool IsInvalidArgument(const Status& status); -ABSL_MUST_USE_RESULT bool IsNotFound(const Status& status); -ABSL_MUST_USE_RESULT bool IsOutOfRange(const Status& status); -ABSL_MUST_USE_RESULT bool IsPermissionDenied(const Status& status); -ABSL_MUST_USE_RESULT bool IsResourceExhausted(const Status& status); -ABSL_MUST_USE_RESULT bool IsUnauthenticated(const Status& status); -ABSL_MUST_USE_RESULT bool IsUnavailable(const Status& status); -ABSL_MUST_USE_RESULT bool IsUnimplemented(const Status& status); -ABSL_MUST_USE_RESULT bool IsUnknown(const Status& status); - -ABSL_NAMESPACE_END -} // namespace absl - -#endif // ABSL_STATUS_STATUS_H_ diff --git a/third_party/abseil_cpp/absl/status/status_payload_printer.cc b/third_party/abseil_cpp/absl/status/status_payload_printer.cc deleted file mode 100644 index a47aea11c2..0000000000 --- a/third_party/abseil_cpp/absl/status/status_payload_printer.cc +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright 2019 The Abseil Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// 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. -#include "absl/status/status_payload_printer.h" - -#include <atomic> - -#include "absl/base/attributes.h" -#include "absl/base/internal/atomic_hook.h" - -namespace absl { -ABSL_NAMESPACE_BEGIN -namespace status_internal { - -ABSL_INTERNAL_ATOMIC_HOOK_ATTRIBUTES -static absl::base_internal::AtomicHook<StatusPayloadPrinter> storage; - -void SetStatusPayloadPrinter(StatusPayloadPrinter printer) { - storage.Store(printer); -} - -StatusPayloadPrinter GetStatusPayloadPrinter() { - return storage.Load(); -} - -} // namespace status_internal -ABSL_NAMESPACE_END -} // namespace absl diff --git a/third_party/abseil_cpp/absl/status/status_payload_printer.h b/third_party/abseil_cpp/absl/status/status_payload_printer.h deleted file mode 100644 index 5e0937f67d..0000000000 --- a/third_party/abseil_cpp/absl/status/status_payload_printer.h +++ /dev/null @@ -1,51 +0,0 @@ -// Copyright 2019 The Abseil Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// 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. -#ifndef ABSL_STATUS_STATUS_PAYLOAD_PRINTER_H_ -#define ABSL_STATUS_STATUS_PAYLOAD_PRINTER_H_ - -#include <string> - -#include "absl/strings/cord.h" -#include "absl/strings/string_view.h" -#include "absl/types/optional.h" - -namespace absl { -ABSL_NAMESPACE_BEGIN -namespace status_internal { - -// By default, `Status::ToString` and `operator<<(Status)` print a payload by -// dumping the type URL and the raw bytes. To help debugging, we provide an -// extension point, which is a global printer function that can be set by users -// to specify how to print payloads. The function takes the type URL and the -// payload as input, and should return a valid human-readable string on success -// or `absl::nullopt` on failure (in which case it falls back to the default -// approach of printing the raw bytes). -// NOTE: This is an internal API and the design is subject to change in the -// future in a non-backward-compatible way. Since it's only meant for debugging -// purpose, you should not rely on it in any critical logic. -using StatusPayloadPrinter = absl::optional<std::string> (*)(absl::string_view, - const absl::Cord&); - -// Sets the global payload printer. Only one printer should be set per process. -// If multiple printers are set, it's undefined which one will be used. -void SetStatusPayloadPrinter(StatusPayloadPrinter); - -// Returns the global payload printer if previously set, otherwise `nullptr`. -StatusPayloadPrinter GetStatusPayloadPrinter(); - -} // namespace status_internal -ABSL_NAMESPACE_END -} // namespace absl - -#endif // ABSL_STATUS_STATUS_PAYLOAD_PRINTER_H_ diff --git a/third_party/abseil_cpp/absl/status/status_test.cc b/third_party/abseil_cpp/absl/status/status_test.cc deleted file mode 100644 index ca9488ad22..0000000000 --- a/third_party/abseil_cpp/absl/status/status_test.cc +++ /dev/null @@ -1,458 +0,0 @@ -// Copyright 2019 The Abseil Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// 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. - -#include "absl/status/status.h" - -#include "gmock/gmock.h" -#include "gtest/gtest.h" -#include "absl/strings/str_cat.h" - -namespace { - -using ::testing::Eq; -using ::testing::HasSubstr; -using ::testing::Optional; -using ::testing::UnorderedElementsAreArray; - -TEST(StatusCode, InsertionOperator) { - const absl::StatusCode code = absl::StatusCode::kUnknown; - std::ostringstream oss; - oss << code; - EXPECT_EQ(oss.str(), absl::StatusCodeToString(code)); -} - -// This structure holds the details for testing a single error code, -// its creator, and its classifier. -struct ErrorTest { - absl::StatusCode code; - using Creator = absl::Status (*)(absl::string_view); - using Classifier = bool (*)(const absl::Status&); - Creator creator; - Classifier classifier; -}; - -constexpr ErrorTest kErrorTests[]{ - {absl::StatusCode::kCancelled, absl::CancelledError, absl::IsCancelled}, - {absl::StatusCode::kUnknown, absl::UnknownError, absl::IsUnknown}, - {absl::StatusCode::kInvalidArgument, absl::InvalidArgumentError, - absl::IsInvalidArgument}, - {absl::StatusCode::kDeadlineExceeded, absl::DeadlineExceededError, - absl::IsDeadlineExceeded}, - {absl::StatusCode::kNotFound, absl::NotFoundError, absl::IsNotFound}, - {absl::StatusCode::kAlreadyExists, absl::AlreadyExistsError, - absl::IsAlreadyExists}, - {absl::StatusCode::kPermissionDenied, absl::PermissionDeniedError, - absl::IsPermissionDenied}, - {absl::StatusCode::kResourceExhausted, absl::ResourceExhaustedError, - absl::IsResourceExhausted}, - {absl::StatusCode::kFailedPrecondition, absl::FailedPreconditionError, - absl::IsFailedPrecondition}, - {absl::StatusCode::kAborted, absl::AbortedError, absl::IsAborted}, - {absl::StatusCode::kOutOfRange, absl::OutOfRangeError, absl::IsOutOfRange}, - {absl::StatusCode::kUnimplemented, absl::UnimplementedError, - absl::IsUnimplemented}, - {absl::StatusCode::kInternal, absl::InternalError, absl::IsInternal}, - {absl::StatusCode::kUnavailable, absl::UnavailableError, - absl::IsUnavailable}, - {absl::StatusCode::kDataLoss, absl::DataLossError, absl::IsDataLoss}, - {absl::StatusCode::kUnauthenticated, absl::UnauthenticatedError, - absl::IsUnauthenticated}, -}; - -TEST(Status, CreateAndClassify) { - for (const auto& test : kErrorTests) { - SCOPED_TRACE(absl::StatusCodeToString(test.code)); - - // Ensure that the creator does, in fact, create status objects with the - // expected error code and message. - std::string message = - absl::StrCat("error code ", test.code, " test message"); - absl::Status status = test.creator(message); - EXPECT_EQ(test.code, status.code()); - EXPECT_EQ(message, status.message()); - - // Ensure that the classifier returns true for a status produced by the - // creator. - EXPECT_TRUE(test.classifier(status)); - - // Ensure that the classifier returns false for status with a different - // code. - for (const auto& other : kErrorTests) { - if (other.code != test.code) { - EXPECT_FALSE(test.classifier(absl::Status(other.code, ""))) - << " other.code = " << other.code; - } - } - } -} - -TEST(Status, DefaultConstructor) { - absl::Status status; - EXPECT_TRUE(status.ok()); - EXPECT_EQ(absl::StatusCode::kOk, status.code()); - EXPECT_EQ("", status.message()); -} - -TEST(Status, OkStatus) { - absl::Status status = absl::OkStatus(); - EXPECT_TRUE(status.ok()); - EXPECT_EQ(absl::StatusCode::kOk, status.code()); - EXPECT_EQ("", status.message()); -} - -TEST(Status, ConstructorWithCodeMessage) { - { - absl::Status status(absl::StatusCode::kCancelled, ""); - EXPECT_FALSE(status.ok()); - EXPECT_EQ(absl::StatusCode::kCancelled, status.code()); - EXPECT_EQ("", status.message()); - } - { - absl::Status status(absl::StatusCode::kInternal, "message"); - EXPECT_FALSE(status.ok()); - EXPECT_EQ(absl::StatusCode::kInternal, status.code()); - EXPECT_EQ("message", status.message()); - } -} - -TEST(Status, ConstructOutOfRangeCode) { - const int kRawCode = 9999; - absl::Status status(static_cast<absl::StatusCode>(kRawCode), ""); - EXPECT_EQ(absl::StatusCode::kUnknown, status.code()); - EXPECT_EQ(kRawCode, status.raw_code()); -} - -constexpr char kUrl1[] = "url.payload.1"; -constexpr char kUrl2[] = "url.payload.2"; -constexpr char kUrl3[] = "url.payload.3"; -constexpr char kUrl4[] = "url.payload.xx"; - -constexpr char kPayload1[] = "aaaaa"; -constexpr char kPayload2[] = "bbbbb"; -constexpr char kPayload3[] = "ccccc"; - -using PayloadsVec = std::vector<std::pair<std::string, absl::Cord>>; - -TEST(Status, TestGetSetPayload) { - absl::Status ok_status = absl::OkStatus(); - ok_status.SetPayload(kUrl1, absl::Cord(kPayload1)); - ok_status.SetPayload(kUrl2, absl::Cord(kPayload2)); - - EXPECT_FALSE(ok_status.GetPayload(kUrl1)); - EXPECT_FALSE(ok_status.GetPayload(kUrl2)); - - absl::Status bad_status(absl::StatusCode::kInternal, "fail"); - bad_status.SetPayload(kUrl1, absl::Cord(kPayload1)); - bad_status.SetPayload(kUrl2, absl::Cord(kPayload2)); - - EXPECT_THAT(bad_status.GetPayload(kUrl1), Optional(Eq(kPayload1))); - EXPECT_THAT(bad_status.GetPayload(kUrl2), Optional(Eq(kPayload2))); - - EXPECT_FALSE(bad_status.GetPayload(kUrl3)); - - bad_status.SetPayload(kUrl1, absl::Cord(kPayload3)); - EXPECT_THAT(bad_status.GetPayload(kUrl1), Optional(Eq(kPayload3))); - - // Testing dynamically generated type_url - bad_status.SetPayload(absl::StrCat(kUrl1, ".1"), absl::Cord(kPayload1)); - EXPECT_THAT(bad_status.GetPayload(absl::StrCat(kUrl1, ".1")), - Optional(Eq(kPayload1))); -} - -TEST(Status, TestErasePayload) { - absl::Status bad_status(absl::StatusCode::kInternal, "fail"); - bad_status.SetPayload(kUrl1, absl::Cord(kPayload1)); - bad_status.SetPayload(kUrl2, absl::Cord(kPayload2)); - bad_status.SetPayload(kUrl3, absl::Cord(kPayload3)); - - EXPECT_FALSE(bad_status.ErasePayload(kUrl4)); - - EXPECT_TRUE(bad_status.GetPayload(kUrl2)); - EXPECT_TRUE(bad_status.ErasePayload(kUrl2)); - EXPECT_FALSE(bad_status.GetPayload(kUrl2)); - EXPECT_FALSE(bad_status.ErasePayload(kUrl2)); - - EXPECT_TRUE(bad_status.ErasePayload(kUrl1)); - EXPECT_TRUE(bad_status.ErasePayload(kUrl3)); - - bad_status.SetPayload(kUrl1, absl::Cord(kPayload1)); - EXPECT_TRUE(bad_status.ErasePayload(kUrl1)); -} - -TEST(Status, TestComparePayloads) { - absl::Status bad_status1(absl::StatusCode::kInternal, "fail"); - bad_status1.SetPayload(kUrl1, absl::Cord(kPayload1)); - bad_status1.SetPayload(kUrl2, absl::Cord(kPayload2)); - bad_status1.SetPayload(kUrl3, absl::Cord(kPayload3)); - - absl::Status bad_status2(absl::StatusCode::kInternal, "fail"); - bad_status2.SetPayload(kUrl2, absl::Cord(kPayload2)); - bad_status2.SetPayload(kUrl3, absl::Cord(kPayload3)); - bad_status2.SetPayload(kUrl1, absl::Cord(kPayload1)); - - EXPECT_EQ(bad_status1, bad_status2); -} - -TEST(Status, TestComparePayloadsAfterErase) { - absl::Status payload_status(absl::StatusCode::kInternal, ""); - payload_status.SetPayload(kUrl1, absl::Cord(kPayload1)); - payload_status.SetPayload(kUrl2, absl::Cord(kPayload2)); - - absl::Status empty_status(absl::StatusCode::kInternal, ""); - - // Different payloads, not equal - EXPECT_NE(payload_status, empty_status); - EXPECT_TRUE(payload_status.ErasePayload(kUrl1)); - - // Still Different payloads, still not equal. - EXPECT_NE(payload_status, empty_status); - EXPECT_TRUE(payload_status.ErasePayload(kUrl2)); - - // Both empty payloads, should be equal - EXPECT_EQ(payload_status, empty_status); -} - -PayloadsVec AllVisitedPayloads(const absl::Status& s) { - PayloadsVec result; - - s.ForEachPayload([&](absl::string_view type_url, const absl::Cord& payload) { - result.push_back(std::make_pair(std::string(type_url), payload)); - }); - - return result; -} - -TEST(Status, TestForEachPayload) { - absl::Status bad_status(absl::StatusCode::kInternal, "fail"); - bad_status.SetPayload(kUrl1, absl::Cord(kPayload1)); - bad_status.SetPayload(kUrl2, absl::Cord(kPayload2)); - bad_status.SetPayload(kUrl3, absl::Cord(kPayload3)); - - int count = 0; - - bad_status.ForEachPayload( - [&count](absl::string_view, const absl::Cord&) { ++count; }); - - EXPECT_EQ(count, 3); - - PayloadsVec expected_payloads = {{kUrl1, absl::Cord(kPayload1)}, - {kUrl2, absl::Cord(kPayload2)}, - {kUrl3, absl::Cord(kPayload3)}}; - - // Test that we visit all the payloads in the status. - PayloadsVec visited_payloads = AllVisitedPayloads(bad_status); - EXPECT_THAT(visited_payloads, UnorderedElementsAreArray(expected_payloads)); - - // Test that visitation order is not consistent between run. - std::vector<absl::Status> scratch; - while (true) { - scratch.emplace_back(absl::StatusCode::kInternal, "fail"); - - scratch.back().SetPayload(kUrl1, absl::Cord(kPayload1)); - scratch.back().SetPayload(kUrl2, absl::Cord(kPayload2)); - scratch.back().SetPayload(kUrl3, absl::Cord(kPayload3)); - - if (AllVisitedPayloads(scratch.back()) != visited_payloads) { - break; - } - } -} - -TEST(Status, ToString) { - absl::Status s(absl::StatusCode::kInternal, "fail"); - EXPECT_EQ("INTERNAL: fail", s.ToString()); - s.SetPayload("foo", absl::Cord("bar")); - EXPECT_EQ("INTERNAL: fail [foo='bar']", s.ToString()); - s.SetPayload("bar", absl::Cord("\377")); - EXPECT_THAT(s.ToString(), - AllOf(HasSubstr("INTERNAL: fail"), HasSubstr("[foo='bar']"), - HasSubstr("[bar='\\xff']"))); -} - -absl::Status EraseAndReturn(const absl::Status& base) { - absl::Status copy = base; - EXPECT_TRUE(copy.ErasePayload(kUrl1)); - return copy; -} - -TEST(Status, CopyOnWriteForErasePayload) { - { - absl::Status base(absl::StatusCode::kInvalidArgument, "fail"); - base.SetPayload(kUrl1, absl::Cord(kPayload1)); - EXPECT_TRUE(base.GetPayload(kUrl1).has_value()); - absl::Status copy = EraseAndReturn(base); - EXPECT_TRUE(base.GetPayload(kUrl1).has_value()); - EXPECT_FALSE(copy.GetPayload(kUrl1).has_value()); - } - { - absl::Status base(absl::StatusCode::kInvalidArgument, "fail"); - base.SetPayload(kUrl1, absl::Cord(kPayload1)); - absl::Status copy = base; - - EXPECT_TRUE(base.GetPayload(kUrl1).has_value()); - EXPECT_TRUE(copy.GetPayload(kUrl1).has_value()); - - EXPECT_TRUE(base.ErasePayload(kUrl1)); - - EXPECT_FALSE(base.GetPayload(kUrl1).has_value()); - EXPECT_TRUE(copy.GetPayload(kUrl1).has_value()); - } -} - -TEST(Status, CopyConstructor) { - { - absl::Status status; - absl::Status copy(status); - EXPECT_EQ(copy, status); - } - { - absl::Status status(absl::StatusCode::kInvalidArgument, "message"); - absl::Status copy(status); - EXPECT_EQ(copy, status); - } - { - absl::Status status(absl::StatusCode::kInvalidArgument, "message"); - status.SetPayload(kUrl1, absl::Cord(kPayload1)); - absl::Status copy(status); - EXPECT_EQ(copy, status); - } -} - -TEST(Status, CopyAssignment) { - absl::Status assignee; - { - absl::Status status; - assignee = status; - EXPECT_EQ(assignee, status); - } - { - absl::Status status(absl::StatusCode::kInvalidArgument, "message"); - assignee = status; - EXPECT_EQ(assignee, status); - } - { - absl::Status status(absl::StatusCode::kInvalidArgument, "message"); - status.SetPayload(kUrl1, absl::Cord(kPayload1)); - assignee = status; - EXPECT_EQ(assignee, status); - } -} - -TEST(Status, CopyAssignmentIsNotRef) { - const absl::Status status_orig(absl::StatusCode::kInvalidArgument, "message"); - absl::Status status_copy = status_orig; - EXPECT_EQ(status_orig, status_copy); - status_copy.SetPayload(kUrl1, absl::Cord(kPayload1)); - EXPECT_NE(status_orig, status_copy); -} - -TEST(Status, MoveConstructor) { - { - absl::Status status; - absl::Status copy(absl::Status{}); - EXPECT_EQ(copy, status); - } - { - absl::Status status(absl::StatusCode::kInvalidArgument, "message"); - absl::Status copy( - absl::Status(absl::StatusCode::kInvalidArgument, "message")); - EXPECT_EQ(copy, status); - } - { - absl::Status status(absl::StatusCode::kInvalidArgument, "message"); - status.SetPayload(kUrl1, absl::Cord(kPayload1)); - absl::Status copy1(status); - absl::Status copy2(std::move(status)); - EXPECT_EQ(copy1, copy2); - } -} - -TEST(Status, MoveAssignment) { - absl::Status assignee; - { - absl::Status status; - assignee = absl::Status(); - EXPECT_EQ(assignee, status); - } - { - absl::Status status(absl::StatusCode::kInvalidArgument, "message"); - assignee = absl::Status(absl::StatusCode::kInvalidArgument, "message"); - EXPECT_EQ(assignee, status); - } - { - absl::Status status(absl::StatusCode::kInvalidArgument, "message"); - status.SetPayload(kUrl1, absl::Cord(kPayload1)); - absl::Status copy(status); - assignee = std::move(status); - EXPECT_EQ(assignee, copy); - } -} - -TEST(Status, Update) { - absl::Status s; - s.Update(absl::OkStatus()); - EXPECT_TRUE(s.ok()); - const absl::Status a(absl::StatusCode::kCancelled, "message"); - s.Update(a); - EXPECT_EQ(s, a); - const absl::Status b(absl::StatusCode::kInternal, "other message"); - s.Update(b); - EXPECT_EQ(s, a); - s.Update(absl::OkStatus()); - EXPECT_EQ(s, a); - EXPECT_FALSE(s.ok()); -} - -TEST(Status, Equality) { - absl::Status ok; - absl::Status no_payload = absl::CancelledError("no payload"); - absl::Status one_payload = absl::InvalidArgumentError("one payload"); - one_payload.SetPayload(kUrl1, absl::Cord(kPayload1)); - absl::Status two_payloads = one_payload; - two_payloads.SetPayload(kUrl2, absl::Cord(kPayload2)); - const std::array<absl::Status, 4> status_arr = {ok, no_payload, one_payload, - two_payloads}; - for (int i = 0; i < status_arr.size(); i++) { - for (int j = 0; j < status_arr.size(); j++) { - if (i == j) { - EXPECT_TRUE(status_arr[i] == status_arr[j]); - EXPECT_FALSE(status_arr[i] != status_arr[j]); - } else { - EXPECT_TRUE(status_arr[i] != status_arr[j]); - EXPECT_FALSE(status_arr[i] == status_arr[j]); - } - } - } -} - -TEST(Status, Swap) { - auto test_swap = [](const absl::Status& s1, const absl::Status& s2) { - absl::Status copy1 = s1, copy2 = s2; - swap(copy1, copy2); - EXPECT_EQ(copy1, s2); - EXPECT_EQ(copy2, s1); - }; - const absl::Status ok; - const absl::Status no_payload(absl::StatusCode::kAlreadyExists, "no payload"); - absl::Status with_payload(absl::StatusCode::kInternal, "with payload"); - with_payload.SetPayload(kUrl1, absl::Cord(kPayload1)); - test_swap(ok, no_payload); - test_swap(no_payload, ok); - test_swap(ok, with_payload); - test_swap(with_payload, ok); - test_swap(no_payload, with_payload); - test_swap(with_payload, no_payload); -} - -} // namespace diff --git a/third_party/abseil_cpp/absl/status/statusor.cc b/third_party/abseil_cpp/absl/status/statusor.cc deleted file mode 100644 index 2d22adb276..0000000000 --- a/third_party/abseil_cpp/absl/status/statusor.cc +++ /dev/null @@ -1,48 +0,0 @@ -/* 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. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -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. -==============================================================================*/ - -#include "absl/status/statusor.h" - -#include "absl/base/internal/raw_logging.h" - -namespace absl { -ABSL_NAMESPACE_BEGIN - -namespace internal_statusor { - -#define ABSL_STATUSOR_INTERNAL_BAD_OK_MSG "An OK status is not a valid " \ - "constructor argument to StatusOr<T>" - -void Helper::HandleInvalidStatusCtorArg(Status* status) { - ABSL_RAW_LOG(ERROR, ABSL_STATUSOR_INTERNAL_BAD_OK_MSG); - // Fall back to kInternal. - *status = InternalError(ABSL_STATUSOR_INTERNAL_BAD_OK_MSG); -} - -#undef ABSL_STATUSOR_INTERNAL_BAD_OK_MSG - -void Helper::Crash(const Status& status) { -#ifdef ABSL_HAVE_EXCEPTIONS - throw status; -#else - std::string status_debug = status.ToString(); - ABSL_RAW_LOG(FATAL, "Attempting to fetch value instead of handling error: %s", status_debug.c_str()); - abort(); // TODO(calabrese) Remove once RAW_LOG FATAL is noreturn. -#endif -} -} // namespace internal_statusor - -ABSL_NAMESPACE_END -} // namespace absl diff --git a/third_party/abseil_cpp/absl/status/statusor.h b/third_party/abseil_cpp/absl/status/statusor.h deleted file mode 100644 index 59a52cb782..0000000000 --- a/third_party/abseil_cpp/absl/status/statusor.h +++ /dev/null @@ -1,394 +0,0 @@ -/* 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. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -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 StatusCode::kOk. -// -// 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 absl::InvalidArgumentError("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 ABSL_STATUS_STATUSOR_H_ -#define ABSL_STATUS_STATUSOR_H_ - -#include "absl/status/status.h" -#include "absl/status/statusor_internals.h" - -namespace absl { -ABSL_NAMESPACE_BEGIN - -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; // DEPRECATED: use `value_type`. - typedef T value_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 enforced with either an - // exception (the passed absl::Status) or a FATAL log. - 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 OkStatus(). - 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() &&; - - // Returns a reference to the current value. - // - // REQUIRES: this->ok() == true, otherwise the behavior is undefined. - // - // Use this->ok() or `operator bool()` to verify that there is a current - // value. Alternatively, see ValueOrDie() for a similar API that guarantees - // CHECK-failing if there is no current value. - const T& operator*() const&; - T& operator*() &; - const T&& operator*() const&&; - T&& operator*() &&; - - // Returns a pointer to the current value. - // - // REQUIRES: this->ok() == true, otherwise the behavior is undefined. - // - // Use this->ok() or `operator bool()` to verify that there is a current - // value. - const T* operator->() const; - T* operator->(); - - 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(StatusCode::kUnknown, "")) {} - -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() && { - // Note that we copy instead of moving the status here so that - // ~StatusOrData() can call ok() without invoking UB. - return ok() ? OkStatus() : 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> -const T* StatusOr<T>::operator->() const { - this->EnsureOk(); - return &this->data_; -} - -template <typename T> -T* StatusOr<T>::operator->() { - this->EnsureOk(); - return &this->data_; -} - -template <typename T> -const T& StatusOr<T>::operator*() const& { - this->EnsureOk(); - return this->data_; -} - -template <typename T> -T& StatusOr<T>::operator*() & { - this->EnsureOk(); - return this->data_; -} - -template <typename T> -const T&& StatusOr<T>::operator*() const&& { - this->EnsureOk(); - return std::move(this->data_); -} - -template <typename T> -T&& StatusOr<T>::operator*() && { - this->EnsureOk(); - return std::move(this->data_); -} - -template <typename T> -void StatusOr<T>::IgnoreError() const { - // no-op -} - -ABSL_NAMESPACE_END -} // namespace absl - -#define ASSERT_OK_AND_ASSIGN(lhs, rexpr) \ - ABSL_ASSERT_OK_AND_ASSIGN_IMPL( \ - ABSL_STATUS_MACROS_CONCAT_NAME(_status_or_value, __COUNTER__), lhs, \ - rexpr); - -#define ABSL_ASSERT_OK_AND_ASSIGN_IMPL(statusor, lhs, rexpr) \ - auto statusor = (rexpr); \ - ASSERT_TRUE(statusor.status().ok()) << statusor.status(); \ - lhs = std::move(statusor.ValueOrDie()) - -#define ABSL_STATUS_MACROS_CONCAT_NAME(x, y) ABSL_STATUS_MACROS_CONCAT_IMPL(x, y) -#define ABSL_STATUS_MACROS_CONCAT_IMPL(x, y) x##y - -#define ASSIGN_OR_RETURN(lhs, rexpr) \ - ABSL_ASSIGN_OR_RETURN_IMPL( \ - ABSL_STATUS_MACROS_CONCAT_NAME(_status_or_value, __COUNTER__), lhs, rexpr) - -#define ABSL_ASSIGN_OR_RETURN_IMPL(statusor, lhs, rexpr) \ - auto statusor = (rexpr); \ - if (ABSL_PREDICT_FALSE(!statusor.ok())) { \ - return statusor.status(); \ - } \ - lhs = std::move(statusor.ValueOrDie()) - -#define RETURN_IF_ERROR(status) \ - do { \ - if (ABSL_PREDICT_FALSE(!status.ok())) { \ - return status; \ - } \ - } while(0) - -#endif // ABSL_STATUS_STATUSOR_H_ diff --git a/third_party/abseil_cpp/absl/status/statusor_internals.h b/third_party/abseil_cpp/absl/status/statusor_internals.h deleted file mode 100644 index 5366c2840c..0000000000 --- a/third_party/abseil_cpp/absl/status/statusor_internals.h +++ /dev/null @@ -1,250 +0,0 @@ -/* 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. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -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. -==============================================================================*/ - -#ifndef ABSL_STATUS_STATUSOR_INTERNALS_H_ -#define ABSL_STATUS_STATUSOR_INTERNALS_H_ - -#include "absl/status/status.h" - -namespace absl { -ABSL_NAMESPACE_BEGIN - -namespace internal_statusor { - -class Helper { - public: - // Move type-agnostic error handling to the .cc. - static void HandleInvalidStatusCtorArg(Status*); - ABSL_ATTRIBUTE_NORETURN static void Crash(const Status& status); -}; - -// Construct an instance of T in `p` through placement new, passing Args... to -// the constructor. -// This abstraction is here mostly for the gcc performance fix. -template <typename T, typename... Args> -void PlacementNew(void* p, Args&&... args) { -#if defined(__GNUC__) && !defined(__clang__) - // Teach gcc that 'p' cannot be null, fixing code size issues. - if (p == nullptr) __builtin_unreachable(); -#endif - new (p) T(std::forward<Args>(args)...); -} - -// Helper base class to hold the data and all operations. -// We move all this to a base class to allow mixing with the appropriate -// TraitsBase specialization. -template <typename T> -class StatusOrData { - template <typename U> - friend class StatusOrData; - - public: - StatusOrData() = delete; - - StatusOrData(const StatusOrData& other) { - if (other.ok()) { - MakeValue(other.data_); - MakeStatus(); - } else { - MakeStatus(other.status_); - } - } - - StatusOrData(StatusOrData&& other) noexcept { - if (other.ok()) { - MakeValue(std::move(other.data_)); - MakeStatus(); - } else { - MakeStatus(other.status_); - } - } - - template <typename U> - StatusOrData(const StatusOrData<U>& other) { - if (other.ok()) { - MakeValue(other.data_); - MakeStatus(); - } else { - MakeStatus(other.status_); - } - } - - template <typename U> - StatusOrData(StatusOrData<U>&& other) { - if (other.ok()) { - MakeValue(std::move(other.data_)); - MakeStatus(); - } else { - MakeStatus(other.status_); - } - } - - explicit StatusOrData(const T& value) : data_(value) { MakeStatus(); } - explicit StatusOrData(T&& value) : data_(std::move(value)) { MakeStatus(); } - - explicit StatusOrData(const Status& status) : status_(status) { - EnsureNotOk(); - } - explicit StatusOrData(Status&& status) : status_(std::move(status)) { - EnsureNotOk(); - } - - StatusOrData& operator=(const StatusOrData& other) { - if (this == &other) return *this; - if (other.ok()) - Assign(other.data_); - else - Assign(other.status_); - return *this; - } - - StatusOrData& operator=(StatusOrData&& other) { - if (this == &other) return *this; - if (other.ok()) - Assign(std::move(other.data_)); - else - Assign(std::move(other.status_)); - return *this; - } - - ~StatusOrData() { - if (ok()) { - status_.~Status(); - data_.~T(); - } else { - status_.~Status(); - } - } - - void Assign(const T& value) { - if (ok()) { - data_.~T(); - MakeValue(value); - } else { - MakeValue(value); - status_ = OkStatus(); - } - } - - void Assign(T&& value) { - if (ok()) { - data_.~T(); - MakeValue(std::move(value)); - } else { - MakeValue(std::move(value)); - status_ = OkStatus(); - } - } - - void Assign(const Status& status) { - Clear(); - status_ = status; - EnsureNotOk(); - } - - void Assign(Status&& status) { - Clear(); - // Note that we copy instead of moving the status here so that - // status.~StatusOrData() can call ok() without invoking UB. - status_ = status; - EnsureNotOk(); - } - - bool ok() const { return status_.ok(); } - - protected: - // status_ will always be active after the constructor. - // We make it a union to be able to initialize exactly how we need without - // waste. - // Eg. in the copy constructor we use the default constructor of Status in - // the ok() path to avoid an extra Ref call. - union { - Status status_; - }; - - // data_ is active iff status_.ok()==true - struct Dummy {}; - union { - // When T is const, we need some non-const object we can cast to void* for - // the placement new. dummy_ is that object. - Dummy dummy_; - T data_; - }; - - void Clear() { - if (ok()) data_.~T(); - } - - void EnsureOk() const { - if (!ok()) Helper::Crash(status_); - } - - void EnsureNotOk() { - if (ok()) Helper::HandleInvalidStatusCtorArg(&status_); - } - - // Construct the value (ie. data_) through placement new with the passed - // argument. - template <typename Arg> - void MakeValue(Arg&& arg) { - internal_statusor::PlacementNew<T>(&dummy_, std::forward<Arg>(arg)); - } - - // Construct the status (ie. status_) through placement new with the passed - // argument. - template <typename... Args> - void MakeStatus(Args&&... args) { - internal_statusor::PlacementNew<Status>(&status_, - std::forward<Args>(args)...); - } -}; - -// Helper base class to allow implicitly deleted constructors and assignment -// operations in StatusOr. -// TraitsBase will explicitly delete what it can't support and StatusOr will -// inherit that behavior implicitly. -template <bool Copy, bool Move> -struct TraitsBase { - TraitsBase() = default; - TraitsBase(const TraitsBase&) = default; - TraitsBase(TraitsBase&&) = default; - TraitsBase& operator=(const TraitsBase&) = default; - TraitsBase& operator=(TraitsBase&&) = default; -}; - -template <> -struct TraitsBase<false, true> { - TraitsBase() = default; - TraitsBase(const TraitsBase&) = delete; - TraitsBase(TraitsBase&&) = default; - TraitsBase& operator=(const TraitsBase&) = delete; - TraitsBase& operator=(TraitsBase&&) = default; -}; - -template <> -struct TraitsBase<false, false> { - TraitsBase() = default; - TraitsBase(const TraitsBase&) = delete; - TraitsBase(TraitsBase&&) = delete; - TraitsBase& operator=(const TraitsBase&) = delete; - TraitsBase& operator=(TraitsBase&&) = delete; -}; - -} // namespace internal_statusor - -ABSL_NAMESPACE_END -} // namespace absl - -#endif // ABSL_STATUS_STATUSOR_INTERNALS_H_ diff --git a/third_party/abseil_cpp/absl/status/statusor_test.cc b/third_party/abseil_cpp/absl/status/statusor_test.cc deleted file mode 100644 index fc849515ca..0000000000 --- a/third_party/abseil_cpp/absl/status/statusor_test.cc +++ /dev/null @@ -1,753 +0,0 @@ -/* 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. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -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. -==============================================================================*/ - -// Unit tests for StatusOr - -#include "absl/status/statusor.h" - -#include <memory> -#include <type_traits> - -#include "absl/base/internal/exception_testing.h" -#include "gtest/gtest.h" - -namespace absl { -ABSL_NAMESPACE_BEGIN - -namespace { - -class Base1 { - public: - virtual ~Base1() {} - int pad_; -}; - -class Base2 { - public: - virtual ~Base2() {} - int yetotherpad_; -}; - -class Derived : public Base1, public Base2 { - public: - ~Derived() override {} - int evenmorepad_; -}; - -class CopyNoAssign { - public: - explicit CopyNoAssign(int value) : foo_(value) {} - CopyNoAssign(const CopyNoAssign& other) : foo_(other.foo_) {} - int foo_; - - private: - const CopyNoAssign& operator=(const CopyNoAssign&); -}; - -class NoDefaultConstructor { - public: - explicit NoDefaultConstructor(int foo); -}; - -static_assert(!std::is_default_constructible<NoDefaultConstructor>(), - "Should not be default-constructible."); - -StatusOr<std::unique_ptr<int>> ReturnUniquePtr() { - // Uses implicit constructor from T&& - return std::unique_ptr<int>(new int(0)); -} - -TEST(StatusOr, ElementType) { - static_assert(std::is_same<StatusOr<int>::element_type, int>(), ""); - static_assert(std::is_same<StatusOr<char>::element_type, char>(), ""); -} - -TEST(StatusOr, NullPointerStatusOr) { - // As a very special case, null-plain-pointer StatusOr used to be an - // error. Test that it no longer is. - StatusOr<int*> null_status(nullptr); - EXPECT_TRUE(null_status.ok()); - EXPECT_EQ(null_status.ValueOrDie(), nullptr); -} - -TEST(StatusOr, TestNoDefaultConstructorInitialization) { - // Explicitly initialize it with an error code. - StatusOr<NoDefaultConstructor> statusor(CancelledError("")); - EXPECT_FALSE(statusor.ok()); - EXPECT_EQ(statusor.status().code(), absl::StatusCode::kCancelled); - - // Default construction of StatusOr initializes it with an UNKNOWN error code. - StatusOr<NoDefaultConstructor> statusor2; - EXPECT_FALSE(statusor2.ok()); - EXPECT_EQ(statusor2.status().code(), absl::StatusCode::kUnknown); -} - -TEST(StatusOr, TestMoveOnlyInitialization) { - StatusOr<std::unique_ptr<int>> thing(ReturnUniquePtr()); - ASSERT_TRUE(thing.ok()); - EXPECT_EQ(0, *thing.ValueOrDie()); - int* previous = thing.ValueOrDie().get(); - - thing = ReturnUniquePtr(); - EXPECT_TRUE(thing.ok()); - EXPECT_EQ(0, *thing.ValueOrDie()); - EXPECT_NE(previous, thing.ValueOrDie().get()); -} - -TEST(StatusOr, TestMoveOnlyStatusCtr) { - StatusOr<std::unique_ptr<int>> thing(CancelledError("")); - ASSERT_FALSE(thing.ok()); -} - -TEST(StatusOr, TestMoveOnlyValueExtraction) { - StatusOr<std::unique_ptr<int>> thing(ReturnUniquePtr()); - ASSERT_TRUE(thing.ok()); - std::unique_ptr<int> ptr = thing.ConsumeValueOrDie(); - EXPECT_EQ(0, *ptr); - - thing = std::move(ptr); - ptr = std::move(thing.ValueOrDie()); - EXPECT_EQ(0, *ptr); -} - -TEST(StatusOr, TestMoveOnlyConversion) { - StatusOr<std::unique_ptr<const int>> const_thing(ReturnUniquePtr()); - EXPECT_TRUE(const_thing.ok()); - EXPECT_EQ(0, *const_thing.ValueOrDie()); - - // Test rvalue converting assignment - const int* const_previous = const_thing.ValueOrDie().get(); - const_thing = ReturnUniquePtr(); - EXPECT_TRUE(const_thing.ok()); - EXPECT_EQ(0, *const_thing.ValueOrDie()); - EXPECT_NE(const_previous, const_thing.ValueOrDie().get()); -} - -TEST(StatusOr, TestMoveOnlyVector) { - // Sanity check that StatusOr<MoveOnly> works in vector. - std::vector<StatusOr<std::unique_ptr<int>>> vec; - vec.push_back(ReturnUniquePtr()); - vec.resize(2); - auto another_vec = std::move(vec); - EXPECT_EQ(0, *another_vec[0].ValueOrDie()); - EXPECT_EQ(absl::StatusCode::kUnknown, another_vec[1].status().code()); -} - -TEST(StatusOr, TestMoveWithValuesAndErrors) { - StatusOr<std::string> status_or(std::string(1000, '0')); - StatusOr<std::string> value1(std::string(1000, '1')); - StatusOr<std::string> value2(std::string(1000, '2')); - StatusOr<std::string> error1(UnknownError("error1")); - StatusOr<std::string> error2(UnknownError("error2")); - - ASSERT_TRUE(status_or.ok()); - EXPECT_EQ(std::string(1000, '0'), status_or.ValueOrDie()); - - // Overwrite the value in status_or with another value. - status_or = std::move(value1); - ASSERT_TRUE(status_or.ok()); - EXPECT_EQ(std::string(1000, '1'), status_or.ValueOrDie()); - - // Overwrite the value in status_or with an error. - status_or = std::move(error1); - ASSERT_FALSE(status_or.ok()); - EXPECT_EQ("error1", status_or.status().message()); - - // Overwrite the error in status_or with another error. - status_or = std::move(error2); - ASSERT_FALSE(status_or.ok()); - EXPECT_EQ("error2", status_or.status().message()); - - // Overwrite the error with a value. - status_or = std::move(value2); - ASSERT_TRUE(status_or.ok()); - EXPECT_EQ(std::string(1000, '2'), status_or.ValueOrDie()); -} - -TEST(StatusOr, TestCopyWithValuesAndErrors) { - StatusOr<std::string> status_or(std::string(1000, '0')); - StatusOr<std::string> value1(std::string(1000, '1')); - StatusOr<std::string> value2(std::string(1000, '2')); - StatusOr<std::string> error1(UnknownError("error1")); - StatusOr<std::string> error2(UnknownError("error2")); - - ASSERT_TRUE(status_or.ok()); - EXPECT_EQ(std::string(1000, '0'), status_or.ValueOrDie()); - - // Overwrite the value in status_or with another value. - status_or = value1; - ASSERT_TRUE(status_or.ok()); - EXPECT_EQ(std::string(1000, '1'), status_or.ValueOrDie()); - - // Overwrite the value in status_or with an error. - status_or = error1; - ASSERT_FALSE(status_or.ok()); - EXPECT_EQ("error1", status_or.status().message()); - - // Overwrite the error in status_or with another error. - status_or = error2; - ASSERT_FALSE(status_or.ok()); - EXPECT_EQ("error2", status_or.status().message()); - - // Overwrite the error with a value. - status_or = value2; - ASSERT_TRUE(status_or.ok()); - EXPECT_EQ(std::string(1000, '2'), status_or.ValueOrDie()); - - // Verify original values unchanged. - EXPECT_EQ(std::string(1000, '1'), value1.ValueOrDie()); - EXPECT_EQ("error1", error1.status().message()); - EXPECT_EQ("error2", error2.status().message()); - EXPECT_EQ(std::string(1000, '2'), value2.ValueOrDie()); -} - -TEST(StatusOr, TestDefaultCtor) { - StatusOr<int> thing; - EXPECT_FALSE(thing.ok()); - EXPECT_EQ(thing.status().code(), absl::StatusCode::kUnknown); -} - -TEST(StatusOrDeathTest, TestDefaultCtorValue) { - StatusOr<int> thing; - ABSL_BASE_INTERNAL_EXPECT_FAIL(thing.ValueOrDie(), absl::Status, ""); - - const StatusOr<int> thing2; - ABSL_BASE_INTERNAL_EXPECT_FAIL(thing.ValueOrDie(), absl::Status, ""); -} - -TEST(StatusOr, TestStatusCtor) { - StatusOr<int> thing(Status(absl::StatusCode::kCancelled, "")); - EXPECT_FALSE(thing.ok()); - EXPECT_EQ(thing.status().code(), absl::StatusCode::kCancelled); -} - -TEST(StatusOr, TestValueCtor) { - const int kI = 4; - const StatusOr<int> thing(kI); - EXPECT_TRUE(thing.ok()); - EXPECT_EQ(kI, thing.ValueOrDie()); -} - -TEST(StatusOr, TestCopyCtorStatusOk) { - const int kI = 4; - const StatusOr<int> original(kI); - const StatusOr<int> copy(original); - EXPECT_EQ(copy.status(), original.status()); - EXPECT_EQ(original.ValueOrDie(), copy.ValueOrDie()); -} - -TEST(StatusOr, TestCopyCtorStatusNotOk) { - StatusOr<int> original(Status(absl::StatusCode::kCancelled, "")); - StatusOr<int> copy(original); - EXPECT_EQ(copy.status(), original.status()); -} - -TEST(StatusOr, TestCopyCtorNonAssignable) { - const int kI = 4; - CopyNoAssign value(kI); - StatusOr<CopyNoAssign> original(value); - StatusOr<CopyNoAssign> copy(original); - EXPECT_EQ(copy.status(), original.status()); - EXPECT_EQ(original.ValueOrDie().foo_, copy.ValueOrDie().foo_); -} - -TEST(StatusOr, TestCopyCtorStatusOKConverting) { - const int kI = 4; - StatusOr<int> original(kI); - StatusOr<double> copy(original); - EXPECT_EQ(copy.status(), original.status()); - EXPECT_DOUBLE_EQ(original.ValueOrDie(), copy.ValueOrDie()); -} - -TEST(StatusOr, TestCopyCtorStatusNotOkConverting) { - StatusOr<int> original(Status(absl::StatusCode::kCancelled, "")); - StatusOr<double> copy(original); - EXPECT_EQ(copy.status(), original.status()); -} - -TEST(StatusOr, TestAssignmentStatusOk) { - const int kI = 4; - StatusOr<int> source(kI); - StatusOr<int> target; - target = source; - EXPECT_EQ(target.status(), source.status()); - EXPECT_EQ(source.ValueOrDie(), target.ValueOrDie()); -} - -TEST(StatusOr, TestAssignmentStatusNotOk) { - StatusOr<int> source(Status(absl::StatusCode::kCancelled, "")); - StatusOr<int> target; - target = source; - EXPECT_EQ(target.status(), source.status()); -} - -TEST(StatusOr, TestStatus) { - StatusOr<int> good(4); - EXPECT_TRUE(good.ok()); - StatusOr<int> bad(Status(absl::StatusCode::kCancelled, "")); - EXPECT_FALSE(bad.ok()); - EXPECT_EQ(bad.status(), Status(absl::StatusCode::kCancelled, "")); -} - -TEST(StatusOr, TestValue) { - const int kI = 4; - StatusOr<int> thing(kI); - EXPECT_EQ(kI, thing.ValueOrDie()); -} - -TEST(StatusOr, TestValueConst) { - const int kI = 4; - const StatusOr<int> thing(kI); - EXPECT_EQ(kI, thing.ValueOrDie()); -} - -TEST(StatusOrDeathTest, TestValueNotOk) { - StatusOr<int> thing(Status(absl::StatusCode::kCancelled, "cancelled")); - ABSL_BASE_INTERNAL_EXPECT_FAIL(thing.ValueOrDie(), absl::Status, "cancelled"); -} - -TEST(StatusOrDeathTest, TestValueNotOkConst) { - const StatusOr<int> thing(Status(absl::StatusCode::kUnknown, "")); - ABSL_BASE_INTERNAL_EXPECT_FAIL(thing.ValueOrDie(), absl::Status, ""); -} - -TEST(StatusOr, TestPointerDefaultCtor) { - StatusOr<int*> thing; - EXPECT_FALSE(thing.ok()); - EXPECT_EQ(thing.status().code(), absl::StatusCode::kUnknown); -} - -TEST(StatusOrDeathTest, TestPointerDefaultCtorValue) { - StatusOr<int*> thing; - ABSL_BASE_INTERNAL_EXPECT_FAIL(thing.ValueOrDie(), absl::Status, ""); -} - -TEST(StatusOr, TestPointerStatusCtor) { - StatusOr<int*> thing(Status(absl::StatusCode::kCancelled, "")); - EXPECT_FALSE(thing.ok()); - EXPECT_EQ(thing.status(), Status(absl::StatusCode::kCancelled, "")); -} - -TEST(StatusOr, TestPointerValueCtor) { - const int kI = 4; - StatusOr<const int*> thing(&kI); - EXPECT_TRUE(thing.ok()); - EXPECT_EQ(&kI, thing.ValueOrDie()); -} - -TEST(StatusOr, TestPointerCopyCtorStatusOk) { - const int kI = 0; - StatusOr<const int*> original(&kI); - StatusOr<const int*> copy(original); - EXPECT_EQ(copy.status(), original.status()); - EXPECT_EQ(original.ValueOrDie(), copy.ValueOrDie()); -} - -TEST(StatusOr, TestPointerCopyCtorStatusNotOk) { - StatusOr<int*> original(Status(absl::StatusCode::kCancelled, "")); - StatusOr<int*> copy(original); - EXPECT_EQ(copy.status(), original.status()); -} - -TEST(StatusOr, TestPointerCopyCtorStatusOKConverting) { - Derived derived; - StatusOr<Derived*> original(&derived); - StatusOr<Base2*> copy(original); - EXPECT_EQ(copy.status(), original.status()); - EXPECT_EQ(static_cast<const Base2*>(original.ValueOrDie()), - copy.ValueOrDie()); -} - -TEST(StatusOr, TestPointerCopyCtorStatusNotOkConverting) { - StatusOr<Derived*> original(Status(absl::StatusCode::kCancelled, "")); - StatusOr<Base2*> copy(original); - EXPECT_EQ(copy.status(), original.status()); -} - -TEST(StatusOr, TestPointerAssignmentStatusOk) { - const int kI = 0; - StatusOr<const int*> source(&kI); - StatusOr<const int*> target; - target = source; - EXPECT_EQ(target.status(), source.status()); - EXPECT_EQ(source.ValueOrDie(), target.ValueOrDie()); -} - -TEST(StatusOr, TestPointerAssignmentStatusNotOk) { - StatusOr<int*> source(Status(absl::StatusCode::kCancelled, "")); - StatusOr<int*> target; - target = source; - EXPECT_EQ(target.status(), source.status()); -} - -TEST(StatusOr, TestPointerStatus) { - const int kI = 0; - StatusOr<const int*> good(&kI); - EXPECT_TRUE(good.ok()); - StatusOr<const int*> bad(Status(absl::StatusCode::kCancelled, "")); - EXPECT_EQ(bad.status(), Status(absl::StatusCode::kCancelled, "")); -} - -TEST(StatusOr, TestPointerValue) { - const int kI = 0; - StatusOr<const int*> thing(&kI); - EXPECT_EQ(&kI, thing.ValueOrDie()); -} - -TEST(StatusOr, TestPointerValueConst) { - const int kI = 0; - const StatusOr<const int*> thing(&kI); - EXPECT_EQ(&kI, thing.ValueOrDie()); -} - -TEST(StatusOr, TestArrowOperator) { - StatusOr<std::unique_ptr<int>> uptr = ReturnUniquePtr(); - EXPECT_EQ(*uptr->get(), 0); -} - -TEST(StatusOr, TestArrowOperatorNotOk) { - StatusOr<Base1> error(Status(absl::StatusCode::kCancelled, "cancelled")); - ABSL_BASE_INTERNAL_EXPECT_FAIL(error->pad_++, absl::Status, "cancelled"); -} - -TEST(StatusOr, TestStarOperator) { - StatusOr<std::unique_ptr<int>> uptr = ReturnUniquePtr(); - EXPECT_EQ(**uptr, 0); -} - -TEST(StatusOr, TestStarOperatorDeath) { - StatusOr<Base1> error(Status(absl::StatusCode::kCancelled, "cancelled")); - ABSL_BASE_INTERNAL_EXPECT_FAIL(*error, absl::Status, "cancelled"); -} - -// NOTE(tucker): StatusOr does not support this kind -// of resize op. -// TEST(StatusOr, StatusOrVectorOfUniquePointerCanResize) { -// using EvilType = std::vector<std::unique_ptr<int>>; -// static_assert(std::is_copy_constructible<EvilType>::value, ""); -// std::vector<StatusOr<EvilType>> v(5); -// v.reserve(v.capacity() + 10); -// } - -TEST(StatusOrDeathTest, TestPointerValueNotOk) { - StatusOr<int*> thing(Status(absl::StatusCode::kCancelled, "cancelled")); - ABSL_BASE_INTERNAL_EXPECT_FAIL(thing.ValueOrDie(), absl::Status, "cancelled"); -} - -TEST(StatusOrDeathTest, TestPointerValueNotOkConst) { - const StatusOr<int*> thing(Status(absl::StatusCode::kCancelled, "cancelled")); - ABSL_BASE_INTERNAL_EXPECT_FAIL(thing.ValueOrDie(), absl::Status, "cancelled"); -} - -static void AssertOkAndAssignBody(absl::StatusOr<int> consume) { - ASSERT_OK_AND_ASSIGN(int value, consume); - EXPECT_EQ(value, 1); -} - -TEST(StatusOr, TestAssertOkAndAssign) { - const int kI = 1; - AssertOkAndAssignBody(kI); -} - -TEST(StatusOrDeathTest, TestAssertOkAndAssignNotOk) { - // Can't actually test this, as calling ASSERT_TRUE fails the test. -} - -static absl::Status AssignOrReturnBody(absl::StatusOr<int*> maybe) { - ASSIGN_OR_RETURN(int *iptr, maybe); - EXPECT_EQ(*iptr, 1); - *iptr = 4; - return OkStatus(); -} - -TEST(StatusOr, TestAssignOrReturn) { - int i = 1; - EXPECT_TRUE(AssignOrReturnBody(&i).ok()); - EXPECT_EQ(i, 4); -} - -TEST(StatusOr, TestAssignOrReturnNotOk) { - const StatusOr<int*> thing(Status(absl::StatusCode::kCancelled, "cancelled")); - const Status result = AssignOrReturnBody(thing); - EXPECT_FALSE(result.ok()); - EXPECT_EQ(result, thing.status()); -} - -static absl::Status ReturnIfErrorBody(absl::Status status, int* iptr) { - RETURN_IF_ERROR(status); - EXPECT_EQ(*iptr, 1); - *iptr = 4; - return OkStatus(); -} - -TEST(StatusOr, TestReturnIfError) { - int i = 1; - EXPECT_TRUE(ReturnIfErrorBody(OkStatus(), &i).ok()); - EXPECT_EQ(i, 4); -} - -TEST(StatusOr, TestReturnIfErrorNotOk) { - int i = 1; - Status thing(absl::StatusCode::kCancelled, ""); - EXPECT_FALSE(ReturnIfErrorBody(thing, &i).ok()); - EXPECT_EQ(i, 1); -} - -/* -static StatusOr<int> MakeStatus() { return 100; } - -// A factory to help us benchmark the various factory styles. All of -// the factory methods are marked as non-inlineable so as to more -// accurately simulate calling a factory for which you do not have -// visibility of implementation. Similarly, the value_ variable is -// marked volatile to prevent the compiler from getting too clever -// about detecting that the same value is used in all loop iterations. -template <typename T> -class BenchmarkFactory { - public: - // Construct a new factory. Allocate an object which will always - // be the result of the factory methods. - BenchmarkFactory() : value_(new T) {} - - // Destroy this factory, including the result value. - ~BenchmarkFactory() { delete value_; } - - // A trivial factory that just returns the value. There is no status - // object that could be returned to encapsulate an error - T* TrivialFactory() ABSL_ATTRIBUTE_NOINLINE { return value_; } - - // A more sophisticated factory, which returns a status to indicate - // the result of the operation. The factory result is populated into - // the user provided pointer result. - Status ArgumentFactory(T** result) ABSL_ATTRIBUTE_NOINLINE { - *result = value_; - return Status::OK(); - } - - Status ArgumentFactoryFail(T** result) ABSL_ATTRIBUTE_NOINLINE { - *result = nullptr; - return CancelledError(""); - } - - Status ArgumentFactoryFailShortMsg(T** result) ABSL_ATTRIBUTE_NOINLINE { - *result = nullptr; - return InternalError(""); - } - - Status ArgumentFactoryFailLongMsg(T** result) ABSL_ATTRIBUTE_NOINLINE { - *result = nullptr; - return InternalError(, - "a big string of message junk that will never be read"); - } - - // A factory that returns a StatusOr<T*>. If the factory operation - // is OK, then the StatusOr<T*> will hold a T*. Otherwise, it will - // hold a status explaining the error. - StatusOr<T*> StatusOrFactory() ABSL_ATTRIBUTE_NOINLINE { - return static_cast<T*>(value_); - } - - StatusOr<T*> StatusOrFactoryFail() ABSL_ATTRIBUTE_NOINLINE { - return CancelledError(""); - } - - StatusOr<T*> StatusOrFactoryFailShortMsg() ABSL_ATTRIBUTE_NOINLINE { - return InternalError("i"); - } - - StatusOr<T*> StatusOrFactoryFailLongMsg() ABSL_ATTRIBUTE_NOINLINE { - return InternalError( - "a big string of message junk that will never be read"); - } - - private: - T* volatile value_; - ABSL_DISALLOW_COPY_AND_ASSIGN(BenchmarkFactory); -}; - -// A simple type we use with the factory. -class BenchmarkType { - public: - BenchmarkType() {} - virtual ~BenchmarkType() {} - virtual void DoWork() ABSL_ATTRIBUTE_NOINLINE {} - - private: - ABSL_DISALLOW_COPY_AND_ASSIGN(BenchmarkType); -}; - -// Calibrate the amount of time spent just calling DoWork, since each of our -// tests will do this, we can subtract this out of benchmark results. -void BM_CalibrateWorkLoop(int iters) { - tensorflow::testing::StopTiming(); - BenchmarkFactory<BenchmarkType> factory; - BenchmarkType* result = factory.TrivialFactory(); - tensorflow::testing::StartTiming(); - for (int i = 0; i != iters; ++i) { - if (result != nullptr) { - result->DoWork(); - } - } -} -BENCHMARK(BM_CalibrateWorkLoop); - -// Measure the time taken to call into the factory, return the value, -// determine that it is OK, and invoke a trivial function. -void BM_TrivialFactory(int iters) { - tensorflow::testing::StopTiming(); - BenchmarkFactory<BenchmarkType> factory; - tensorflow::testing::StartTiming(); - for (int i = 0; i != iters; ++i) { - BenchmarkType* result = factory.TrivialFactory(); - if (result != nullptr) { - result->DoWork(); - } - } -} -BENCHMARK(BM_TrivialFactory); - -// Measure the time taken to call into the factory, providing an -// out-param for the result, evaluating the status result and the -// result pointer, and invoking the trivial function. -void BM_ArgumentFactory(int iters) { - tensorflow::testing::StopTiming(); - BenchmarkFactory<BenchmarkType> factory; - tensorflow::testing::StartTiming(); - for (int i = 0; i != iters; ++i) { - BenchmarkType* result = nullptr; - Status status = factory.ArgumentFactory(&result); - if (status.ok() && result != nullptr) { - result->DoWork(); - } - } -} -BENCHMARK(BM_ArgumentFactory); - -// Measure the time to use the StatusOr<T*> factory, evaluate the result, -// and invoke the trivial function. -void BM_StatusOrFactory(int iters) { - tensorflow::testing::StopTiming(); - BenchmarkFactory<BenchmarkType> factory; - tensorflow::testing::StartTiming(); - for (int i = 0; i != iters; ++i) { - StatusOr<BenchmarkType*> result = factory.StatusOrFactory(); - if (result.ok()) { - result.ValueOrDie()->DoWork(); - } - } -} -BENCHMARK(BM_StatusOrFactory); - -// Measure the time taken to call into the factory, providing an -// out-param for the result, evaluating the status result and the -// result pointer, and invoking the trivial function. -void BM_ArgumentFactoryFail(int iters) { - tensorflow::testing::StopTiming(); - BenchmarkFactory<BenchmarkType> factory; - tensorflow::testing::StartTiming(); - for (int i = 0; i != iters; ++i) { - BenchmarkType* result = nullptr; - Status status = factory.ArgumentFactoryFail(&result); - if (status.ok() && result != nullptr) { - result->DoWork(); - } - } -} -BENCHMARK(BM_ArgumentFactoryFail); - -// Measure the time to use the StatusOr<T*> factory, evaluate the result, -// and invoke the trivial function. -void BM_StatusOrFactoryFail(int iters) { - tensorflow::testing::StopTiming(); - BenchmarkFactory<BenchmarkType> factory; - tensorflow::testing::StartTiming(); - for (int i = 0; i != iters; ++i) { - StatusOr<BenchmarkType*> result = factory.StatusOrFactoryFail(); - if (result.ok()) { - result.ValueOrDie()->DoWork(); - } - } -} -BENCHMARK(BM_StatusOrFactoryFail); - -// Measure the time taken to call into the factory, providing an -// out-param for the result, evaluating the status result and the -// result pointer, and invoking the trivial function. -void BM_ArgumentFactoryFailShortMsg(int iters) { - tensorflow::testing::StopTiming(); - BenchmarkFactory<BenchmarkType> factory; - tensorflow::testing::StartTiming(); - for (int i = 0; i != iters; ++i) { - BenchmarkType* result = nullptr; - Status status = factory.ArgumentFactoryFailShortMsg(&result); - if (status.ok() && result != nullptr) { - result->DoWork(); - } - } -} -BENCHMARK(BM_ArgumentFactoryFailShortMsg); - -// Measure the time to use the StatusOr<T*> factory, evaluate the result, -// and invoke the trivial function. -void BM_StatusOrFactoryFailShortMsg(int iters) { - tensorflow::testing::StopTiming(); - BenchmarkFactory<BenchmarkType> factory; - tensorflow::testing::StartTiming(); - for (int i = 0; i != iters; ++i) { - StatusOr<BenchmarkType*> result = factory.StatusOrFactoryFailShortMsg(); - if (result.ok()) { - result.ValueOrDie()->DoWork(); - } - } -} -BENCHMARK(BM_StatusOrFactoryFailShortMsg); - -// Measure the time taken to call into the factory, providing an -// out-param for the result, evaluating the status result and the -// result pointer, and invoking the trivial function. -void BM_ArgumentFactoryFailLongMsg(int iters) { - tensorflow::testing::StopTiming(); - BenchmarkFactory<BenchmarkType> factory; - tensorflow::testing::StartTiming(); - for (int i = 0; i != iters; ++i) { - BenchmarkType* result = nullptr; - Status status = factory.ArgumentFactoryFailLongMsg(&result); - if (status.ok() && result != nullptr) { - result->DoWork(); - } - } -} -BENCHMARK(BM_ArgumentFactoryFailLongMsg); - -// Measure the time to use the StatusOr<T*> factory, evaluate the result, -// and invoke the trivial function. -void BM_StatusOrFactoryFailLongMsg(int iters) { - tensorflow::testing::StopTiming(); - BenchmarkFactory<BenchmarkType> factory; - tensorflow::testing::StartTiming(); - for (int i = 0; i != iters; ++i) { - StatusOr<BenchmarkType*> result = factory.StatusOrFactoryFailLongMsg(); - if (result.ok()) { - result.ValueOrDie()->DoWork(); - } - } -} -BENCHMARK(BM_StatusOrFactoryFailLongMsg); -*/ - -} // namespace - -ABSL_NAMESPACE_END -} // namespace absl |