| // Copyright 2026 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: status_macros.h | |
| // ----------------------------------------------------------------------------- | |
| // | |
| // Helper macros and methods to return and propagate errors with `absl::Status`. | |
| #ifndef ABSL_STATUS_STATUS_MACROS_H_ | |
| #define ABSL_STATUS_STATUS_MACROS_H_ | |
| #include <cstddef> | |
| #include <string> | |
| #include <type_traits> | |
| #include <utility> | |
| #include "absl/base/attributes.h" | |
| #include "absl/base/config.h" | |
| #include "absl/base/optimization.h" | |
| #include "absl/status/status.h" | |
| #include "absl/status/status_builder.h" // IWYU pragma: export | |
| #include "absl/status/statusor.h" | |
| #include "absl/types/source_location.h" | |
| // Evaluates an expression that produces a `absl::Status`. If the status is not | |
| // ok, returns it from the current function. | |
| // | |
| // For example: | |
| // absl::Status MultiStepFunction() { | |
| // ABSL_RETURN_IF_ERROR(Function(args...)); | |
| // ABSL_RETURN_IF_ERROR(foo.Method(args...)); | |
| // return absl::OkStatus(); | |
| // } | |
| // | |
| // The macro ends with a `absl::StatusBuilder` which allows the returned status | |
| // to be extended with more details. Any chained expressions after the macro | |
| // will not be evaluated unless there is an error. | |
| // | |
| // For example: | |
| // absl::Status MultiStepFunction() { | |
| // ABSL_RETURN_IF_ERROR(Function(args...)) << "in MultiStepFunction"; | |
| // ABSL_RETURN_IF_ERROR(foo.Method(args...)).Log(absl::LogSeverity::kError) | |
| // << "while processing query: " << query.DebugString(); | |
| // return absl::OkStatus(); | |
| // } | |
| // | |
| // `absl::StatusBuilder` supports adapting the builder chain using a `With` | |
| // method and a functor. This allows for powerful extensions to the macro. | |
| // | |
| // For example, teams can define local policies to use across their code: | |
| // | |
| // StatusBuilder TeamPolicy(StatusBuilder builder) { | |
| // return std::move(builder.Log(absl::LogSeverity::kWarning).Attach(...)); | |
| // } | |
| // | |
| // ABSL_RETURN_IF_ERROR(foo()).With(TeamPolicy); | |
| // ABSL_RETURN_IF_ERROR(bar()).With(TeamPolicy); | |
| // | |
| // Changing the return type allows the macro to be used with Task and Rpc | |
| // interfaces. See `util::TaskReturn` and `rpc::RpcSetStatus` for details. | |
| // | |
| // void Read(StringPiece name, util::Task* task) { | |
| // int64 id; | |
| // ABSL_RETURN_IF_ERROR(GetIdForName(name, &id)).With(TaskReturn(task)); | |
| // ABSL_RETURN_IF_ERROR(ReadForId(id)).With(TaskReturn(task)); | |
| // task->Return(); | |
| // } | |
| // | |
| // If using this macro inside a lambda, you need to annotate the return type | |
| // to avoid confusion between a `absl::StatusBuilder` and a `absl::Status` type. | |
| // E.g. | |
| // | |
| // []() -> absl::Status { | |
| // ABSL_RETURN_IF_ERROR(Function(args...)); | |
| // ABSL_RETURN_IF_ERROR(foo.Method(args...)); | |
| // return absl::OkStatus(); | |
| // } | |
| #define ABSL_RETURN_IF_ERROR(expr) \ | |
| ABSL_INTERNAL_STATUS_MACROS_RETURN_IF_ERROR_IMPL_(return, expr) | |
| // Executes an expression `rexpr` that returns an `absl::StatusOr<T>`. On OK, | |
| // moves its value into the variable defined by `lhs`, otherwise returns | |
| // from the current function. By default the error status is returned | |
| // unchanged, but it may be modified by an `error_expression`. If there is an | |
| // error, `lhs` is not evaluated; thus any side effects that `lhs` may have | |
| // only occur in the success case. | |
| // | |
| // Interface: | |
| // | |
| // ABSL_ASSIGN_OR_RETURN(lhs, rexpr) | |
| // ABSL_ASSIGN_OR_RETURN(lhs, rexpr, error_expression); | |
| // | |
| // WARNING: if lhs is parenthesized, the parentheses are removed. See examples | |
| // for more details. | |
| // | |
| // WARNING: expands into multiple statements; it cannot be used in a single | |
| // statement (e.g. as the body of an if statement without {})! | |
| // | |
| // Example: Declaring and initializing a new variable (ValueType can be anything | |
| // that can be initialized with assignment--including a const | |
| // reference, although that's discouraged by go/totw/107): | |
| // ABSL_ASSIGN_OR_RETURN(ValueType value, MaybeGetValue(arg)); | |
| // | |
| // Example: Assigning to an existing variable: | |
| // ValueType value; | |
| // ABSL_ASSIGN_OR_RETURN(value, MaybeGetValue(arg)); | |
| // | |
| // Example: Assigning to an expression with side effects: | |
| // MyProto data; | |
| // ABSL_ASSIGN_OR_RETURN(*data.mutable_str(), MaybeGetValue(arg)); | |
| // // No field "str" is added on error. | |
| // | |
| // Example: Initializing a `std::unique_ptr`. | |
| // ABSL_ASSIGN_OR_RETURN(std::unique_ptr<T> ptr, MaybeGetPtr(arg)); | |
| // | |
| // Example: Initializing a map. Because of C++ preprocessor limitations, | |
| // the type used in ABSL_ASSIGN_OR_RETURN cannot contain commas, so wrap the | |
| // lhs in parentheses: | |
| // ABSL_ASSIGN_OR_RETURN((absl::flat_hash_map<Foo, Bar> my_map), GetMap()); | |
| // Or use `auto` if the type is obvious enough: | |
| // ABSL_ASSIGN_OR_RETURN(auto my_map, GetMap()); | |
| // | |
| // Example: Assigning to structured bindings (go/totw/169). The same situation | |
| // with comma as in map, so wrap the statement in parentheses. | |
| // ABSL_ASSIGN_OR_RETURN((auto [first, second]), GetPair()); | |
| // | |
| // If passed, the `error_expression` is evaluated to produce the return | |
| // value. The expression may reference any variable visible in scope, as | |
| // well as a `absl::StatusBuilder` object populated with the error and | |
| // named by a single underscore `_`. The expression typically uses the | |
| // builder to modify the status and is returned directly in manner similar | |
| // to ABSL_RETURN_IF_ERROR. The expression may, however, evaluate to any type | |
| // returnable by the function, including (void). For example: | |
| // | |
| // Example: Adjusting the error message. | |
| // ABSL_ASSIGN_OR_RETURN(ValueType value, MaybeGetValue(query), | |
| // _ << "while processing query " << query.DebugString()); | |
| // | |
| // Example: Logging the error on failure. | |
| // ABSL_ASSIGN_OR_RETURN(ValueType value, MaybeGetValue(query), _.LogError()); | |
| // | |
| #define ABSL_ASSIGN_OR_RETURN(...) \ | |
| ABSL_INTERNAL_STATUS_MACROS_ASSIGN_OR_RETURN_IMPL_(return, __VA_ARGS__) | |
| // ================================================================= | |
| // == Implementation details, do not rely on anything below here. == | |
| // ================================================================= | |
| #define ABSL_INTERNAL_STATUS_MACROS_RETURN_IF_ERROR_IMPL_(return_keyword, \ | |
| expr) \ | |
| ABSL_INTERNAL_STATUS_MACROS_IMPL_ELSE_BLOCKER_ \ | |
| if (auto status_macro_internal_adaptor = \ | |
| absl::status_macro_internal::MacroAdaptor( \ | |
| (expr), absl::SourceLocation::current())) { \ | |
| } else /* NOLINT */ \ | |
| return_keyword status_macro_internal_adaptor.Consume() | |
| #define ABSL_INTERNAL_STATUS_MACROS_ASSIGN_OR_RETURN_IMPL_(return_keyword, \ | |
| ...) \ | |
| ABSL_INTERNAL_STATUS_MACROS_IMPL_GET_VARIADIC_( \ | |
| (return_keyword, __VA_ARGS__, \ | |
| ABSL_INTERNAL_STATUS_MACROS_IMPL_ASSIGN_OR_RETURN_3_, \ | |
| ABSL_INTERNAL_STATUS_MACROS_IMPL_ASSIGN_OR_RETURN_2_)) \ | |
| (return_keyword, __VA_ARGS__) | |
| constexpr bool HasPotentialConditionalOperator(const char* lhs, size_t size) { | |
| return lhs[0] == '(' && lhs[size - 1] == ')' && | |
| std::char_traits<char>::find(lhs, size, '?') != nullptr; | |
| } | |
| template <std::size_t N> | |
| constexpr bool IsEnclosedByParentheses(const char (&lhs)[N]) { | |
| if (N < 2) { | |
| return false; | |
| } | |
| return lhs[0] == '(' && lhs[N - 2] == ')'; | |
| } | |
| namespace absl { | |
| ABSL_NAMESPACE_BEGIN | |
| namespace status_macro_internal { | |
| template <typename T, typename EnableIf = void> | |
| struct IsAllowedStatusOrMacroType : std::false_type {}; | |
| template <typename T> | |
| struct IsAllowedStatusOrMacroType< | |
| T, std::enable_if_t<std::is_convertible_v< | |
| T*, typename absl::StatusOr<typename T::value_type>*>>> | |
| : std::true_type {}; | |
| } // namespace status_macro_internal | |
| ABSL_NAMESPACE_END | |
| } // namespace absl | |
| // MSVC incorrectly expands variadic macros, splice together a macro call to | |
| // work around the bug. | |
| #define ABSL_INTERNAL_STATUS_MACROS_IMPL_GET_VARIADIC_HELPER_(_1, _2, _3, _4, \ | |
| NAME, ...) \ | |
| NAME | |
| #define ABSL_INTERNAL_STATUS_MACROS_IMPL_GET_VARIADIC_(args) \ | |
| /* NOLINTNEXTLINE(clang-diagnostic-pre-c++20-compat) */ \ | |
| ABSL_INTERNAL_STATUS_MACROS_IMPL_GET_VARIADIC_HELPER_ args | |
| #define ABSL_INTERNAL_STATUS_MACROS_IMPL_ASSIGN_OR_RETURN_2_(return_keyword, \ | |
| lhs, rexpr) \ | |
| ABSL_INTERNAL_STATUS_MACROS_IMPL_ASSIGN_OR_RETURN_( \ | |
| ABSL_INTERNAL_STATUS_MACROS_IMPL_CONCAT_(_status_or_value, __LINE__), \ | |
| lhs, rexpr, \ | |
| return_keyword absl::Status( \ | |
| std::move(ABSL_INTERNAL_STATUS_MACROS_IMPL_CONCAT_(_status_or_value, \ | |
| __LINE__)) \ | |
| .status(), \ | |
| absl::SourceLocation::current())) | |
| #define ABSL_INTERNAL_STATUS_MACROS_IMPL_ASSIGN_OR_RETURN_3_( \ | |
| return_keyword, lhs, rexpr, error_expression) \ | |
| ABSL_INTERNAL_STATUS_MACROS_IMPL_ASSIGN_OR_RETURN_( \ | |
| ABSL_INTERNAL_STATUS_MACROS_IMPL_CONCAT_(_status_or_value, __LINE__), \ | |
| lhs, rexpr, /* NOLINTNEXTLINE(misc-const-correctness) */ \ | |
| absl::StatusBuilder _( \ | |
| std::move(ABSL_INTERNAL_STATUS_MACROS_IMPL_CONCAT_(_status_or_value, \ | |
| __LINE__)) \ | |
| .status(), \ | |
| absl::SourceLocation::current()); \ | |
| (void)_; /* error_expression is allowed to not use this variable */ \ | |
| return_keyword(error_expression)) | |
| #define ABSL_INTERNAL_STATUS_MACROS_IMPL_ASSIGN_OR_RETURN_( \ | |
| statusor, lhs, rexpr, error_expression) \ | |
| auto statusor = (rexpr); \ | |
| if (ABSL_PREDICT_FALSE(!statusor.ok())) { \ | |
| error_expression; \ | |
| } \ | |
| { \ | |
| static_assert(!HasPotentialConditionalOperator(#lhs, sizeof(#lhs) - 1), \ | |
| "Identified potential conditional operator, consider not " \ | |
| "using ABSL_ASSIGN_OR_RETURN"); \ | |
| } \ | |
| { \ | |
| static_assert( \ | |
| absl::status_macro_internal::IsAllowedStatusOrMacroType< \ | |
| std::remove_const_t<decltype(statusor)>>(), \ | |
| "ABSL_ASSIGN_OR_RETURN should only be used with absl::StatusOr<>"); \ | |
| } \ | |
| ABSL_INTERNAL_STATUS_MACROS_IMPL_UNPARENTHESIZE_IF_PARENTHESIZED(lhs) = \ | |
| (*std::move(statusor)) | |
| // Internal helpers for macro expansion. | |
| #define ABSL_INTERNAL_STATUS_MACROS_IMPL_EAT(...) | |
| #define ABSL_INTERNAL_STATUS_MACROS_IMPL_REM(...) __VA_ARGS__ | |
| #define ABSL_INTERNAL_STATUS_MACROS_IMPL_COMMA(...) , | |
| #define ABSL_INTERNAL_STATUS_MACROS_IMPL_ARG_3(a, b, c, ...) c | |
| #define ABSL_INTERNAL_STATUS_MACROS_IMPL_HAS_COMMA(...) \ | |
| ABSL_INTERNAL_STATUS_MACROS_IMPL_REM( \ | |
| ABSL_INTERNAL_STATUS_MACROS_IMPL_ARG_3(__VA_ARGS__, 1, 10)) | |
| // Concatenates five macro arguments. | |
| #define ABSL_INTERNAL_STATUS_MACROS_IMPL_CONCAT_5(a, b, c, d, e) a##b##c##d##e | |
| // Identifies (below) the case where all arguments are empty, except the last. | |
| #define ABSL_INTERNAL_STATUS_MACROS_IMPL_IS_EMPTY_CASE_1010101 , | |
| // Evaluates to 1 if the arguments concatenate to 1010101, and 10 otherwise. | |
| #define ABSL_INTERNAL_STATUS_MACROS_1_IF_1010101_ELSE_10(a, b, c, d) \ | |
| ABSL_INTERNAL_STATUS_MACROS_IMPL_HAS_COMMA( \ | |
| ABSL_INTERNAL_STATUS_MACROS_IMPL_CONCAT_5( \ | |
| ABSL_INTERNAL_STATUS_MACROS_IMPL_IS_EMPTY_CASE_, a, b, c, d)) | |
| // Evaluates to 1 if __VA_OPT__ is supported and the argument list is non-empty, | |
| // and 0 otherwise. | |
| #define ABSL_INTERNAL_STATUS_MACROS_IMPL_HAVE_VA_OPT(...) \ | |
| ABSL_INTERNAL_STATUS_MACROS_IMPL_ARG_3(__VA_OPT__(, ), 1, 0, ) | |
| #if ABSL_INTERNAL_STATUS_MACROS_IMPL_HAVE_VA_OPT(.) | |
| // Evaluates to 1 if the argument list is empty, and 10 otherwise. | |
| #define ABSL_INTERNAL_STATUS_MACROS_1_IF_EMPTY_ELSE_10(...) 1##__VA_OPT__(0) | |
| #else | |
| #define ABSL_INTERNAL_STATUS_MACROS_1_IF_EMPTY_ELSE_10(...) \ | |
| ABSL_INTERNAL_STATUS_MACROS_1_IF_1010101_ELSE_10( \ | |
| ABSL_INTERNAL_STATUS_MACROS_IMPL_HAS_COMMA(__VA_ARGS__), \ | |
| ABSL_INTERNAL_STATUS_MACROS_IMPL_HAS_COMMA( \ | |
| ABSL_INTERNAL_STATUS_MACROS_IMPL_COMMA __VA_ARGS__), \ | |
| ABSL_INTERNAL_STATUS_MACROS_IMPL_HAS_COMMA(__VA_ARGS__()), \ | |
| ABSL_INTERNAL_STATUS_MACROS_IMPL_HAS_COMMA( \ | |
| ABSL_INTERNAL_STATUS_MACROS_IMPL_COMMA __VA_ARGS__())) | |
| #endif | |
| // Parenthesized case: strips the initial pair of parentheses from the input. | |
| // | |
| // Note that this may not result in an equivalent expression. For example, | |
| // (*a)[b] would evaluate to a[b]. The caller below is required to ensure | |
| // this is only called when the input is fully parenthesized to avoid this | |
| // issue. | |
| #define ABSL_INTERNAL_STATUS_MACROS_IMPL_UNPARENTHESIZE_IF_PARENTHESIZED_1(x) \ | |
| ABSL_INTERNAL_STATUS_MACROS_IMPL_REM x | |
| // Unparenthesized case: evaluates to the argument list as-is. | |
| #define ABSL_INTERNAL_STATUS_MACROS_IMPL_UNPARENTHESIZE_IF_PARENTHESIZED_10(x) \ | |
| ABSL_INTERNAL_STATUS_MACROS_IMPL_REM(x) | |
| // If the input is parenthesized, removes the parentheses. Otherwise expands to | |
| // the input unchanged. | |
| #define ABSL_INTERNAL_STATUS_MACROS_IMPL_UNPARENTHESIZE_IF_PARENTHESIZED(...) \ | |
| ABSL_INTERNAL_STATUS_MACROS_IMPL_REM( \ | |
| ABSL_INTERNAL_STATUS_MACROS_IMPL_CONCAT_( \ | |
| ABSL_INTERNAL_STATUS_MACROS_IMPL_UNPARENTHESIZE_IF_PARENTHESIZED_, \ | |
| ABSL_INTERNAL_STATUS_MACROS_1_IF_EMPTY_ELSE_10( \ | |
| ABSL_INTERNAL_STATUS_MACROS_IMPL_EAT __VA_ARGS__))( \ | |
| ABSL_INTERNAL_STATUS_MACROS_IMPL_REM(__VA_ARGS__))) | |
| // Internal helper for concatenating macro values. | |
| #define ABSL_INTERNAL_STATUS_MACROS_IMPL_CONCAT_INNER_(x, y) x##y | |
| #define ABSL_INTERNAL_STATUS_MACROS_IMPL_CONCAT_(x, y) \ | |
| ABSL_INTERNAL_STATUS_MACROS_IMPL_CONCAT_INNER_(x, y) | |
| // The GNU compiler emits a warning for code like: | |
| // | |
| // if (foo) | |
| // if (bar) { } else baz; | |
| // | |
| // because it thinks you might want the else to bind to the first if. This | |
| // leads to problems with code like: | |
| // | |
| // if (do_expr) ABSL_RETURN_IF_ERROR(expr) << "Some message"; | |
| // | |
| // The "switch (0) case 0:" idiom is used to suppress this. | |
| #define ABSL_INTERNAL_STATUS_MACROS_IMPL_ELSE_BLOCKER_ \ | |
| switch (0) \ | |
| case 0: \ | |
| default: // NOLINT | |
| namespace absl { | |
| ABSL_NAMESPACE_BEGIN | |
| namespace status_macro_internal { | |
| // Provides a conversion to bool so that it can be used inside an if statement | |
| // that declares a variable. | |
| class StatusAdaptorForMacros { | |
| public: | |
| StatusAdaptorForMacros( | |
| const absl::Status& status, | |
| absl::SourceLocation loc = absl::SourceLocation::current()) | |
| : builder_(status, loc) {} | |
| StatusAdaptorForMacros( | |
| absl::Status&& status, | |
| absl::SourceLocation loc = absl::SourceLocation::current()) | |
| : builder_(std::move(status), loc) {} | |
| StatusAdaptorForMacros(const StatusBuilder& builder, | |
| absl::SourceLocation = absl::SourceLocation()) | |
| : builder_(builder) {} | |
| StatusAdaptorForMacros(StatusBuilder&& builder, | |
| absl::SourceLocation = absl::SourceLocation()) | |
| : builder_(std::move(builder)) {} | |
| StatusAdaptorForMacros(const StatusAdaptorForMacros&) = delete; | |
| StatusAdaptorForMacros& operator=(const StatusAdaptorForMacros&) = delete; | |
| explicit operator bool() const { return ABSL_PREDICT_TRUE(builder_.ok()); } | |
| StatusBuilder&& Consume() { return std::move(builder_); } | |
| private: | |
| StatusBuilder builder_; | |
| }; | |
| // Special adaptor for use by ABSL_RETURN_IF_ERROR for absl::Status arguments. | |
| // This one avoids constructing a StatusBuilder on the fast path. | |
| // | |
| // REQUIRES: Only used by ABSL_RETURN_IF_ERROR implementation. | |
| class ReturnIfErrorAdaptor { | |
| public: | |
| explicit ReturnIfErrorAdaptor( | |
| const absl::Status& status, | |
| absl::SourceLocation loc = absl::SourceLocation::current()) | |
| : status_(status), loc_(loc) {} | |
| explicit ReturnIfErrorAdaptor( | |
| absl::Status&& status, | |
| absl::SourceLocation loc = absl::SourceLocation::current()) | |
| : status_(std::move(status)), loc_(loc) {} | |
| ~ReturnIfErrorAdaptor() { | |
| // WARNING! WARNING! WARNING! | |
| // | |
| // We play fast and loose here and avoid destroying status_. This should be | |
| // safe because status_ will never own memory at destruction time. The two | |
| // cases to consider are: | |
| // (1) OK: OkStatus() representation needs no cleanup | |
| // (2) Not-OK: we take the else branch in ABSL_RETURN_IF_ERROR and move | |
| // status_ into StatusBuilder which leaves status_ with a MovedFromRep | |
| // that needs no cleanup. | |
| // If the absl::Status implementation changes, leaks should be caught by | |
| // the various tests we have when run under lsan or debug leak checker. | |
| } | |
| explicit operator bool() const { return ABSL_PREDICT_TRUE(status_.ok()); } | |
| StatusBuilder Consume() { return StatusBuilder(std::move(status_), loc_); } | |
| private: | |
| // Place the status inside a union so we can avoid generating unnecessary code | |
| // to call the Status destructor. | |
| union { | |
| absl::Status status_; | |
| char nothing_[1]; | |
| }; | |
| absl::SourceLocation loc_; | |
| }; | |
| // Overloads of MacroAdaptor that pick the right adaptor class | |
| // for each argument type. | |
| // | |
| // TODO(b/501387693): Replace these with deduction guides of template | |
| // specializations once the bug is fixed. (See prior file revision.) | |
| inline ReturnIfErrorAdaptor MacroAdaptor(const absl::Status& s, | |
| absl::SourceLocation loc) { | |
| return ReturnIfErrorAdaptor(s, loc); | |
| } | |
| inline ReturnIfErrorAdaptor MacroAdaptor(absl::Status&& s, | |
| absl::SourceLocation loc) { | |
| return ReturnIfErrorAdaptor(std::move(s), loc); | |
| } | |
| inline StatusAdaptorForMacros MacroAdaptor(const StatusBuilder& s, | |
| absl::SourceLocation loc) { | |
| return StatusAdaptorForMacros(s, loc); | |
| } | |
| inline StatusAdaptorForMacros MacroAdaptor(StatusBuilder&& s, | |
| absl::SourceLocation loc) { | |
| return StatusAdaptorForMacros(std::move(s), loc); | |
| } | |
| } // namespace status_macro_internal | |
| // By defining ABSL_DEFINE_UNQUALIFIED_STATUS_MACROS, this library also provides | |
| // unqualified versions of its macros. | |
| // | |
| // Unqualified macro names are likely to collide with those in other projects, | |
| // and so are not recommended. Furthermore, this is true for any transitive | |
| // dependencies of Abseil: it is impossible to be confident that downstream | |
| // libraries will neither define these macros themselves nor depend on a | |
| // different library that also defines them. | |
| // | |
| // To enable unqualified names despite the caveats, define | |
| // `ABSL_DEFINE_UNQUALIFIED_STATUS_MACROS` preferably at the command line, e.g. | |
| // `-DABSL_DEFINE_UNQUALIFIED_STATUS_MACROS`, or `local_defines = | |
| // ["ABSL_DEFINE_UNQUALIFIED_STATUS_MACROS"]` if using Bazel. | |
| // | |
| // These are turned on by default inside Google's internal codebase where their | |
| // use is historically ubiquitous. Other OSS Google projects should use the | |
| // qualified versions. | |
| // | |
| #ifdef ABSL_DEFINE_UNQUALIFIED_STATUS_MACROS | |
| #define ASSIGN_OR_RETURN(...) ABSL_ASSIGN_OR_RETURN(__VA_ARGS__) | |
| #define RETURN_IF_ERROR(...) ABSL_RETURN_IF_ERROR(__VA_ARGS__) | |
| #endif // ABSL_DEFINE_UNQUALIFIED_STATUS_MACROS | |
| ABSL_NAMESPACE_END | |
| } // namespace absl | |
| #endif // ABSL_STATUS_STATUS_MACROS_H_ |