// Copyright 2022 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. // // ----------------------------------------------------------------------------- // File: log/internal/check_op.h // ----------------------------------------------------------------------------- // // This file declares helpers routines and macros used to implement `CHECK` // macros. #ifndef ABSL_LOG_INTERNAL_CHECK_OP_H_ #define ABSL_LOG_INTERNAL_CHECK_OP_H_ #include <stdint.h> #include <cstddef> #include <ostream> #include <sstream> #include <string> #include <type_traits> #include <utility> #include "absl/base/attributes.h" #include "absl/base/config.h" #include "absl/base/nullability.h" #include "absl/base/optimization.h" #include "absl/log/internal/nullguard.h" #include "absl/log/internal/nullstream.h" #include "absl/log/internal/strip.h" #include "absl/strings/has_absl_stringify.h" #include "absl/strings/string_view.h" // `ABSL_LOG_INTERNAL_STRIP_STRING_LITERAL` wraps string literals that // should be stripped when `ABSL_MIN_LOG_LEVEL` exceeds `kFatal`. #ifdef ABSL_MIN_LOG_LEVEL #define ABSL_LOG_INTERNAL_STRIP_STRING_LITERAL … #else #define ABSL_LOG_INTERNAL_STRIP_STRING_LITERAL(literal) … #endif #ifdef NDEBUG // `NDEBUG` is defined, so `DCHECK_EQ(x, y)` and so on do nothing. However, we // still want the compiler to parse `x` and `y`, because we don't want to lose // potentially useful errors and warnings. #define ABSL_LOG_INTERNAL_DCHECK_NOP … #endif #define ABSL_LOG_INTERNAL_CHECK_OP(name, op, val1, val1_text, val2, val2_text) … #define ABSL_LOG_INTERNAL_QCHECK_OP(name, op, val1, val1_text, val2, \ val2_text) … #define ABSL_LOG_INTERNAL_CHECK_STROP(func, op, expected, s1, s1_text, s2, \ s2_text) … #define ABSL_LOG_INTERNAL_QCHECK_STROP(func, op, expected, s1, s1_text, s2, \ s2_text) … // This one is tricky: // * We must evaluate `val` exactly once, yet we need to do two things with it: // evaluate `.ok()` and (sometimes) `.ToString()`. // * `val` might be an `absl::Status` or some `absl::StatusOr<T>`. // * `val` might be e.g. `ATemporary().GetStatus()`, which may return a // reference to a member of `ATemporary` that is only valid until the end of // the full expression. // * We don't want this file to depend on `absl::Status` `#include`s or linkage, // nor do we want to move the definition to status and introduce a dependency // in the other direction. We can be assured that callers must already have a // `Status` and the necessary `#include`s and linkage. // * Callsites should be small and fast (at least when `val.ok()`): one branch, // minimal stack footprint. // * In particular, the string concat stuff should be out-of-line and emitted // in only one TU to save linker input size // * We want the `val.ok()` check inline so static analyzers and optimizers can // see it. // * As usual, no braces so we can stream into the expansion with `operator<<`. // * Also as usual, it must expand to a single (partial) statement with no // ambiguous-else problems. // * When stripped by `ABSL_MIN_LOG_LEVEL`, we must discard the `<expr> is OK` // string literal and abort without doing any streaming. We don't need to // strip the call to stringify the non-ok `Status` as long as we don't log it; // dropping the `Status`'s message text is out of scope. #define ABSL_LOG_INTERNAL_CHECK_OK(val, val_text) … #define ABSL_LOG_INTERNAL_QCHECK_OK(val, val_text) … namespace absl { ABSL_NAMESPACE_BEGIN class Status; template <typename T> class StatusOr; namespace status_internal { ABSL_ATTRIBUTE_PURE_FUNCTION absl::Nonnull<std::string*> MakeCheckFailString( absl::Nonnull<const absl::Status*> status, absl::Nonnull<const char*> prefix); } // namespace status_internal log_internal // namespace log_internal ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_LOG_INTERNAL_CHECK_OP_H_