Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-12-16 09:40:52

0001 // Copyright 2022 The Abseil Authors.
0002 //
0003 // Licensed under the Apache License, Version 2.0 (the "License");
0004 // you may not use this file except in compliance with the License.
0005 // You may obtain a copy of the License at
0006 //
0007 //      https://www.apache.org/licenses/LICENSE-2.0
0008 //
0009 // Unless required by applicable law or agreed to in writing, software
0010 // distributed under the License is distributed on an "AS IS" BASIS,
0011 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0012 // See the License for the specific language governing permissions and
0013 // limitations under the License.
0014 //
0015 // -----------------------------------------------------------------------------
0016 // File: log/internal/check_op.h
0017 // -----------------------------------------------------------------------------
0018 //
0019 // This file declares helpers routines and macros used to implement `CHECK`
0020 // macros.
0021 
0022 #ifndef ABSL_LOG_INTERNAL_CHECK_OP_H_
0023 #define ABSL_LOG_INTERNAL_CHECK_OP_H_
0024 
0025 #include <stdint.h>
0026 
0027 #include <cstddef>
0028 #include <ostream>
0029 #include <sstream>
0030 #include <string>
0031 #include <type_traits>
0032 #include <utility>
0033 
0034 #include "absl/base/attributes.h"
0035 #include "absl/base/config.h"
0036 #include "absl/base/optimization.h"
0037 #include "absl/log/internal/nullguard.h"
0038 #include "absl/log/internal/nullstream.h"
0039 #include "absl/log/internal/strip.h"
0040 #include "absl/strings/has_absl_stringify.h"
0041 #include "absl/strings/string_view.h"
0042 
0043 // `ABSL_LOG_INTERNAL_STRIP_STRING_LITERAL` wraps string literals that
0044 // should be stripped when `ABSL_MIN_LOG_LEVEL` exceeds `kFatal`.
0045 #ifdef ABSL_MIN_LOG_LEVEL
0046 #define ABSL_LOG_INTERNAL_STRIP_STRING_LITERAL(literal)         \
0047   (::absl::LogSeverity::kFatal >=                               \
0048            static_cast<::absl::LogSeverity>(ABSL_MIN_LOG_LEVEL) \
0049        ? (literal)                                              \
0050        : "")
0051 #else
0052 #define ABSL_LOG_INTERNAL_STRIP_STRING_LITERAL(literal) (literal)
0053 #endif
0054 
0055 #ifdef NDEBUG
0056 // `NDEBUG` is defined, so `DCHECK_EQ(x, y)` and so on do nothing.  However, we
0057 // still want the compiler to parse `x` and `y`, because we don't want to lose
0058 // potentially useful errors and warnings.
0059 #define ABSL_LOG_INTERNAL_DCHECK_NOP(x, y)   \
0060   while (false && ((void)(x), (void)(y), 0)) \
0061   ::absl::log_internal::NullStream().InternalStream()
0062 #endif
0063 
0064 #define ABSL_LOG_INTERNAL_CHECK_OP(name, op, val1, val1_text, val2, val2_text) \
0065   while (::std::string* absl_log_internal_check_op_result                      \
0066              ABSL_LOG_INTERNAL_ATTRIBUTE_UNUSED_IF_STRIP_LOG =                 \
0067                  ::absl::log_internal::name##Impl(                             \
0068                      ::absl::log_internal::GetReferenceableValue(val1),        \
0069                      ::absl::log_internal::GetReferenceableValue(val2),        \
0070                      ABSL_LOG_INTERNAL_STRIP_STRING_LITERAL(                   \
0071                          val1_text " " #op " " val2_text)))                    \
0072     ABSL_LOG_INTERNAL_CONDITION_FATAL(STATELESS, true)                         \
0073   ABSL_LOG_INTERNAL_CHECK(*absl_log_internal_check_op_result).InternalStream()
0074 #define ABSL_LOG_INTERNAL_QCHECK_OP(name, op, val1, val1_text, val2, \
0075                                     val2_text)                       \
0076   while (::std::string* absl_log_internal_qcheck_op_result =         \
0077              ::absl::log_internal::name##Impl(                       \
0078                  ::absl::log_internal::GetReferenceableValue(val1),  \
0079                  ::absl::log_internal::GetReferenceableValue(val2),  \
0080                  ABSL_LOG_INTERNAL_STRIP_STRING_LITERAL(             \
0081                      val1_text " " #op " " val2_text)))              \
0082     ABSL_LOG_INTERNAL_CONDITION_QFATAL(STATELESS, true)              \
0083   ABSL_LOG_INTERNAL_QCHECK(*absl_log_internal_qcheck_op_result).InternalStream()
0084 #define ABSL_LOG_INTERNAL_CHECK_STROP(func, op, expected, s1, s1_text, s2,     \
0085                                       s2_text)                                 \
0086   while (::std::string* absl_log_internal_check_strop_result =                 \
0087              ::absl::log_internal::Check##func##expected##Impl(                \
0088                  (s1), (s2),                                                   \
0089                  ABSL_LOG_INTERNAL_STRIP_STRING_LITERAL(s1_text " " #op        \
0090                                                                 " " s2_text))) \
0091     ABSL_LOG_INTERNAL_CONDITION_FATAL(STATELESS, true)                         \
0092   ABSL_LOG_INTERNAL_CHECK(*absl_log_internal_check_strop_result)               \
0093       .InternalStream()
0094 #define ABSL_LOG_INTERNAL_QCHECK_STROP(func, op, expected, s1, s1_text, s2,    \
0095                                        s2_text)                                \
0096   while (::std::string* absl_log_internal_qcheck_strop_result =                \
0097              ::absl::log_internal::Check##func##expected##Impl(                \
0098                  (s1), (s2),                                                   \
0099                  ABSL_LOG_INTERNAL_STRIP_STRING_LITERAL(s1_text " " #op        \
0100                                                                 " " s2_text))) \
0101     ABSL_LOG_INTERNAL_CONDITION_QFATAL(STATELESS, true)                        \
0102   ABSL_LOG_INTERNAL_QCHECK(*absl_log_internal_qcheck_strop_result)             \
0103       .InternalStream()
0104 // This one is tricky:
0105 // * We must evaluate `val` exactly once, yet we need to do two things with it:
0106 //   evaluate `.ok()` and (sometimes) `.ToString()`.
0107 // * `val` might be an `absl::Status` or some `absl::StatusOr<T>`.
0108 // * `val` might be e.g. `ATemporary().GetStatus()`, which may return a
0109 //   reference to a member of `ATemporary` that is only valid until the end of
0110 //   the full expression.
0111 // * We don't want this file to depend on `absl::Status` `#include`s or linkage,
0112 //   nor do we want to move the definition to status and introduce a dependency
0113 //   in the other direction.  We can be assured that callers must already have a
0114 //   `Status` and the necessary `#include`s and linkage.
0115 // * Callsites should be small and fast (at least when `val.ok()`): one branch,
0116 //   minimal stack footprint.
0117 //   * In particular, the string concat stuff should be out-of-line and emitted
0118 //     in only one TU to save linker input size
0119 // * We want the `val.ok()` check inline so static analyzers and optimizers can
0120 //   see it.
0121 // * As usual, no braces so we can stream into the expansion with `operator<<`.
0122 // * Also as usual, it must expand to a single (partial) statement with no
0123 //   ambiguous-else problems.
0124 // * When stripped by `ABSL_MIN_LOG_LEVEL`, we must discard the `<expr> is OK`
0125 //   string literal and abort without doing any streaming.  We don't need to
0126 //   strip the call to stringify the non-ok `Status` as long as we don't log it;
0127 //   dropping the `Status`'s message text is out of scope.
0128 #define ABSL_LOG_INTERNAL_CHECK_OK(val, val_text)                        \
0129   for (::std::pair<const ::absl::Status*, ::std::string*>                \
0130            absl_log_internal_check_ok_goo;                               \
0131        absl_log_internal_check_ok_goo.first =                            \
0132            ::absl::log_internal::AsStatus(val),                          \
0133        absl_log_internal_check_ok_goo.second =                           \
0134            ABSL_PREDICT_TRUE(absl_log_internal_check_ok_goo.first->ok()) \
0135                ? nullptr                                                 \
0136                : ::absl::status_internal::MakeCheckFailString(           \
0137                      absl_log_internal_check_ok_goo.first,               \
0138                      ABSL_LOG_INTERNAL_STRIP_STRING_LITERAL(val_text     \
0139                                                             " is OK")),  \
0140        !ABSL_PREDICT_TRUE(absl_log_internal_check_ok_goo.first->ok());)  \
0141     ABSL_LOG_INTERNAL_CONDITION_FATAL(STATELESS, true)                   \
0142   ABSL_LOG_INTERNAL_CHECK(*absl_log_internal_check_ok_goo.second)        \
0143       .InternalStream()
0144 #define ABSL_LOG_INTERNAL_QCHECK_OK(val, val_text)                        \
0145   for (::std::pair<const ::absl::Status*, ::std::string*>                 \
0146            absl_log_internal_qcheck_ok_goo;                               \
0147        absl_log_internal_qcheck_ok_goo.first =                            \
0148            ::absl::log_internal::AsStatus(val),                           \
0149        absl_log_internal_qcheck_ok_goo.second =                           \
0150            ABSL_PREDICT_TRUE(absl_log_internal_qcheck_ok_goo.first->ok()) \
0151                ? nullptr                                                  \
0152                : ::absl::status_internal::MakeCheckFailString(            \
0153                      absl_log_internal_qcheck_ok_goo.first,               \
0154                      ABSL_LOG_INTERNAL_STRIP_STRING_LITERAL(val_text      \
0155                                                             " is OK")),   \
0156        !ABSL_PREDICT_TRUE(absl_log_internal_qcheck_ok_goo.first->ok());)  \
0157     ABSL_LOG_INTERNAL_CONDITION_QFATAL(STATELESS, true)                   \
0158   ABSL_LOG_INTERNAL_QCHECK(*absl_log_internal_qcheck_ok_goo.second)       \
0159       .InternalStream()
0160 
0161 namespace absl {
0162 ABSL_NAMESPACE_BEGIN
0163 
0164 class Status;
0165 template <typename T>
0166 class StatusOr;
0167 
0168 namespace status_internal {
0169 ABSL_ATTRIBUTE_PURE_FUNCTION std::string* MakeCheckFailString(
0170     const absl::Status* status, const char* prefix);
0171 }  // namespace status_internal
0172 
0173 namespace log_internal {
0174 
0175 // Convert a Status or a StatusOr to its underlying status value.
0176 //
0177 // (This implementation does not require a dep on absl::Status to work.)
0178 inline const absl::Status* AsStatus(const absl::Status& s) { return &s; }
0179 template <typename T>
0180 const absl::Status* AsStatus(const absl::StatusOr<T>& s) {
0181   return &s.status();
0182 }
0183 
0184 // A helper class for formatting `expr (V1 vs. V2)` in a `CHECK_XX` statement.
0185 // See `MakeCheckOpString` for sample usage.
0186 class CheckOpMessageBuilder final {
0187  public:
0188   // Inserts `exprtext` and ` (` to the stream.
0189   explicit CheckOpMessageBuilder(const char* exprtext);
0190   ~CheckOpMessageBuilder() = default;
0191   // For inserting the first variable.
0192   std::ostream& ForVar1() { return stream_; }
0193   // For inserting the second variable (adds an intermediate ` vs. `).
0194   std::ostream& ForVar2();
0195   // Get the result (inserts the closing `)`).
0196   std::string* NewString();
0197 
0198  private:
0199   std::ostringstream stream_;
0200 };
0201 
0202 // This formats a value for a failing `CHECK_XX` statement.  Ordinarily, it uses
0203 // the definition for `operator<<`, with a few special cases below.
0204 template <typename T>
0205 inline void MakeCheckOpValueString(std::ostream& os, const T& v) {
0206   os << log_internal::NullGuard<T>::Guard(v);
0207 }
0208 
0209 // Overloads for char types provide readable values for unprintable characters.
0210 void MakeCheckOpValueString(std::ostream& os, char v);
0211 void MakeCheckOpValueString(std::ostream& os, signed char v);
0212 void MakeCheckOpValueString(std::ostream& os, unsigned char v);
0213 void MakeCheckOpValueString(std::ostream& os, const void* p);
0214 
0215 namespace detect_specialization {
0216 
0217 // MakeCheckOpString is being specialized for every T and U pair that is being
0218 // passed to the CHECK_op macros. However, there is a lot of redundancy in these
0219 // specializations that creates unnecessary library and binary bloat.
0220 // The number of instantiations tends to be O(n^2) because we have two
0221 // independent inputs. This technique works by reducing `n`.
0222 //
0223 // Most user-defined types being passed to CHECK_op end up being printed as a
0224 // builtin type. For example, enums tend to be implicitly converted to its
0225 // underlying type when calling operator<<, and pointers are printed with the
0226 // `const void*` overload.
0227 // To reduce the number of instantiations we coerce these values before calling
0228 // MakeCheckOpString instead of inside it.
0229 //
0230 // To detect if this coercion is needed, we duplicate all the relevant
0231 // operator<< overloads as specified in the standard, just in a different
0232 // namespace. If the call to `stream << value` becomes ambiguous, it means that
0233 // one of these overloads is the one selected by overload resolution. We then
0234 // do overload resolution again just with our overload set to see which one gets
0235 // selected. That tells us which type to coerce to.
0236 // If the augmented call was not ambiguous, it means that none of these were
0237 // selected and we can't coerce the input.
0238 //
0239 // As a secondary step to reduce code duplication, we promote integral types to
0240 // their 64-bit variant. This does not change the printed value, but reduces the
0241 // number of instantiations even further. Promoting an integer is very cheap at
0242 // the call site.
0243 int64_t operator<<(std::ostream&, short value);           // NOLINT
0244 int64_t operator<<(std::ostream&, unsigned short value);  // NOLINT
0245 int64_t operator<<(std::ostream&, int value);
0246 int64_t operator<<(std::ostream&, unsigned int value);
0247 int64_t operator<<(std::ostream&, long value);                 // NOLINT
0248 uint64_t operator<<(std::ostream&, unsigned long value);       // NOLINT
0249 int64_t operator<<(std::ostream&, long long value);            // NOLINT
0250 uint64_t operator<<(std::ostream&, unsigned long long value);  // NOLINT
0251 float operator<<(std::ostream&, float value);
0252 double operator<<(std::ostream&, double value);
0253 long double operator<<(std::ostream&, long double value);
0254 bool operator<<(std::ostream&, bool value);
0255 const void* operator<<(std::ostream&, const void* value);
0256 const void* operator<<(std::ostream&, std::nullptr_t);
0257 
0258 // These `char` overloads are specified like this in the standard, so we have to
0259 // write them exactly the same to ensure the call is ambiguous.
0260 // If we wrote it in a different way (eg taking std::ostream instead of the
0261 // template) then one call might have a higher rank than the other and it would
0262 // not be ambiguous.
0263 template <typename Traits>
0264 char operator<<(std::basic_ostream<char, Traits>&, char);
0265 template <typename Traits>
0266 signed char operator<<(std::basic_ostream<char, Traits>&, signed char);
0267 template <typename Traits>
0268 unsigned char operator<<(std::basic_ostream<char, Traits>&, unsigned char);
0269 template <typename Traits>
0270 const char* operator<<(std::basic_ostream<char, Traits>&, const char*);
0271 template <typename Traits>
0272 const signed char* operator<<(std::basic_ostream<char, Traits>&,
0273                               const signed char*);
0274 template <typename Traits>
0275 const unsigned char* operator<<(std::basic_ostream<char, Traits>&,
0276                                 const unsigned char*);
0277 
0278 // This overload triggers when the call is not ambiguous.
0279 // It means that T is being printed with some overload not on this list.
0280 // We keep the value as `const T&`.
0281 template <typename T, typename = decltype(std::declval<std::ostream&>()
0282                                           << std::declval<const T&>())>
0283 const T& Detect(int);
0284 
0285 // This overload triggers when the call is ambiguous.
0286 // It means that T is either one from this list or printed as one from this
0287 // list. Eg an enum that decays to `int` for printing.
0288 // We ask the overload set to give us the type we want to convert it to.
0289 template <typename T>
0290 decltype(detect_specialization::operator<<(std::declval<std::ostream&>(),
0291                                            std::declval<const T&>()))
0292 Detect(char);
0293 
0294 // A sink for AbslStringify which redirects everything to a std::ostream.
0295 class StringifySink {
0296  public:
0297   explicit StringifySink(std::ostream& os ABSL_ATTRIBUTE_LIFETIME_BOUND);
0298 
0299   void Append(absl::string_view text);
0300   void Append(size_t length, char ch);
0301   friend void AbslFormatFlush(StringifySink* sink, absl::string_view text);
0302 
0303  private:
0304   std::ostream& os_;
0305 };
0306 
0307 // Wraps a type implementing AbslStringify, and implements operator<<.
0308 template <typename T>
0309 class StringifyToStreamWrapper {
0310  public:
0311   explicit StringifyToStreamWrapper(const T& v ABSL_ATTRIBUTE_LIFETIME_BOUND)
0312       : v_(v) {}
0313 
0314   friend std::ostream& operator<<(std::ostream& os,
0315                                   const StringifyToStreamWrapper& wrapper) {
0316     StringifySink sink(os);
0317     AbslStringify(sink, wrapper.v_);
0318     return os;
0319   }
0320 
0321  private:
0322   const T& v_;
0323 };
0324 
0325 // This overload triggers when T implements AbslStringify.
0326 // StringifyToStreamWrapper is used to allow MakeCheckOpString to use
0327 // operator<<.
0328 template <typename T>
0329 std::enable_if_t<HasAbslStringify<T>::value,
0330                  StringifyToStreamWrapper<T>>
0331 Detect(...);  // Ellipsis has lowest preference when int passed.
0332 }  // namespace detect_specialization
0333 
0334 template <typename T>
0335 using CheckOpStreamType = decltype(detect_specialization::Detect<T>(0));
0336 
0337 // Build the error message string.  Specify no inlining for code size.
0338 template <typename T1, typename T2>
0339 ABSL_ATTRIBUTE_RETURNS_NONNULL std::string* MakeCheckOpString(
0340     T1 v1, T2 v2, const char* exprtext) ABSL_ATTRIBUTE_NOINLINE;
0341 
0342 template <typename T1, typename T2>
0343 std::string* MakeCheckOpString(T1 v1, T2 v2, const char* exprtext) {
0344   CheckOpMessageBuilder comb(exprtext);
0345   MakeCheckOpValueString(comb.ForVar1(), v1);
0346   MakeCheckOpValueString(comb.ForVar2(), v2);
0347   return comb.NewString();
0348 }
0349 
0350 // Add a few commonly used instantiations as extern to reduce size of objects
0351 // files.
0352 #define ABSL_LOG_INTERNAL_DEFINE_MAKE_CHECK_OP_STRING_EXTERN(x) \
0353   extern template std::string* MakeCheckOpString(x, x, const char*)
0354 ABSL_LOG_INTERNAL_DEFINE_MAKE_CHECK_OP_STRING_EXTERN(bool);
0355 ABSL_LOG_INTERNAL_DEFINE_MAKE_CHECK_OP_STRING_EXTERN(int64_t);
0356 ABSL_LOG_INTERNAL_DEFINE_MAKE_CHECK_OP_STRING_EXTERN(uint64_t);
0357 ABSL_LOG_INTERNAL_DEFINE_MAKE_CHECK_OP_STRING_EXTERN(float);
0358 ABSL_LOG_INTERNAL_DEFINE_MAKE_CHECK_OP_STRING_EXTERN(double);
0359 ABSL_LOG_INTERNAL_DEFINE_MAKE_CHECK_OP_STRING_EXTERN(char);
0360 ABSL_LOG_INTERNAL_DEFINE_MAKE_CHECK_OP_STRING_EXTERN(unsigned char);
0361 ABSL_LOG_INTERNAL_DEFINE_MAKE_CHECK_OP_STRING_EXTERN(const std::string&);
0362 ABSL_LOG_INTERNAL_DEFINE_MAKE_CHECK_OP_STRING_EXTERN(const absl::string_view&);
0363 ABSL_LOG_INTERNAL_DEFINE_MAKE_CHECK_OP_STRING_EXTERN(const char*);
0364 ABSL_LOG_INTERNAL_DEFINE_MAKE_CHECK_OP_STRING_EXTERN(const signed char*);
0365 ABSL_LOG_INTERNAL_DEFINE_MAKE_CHECK_OP_STRING_EXTERN(const unsigned char*);
0366 ABSL_LOG_INTERNAL_DEFINE_MAKE_CHECK_OP_STRING_EXTERN(const void*);
0367 #undef ABSL_LOG_INTERNAL_DEFINE_MAKE_CHECK_OP_STRING_EXTERN
0368 
0369 // `ABSL_LOG_INTERNAL_CHECK_OP_IMPL_RESULT` skips formatting the Check_OP result
0370 // string iff `ABSL_MIN_LOG_LEVEL` exceeds `kFatal`, instead returning an empty
0371 // string.
0372 #ifdef ABSL_MIN_LOG_LEVEL
0373 #define ABSL_LOG_INTERNAL_CHECK_OP_IMPL_RESULT(U1, U2, v1, v2, exprtext) \
0374   ((::absl::LogSeverity::kFatal >=                                       \
0375     static_cast<::absl::LogSeverity>(ABSL_MIN_LOG_LEVEL))                \
0376        ? MakeCheckOpString<U1, U2>(v1, v2, exprtext)                     \
0377        : new std::string())
0378 #else
0379 #define ABSL_LOG_INTERNAL_CHECK_OP_IMPL_RESULT(U1, U2, v1, v2, exprtext) \
0380   MakeCheckOpString<U1, U2>(v1, v2, exprtext)
0381 #endif
0382 
0383 // Helper functions for `ABSL_LOG_INTERNAL_CHECK_OP` macro family.  The
0384 // `(int, int)` override works around the issue that the compiler will not
0385 // instantiate the template version of the function on values of unnamed enum
0386 // type.
0387 #define ABSL_LOG_INTERNAL_CHECK_OP_IMPL(name, op)                          \
0388   template <typename T1, typename T2>                                      \
0389   inline constexpr ::std::string* name##Impl(const T1& v1, const T2& v2,   \
0390                                              const char* exprtext) {       \
0391     using U1 = CheckOpStreamType<T1>;                                      \
0392     using U2 = CheckOpStreamType<T2>;                                      \
0393     return ABSL_PREDICT_TRUE(v1 op v2)                                     \
0394                ? nullptr                                                   \
0395                : ABSL_LOG_INTERNAL_CHECK_OP_IMPL_RESULT(U1, U2, U1(v1),    \
0396                                                         U2(v2), exprtext); \
0397   }                                                                        \
0398   inline constexpr ::std::string* name##Impl(int v1, int v2,               \
0399                                              const char* exprtext) {       \
0400     return name##Impl<int, int>(v1, v2, exprtext);                         \
0401   }
0402 
0403 ABSL_LOG_INTERNAL_CHECK_OP_IMPL(Check_EQ, ==)
0404 ABSL_LOG_INTERNAL_CHECK_OP_IMPL(Check_NE, !=)
0405 ABSL_LOG_INTERNAL_CHECK_OP_IMPL(Check_LE, <=)
0406 ABSL_LOG_INTERNAL_CHECK_OP_IMPL(Check_LT, <)
0407 ABSL_LOG_INTERNAL_CHECK_OP_IMPL(Check_GE, >=)
0408 ABSL_LOG_INTERNAL_CHECK_OP_IMPL(Check_GT, >)
0409 #undef ABSL_LOG_INTERNAL_CHECK_OP_IMPL_RESULT
0410 #undef ABSL_LOG_INTERNAL_CHECK_OP_IMPL
0411 
0412 std::string* CheckstrcmptrueImpl(const char* s1, const char* s2,
0413                                  const char* exprtext);
0414 std::string* CheckstrcmpfalseImpl(const char* s1, const char* s2,
0415                                   const char* exprtext);
0416 std::string* CheckstrcasecmptrueImpl(const char* s1, const char* s2,
0417                                      const char* exprtext);
0418 std::string* CheckstrcasecmpfalseImpl(const char* s1, const char* s2,
0419                                       const char* exprtext);
0420 
0421 // `CHECK_EQ` and friends want to pass their arguments by reference, however
0422 // this winds up exposing lots of cases where people have defined and
0423 // initialized static const data members but never declared them (i.e. in a .cc
0424 // file), meaning they are not referenceable.  This function avoids that problem
0425 // for integers (the most common cases) by overloading for every primitive
0426 // integer type, even the ones we discourage, and returning them by value.
0427 template <typename T>
0428 inline constexpr const T& GetReferenceableValue(const T& t) {
0429   return t;
0430 }
0431 inline constexpr char GetReferenceableValue(char t) { return t; }
0432 inline constexpr unsigned char GetReferenceableValue(unsigned char t) {
0433   return t;
0434 }
0435 inline constexpr signed char GetReferenceableValue(signed char t) { return t; }
0436 inline constexpr short GetReferenceableValue(short t) { return t; }  // NOLINT
0437 inline constexpr unsigned short GetReferenceableValue(               // NOLINT
0438     unsigned short t) {                                              // NOLINT
0439   return t;
0440 }
0441 inline constexpr int GetReferenceableValue(int t) { return t; }
0442 inline constexpr unsigned int GetReferenceableValue(unsigned int t) {
0443   return t;
0444 }
0445 inline constexpr long GetReferenceableValue(long t) { return t; }  // NOLINT
0446 inline constexpr unsigned long GetReferenceableValue(              // NOLINT
0447     unsigned long t) {                                             // NOLINT
0448   return t;
0449 }
0450 inline constexpr long long GetReferenceableValue(long long t) {  // NOLINT
0451   return t;
0452 }
0453 inline constexpr unsigned long long GetReferenceableValue(  // NOLINT
0454     unsigned long long t) {                                 // NOLINT
0455   return t;
0456 }
0457 
0458 }  // namespace log_internal
0459 ABSL_NAMESPACE_END
0460 }  // namespace absl
0461 
0462 #endif  // ABSL_LOG_INTERNAL_CHECK_OP_H_