check_op.h 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484
  1. // Copyright 2022 The Abseil Authors.
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // https://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. //
  15. // -----------------------------------------------------------------------------
  16. // File: log/internal/check_op.h
  17. // -----------------------------------------------------------------------------
  18. //
  19. // This file declares helpers routines and macros used to implement `CHECK`
  20. // macros.
  21. #ifndef ABSL_LOG_INTERNAL_CHECK_OP_H_
  22. #define ABSL_LOG_INTERNAL_CHECK_OP_H_
  23. #include <stdint.h>
  24. #include <cstddef>
  25. #include <ostream>
  26. #include <sstream>
  27. #include <string>
  28. #include <type_traits>
  29. #include <utility>
  30. #include "absl/base/attributes.h"
  31. #include "absl/base/casts.h"
  32. #include "absl/base/config.h"
  33. #include "absl/base/nullability.h"
  34. #include "absl/base/optimization.h"
  35. #include "absl/log/internal/nullguard.h"
  36. #include "absl/log/internal/nullstream.h"
  37. #include "absl/log/internal/strip.h"
  38. #include "absl/strings/has_absl_stringify.h"
  39. #include "absl/strings/string_view.h"
  40. // `ABSL_LOG_INTERNAL_STRIP_STRING_LITERAL` wraps string literals that
  41. // should be stripped when `ABSL_MIN_LOG_LEVEL` exceeds `kFatal`.
  42. #ifdef ABSL_MIN_LOG_LEVEL
  43. #define ABSL_LOG_INTERNAL_STRIP_STRING_LITERAL(literal) \
  44. (::absl::LogSeverity::kFatal >= \
  45. static_cast<::absl::LogSeverity>(ABSL_MIN_LOG_LEVEL) \
  46. ? (literal) \
  47. : "")
  48. #else
  49. #define ABSL_LOG_INTERNAL_STRIP_STRING_LITERAL(literal) (literal)
  50. #endif
  51. #ifdef NDEBUG
  52. // `NDEBUG` is defined, so `DCHECK_EQ(x, y)` and so on do nothing. However, we
  53. // still want the compiler to parse `x` and `y`, because we don't want to lose
  54. // potentially useful errors and warnings.
  55. #define ABSL_LOG_INTERNAL_DCHECK_NOP(x, y) \
  56. while (false && ((void)(x), (void)(y), 0)) \
  57. ::absl::log_internal::NullStream().InternalStream()
  58. #endif
  59. #define ABSL_LOG_INTERNAL_CHECK_OP(name, op, val1, val1_text, val2, val2_text) \
  60. while (absl::Nullable<const char*> absl_log_internal_check_op_result \
  61. ABSL_LOG_INTERNAL_ATTRIBUTE_UNUSED_IF_STRIP_LOG = \
  62. ::absl::log_internal::name##Impl( \
  63. ::absl::log_internal::GetReferenceableValue(val1), \
  64. ::absl::log_internal::GetReferenceableValue(val2), \
  65. ABSL_LOG_INTERNAL_STRIP_STRING_LITERAL( \
  66. val1_text " " #op " " val2_text))) \
  67. ABSL_LOG_INTERNAL_CONDITION_FATAL(STATELESS, true) \
  68. ABSL_LOG_INTERNAL_CHECK(absl::implicit_cast<absl::Nonnull<const char*>>( \
  69. absl_log_internal_check_op_result)) \
  70. .InternalStream()
  71. #define ABSL_LOG_INTERNAL_QCHECK_OP(name, op, val1, val1_text, val2, \
  72. val2_text) \
  73. while (absl::Nullable<const char*> absl_log_internal_qcheck_op_result = \
  74. ::absl::log_internal::name##Impl( \
  75. ::absl::log_internal::GetReferenceableValue(val1), \
  76. ::absl::log_internal::GetReferenceableValue(val2), \
  77. ABSL_LOG_INTERNAL_STRIP_STRING_LITERAL( \
  78. val1_text " " #op " " val2_text))) \
  79. ABSL_LOG_INTERNAL_CONDITION_QFATAL(STATELESS, true) \
  80. ABSL_LOG_INTERNAL_QCHECK(absl::implicit_cast<absl::Nonnull<const char*>>( \
  81. absl_log_internal_qcheck_op_result)) \
  82. .InternalStream()
  83. #define ABSL_LOG_INTERNAL_CHECK_STROP(func, op, expected, s1, s1_text, s2, \
  84. s2_text) \
  85. while (absl::Nullable<const char*> absl_log_internal_check_strop_result = \
  86. ::absl::log_internal::Check##func##expected##Impl( \
  87. (s1), (s2), \
  88. ABSL_LOG_INTERNAL_STRIP_STRING_LITERAL(s1_text " " #op \
  89. " " s2_text))) \
  90. ABSL_LOG_INTERNAL_CONDITION_FATAL(STATELESS, true) \
  91. ABSL_LOG_INTERNAL_CHECK(absl::implicit_cast<absl::Nonnull<const char*>>( \
  92. absl_log_internal_check_strop_result)) \
  93. .InternalStream()
  94. #define ABSL_LOG_INTERNAL_QCHECK_STROP(func, op, expected, s1, s1_text, s2, \
  95. s2_text) \
  96. while (absl::Nullable<const char*> absl_log_internal_qcheck_strop_result = \
  97. ::absl::log_internal::Check##func##expected##Impl( \
  98. (s1), (s2), \
  99. ABSL_LOG_INTERNAL_STRIP_STRING_LITERAL(s1_text " " #op \
  100. " " s2_text))) \
  101. ABSL_LOG_INTERNAL_CONDITION_QFATAL(STATELESS, true) \
  102. ABSL_LOG_INTERNAL_QCHECK(absl::implicit_cast<absl::Nonnull<const char*>>( \
  103. absl_log_internal_qcheck_strop_result)) \
  104. .InternalStream()
  105. // This one is tricky:
  106. // * We must evaluate `val` exactly once, yet we need to do two things with it:
  107. // evaluate `.ok()` and (sometimes) `.ToString()`.
  108. // * `val` might be an `absl::Status` or some `absl::StatusOr<T>`.
  109. // * `val` might be e.g. `ATemporary().GetStatus()`, which may return a
  110. // reference to a member of `ATemporary` that is only valid until the end of
  111. // the full expression.
  112. // * We don't want this file to depend on `absl::Status` `#include`s or linkage,
  113. // nor do we want to move the definition to status and introduce a dependency
  114. // in the other direction. We can be assured that callers must already have a
  115. // `Status` and the necessary `#include`s and linkage.
  116. // * Callsites should be small and fast (at least when `val.ok()`): one branch,
  117. // minimal stack footprint.
  118. // * In particular, the string concat stuff should be out-of-line and emitted
  119. // in only one TU to save linker input size
  120. // * We want the `val.ok()` check inline so static analyzers and optimizers can
  121. // see it.
  122. // * As usual, no braces so we can stream into the expansion with `operator<<`.
  123. // * Also as usual, it must expand to a single (partial) statement with no
  124. // ambiguous-else problems.
  125. // * When stripped by `ABSL_MIN_LOG_LEVEL`, we must discard the `<expr> is OK`
  126. // string literal and abort without doing any streaming. We don't need to
  127. // strip the call to stringify the non-ok `Status` as long as we don't log it;
  128. // dropping the `Status`'s message text is out of scope.
  129. #define ABSL_LOG_INTERNAL_CHECK_OK(val, val_text) \
  130. for (::std::pair<absl::Nonnull<const ::absl::Status*>, \
  131. absl::Nullable<const char*>> \
  132. absl_log_internal_check_ok_goo; \
  133. absl_log_internal_check_ok_goo.first = \
  134. ::absl::log_internal::AsStatus(val), \
  135. absl_log_internal_check_ok_goo.second = \
  136. ABSL_PREDICT_TRUE(absl_log_internal_check_ok_goo.first->ok()) \
  137. ? nullptr \
  138. : ::absl::status_internal::MakeCheckFailString( \
  139. absl_log_internal_check_ok_goo.first, \
  140. ABSL_LOG_INTERNAL_STRIP_STRING_LITERAL(val_text \
  141. " is OK")), \
  142. !ABSL_PREDICT_TRUE(absl_log_internal_check_ok_goo.first->ok());) \
  143. ABSL_LOG_INTERNAL_CONDITION_FATAL(STATELESS, true) \
  144. ABSL_LOG_INTERNAL_CHECK(absl::implicit_cast<absl::Nonnull<const char*>>( \
  145. absl_log_internal_check_ok_goo.second)) \
  146. .InternalStream()
  147. #define ABSL_LOG_INTERNAL_QCHECK_OK(val, val_text) \
  148. for (::std::pair<absl::Nonnull<const ::absl::Status*>, \
  149. absl::Nullable<const char*>> \
  150. absl_log_internal_qcheck_ok_goo; \
  151. absl_log_internal_qcheck_ok_goo.first = \
  152. ::absl::log_internal::AsStatus(val), \
  153. absl_log_internal_qcheck_ok_goo.second = \
  154. ABSL_PREDICT_TRUE(absl_log_internal_qcheck_ok_goo.first->ok()) \
  155. ? nullptr \
  156. : ::absl::status_internal::MakeCheckFailString( \
  157. absl_log_internal_qcheck_ok_goo.first, \
  158. ABSL_LOG_INTERNAL_STRIP_STRING_LITERAL(val_text \
  159. " is OK")), \
  160. !ABSL_PREDICT_TRUE(absl_log_internal_qcheck_ok_goo.first->ok());) \
  161. ABSL_LOG_INTERNAL_CONDITION_QFATAL(STATELESS, true) \
  162. ABSL_LOG_INTERNAL_QCHECK(absl::implicit_cast<absl::Nonnull<const char*>>( \
  163. absl_log_internal_qcheck_ok_goo.second)) \
  164. .InternalStream()
  165. namespace absl {
  166. ABSL_NAMESPACE_BEGIN
  167. class Status;
  168. template <typename T>
  169. class StatusOr;
  170. namespace status_internal {
  171. ABSL_ATTRIBUTE_PURE_FUNCTION absl::Nonnull<const char*> MakeCheckFailString(
  172. absl::Nonnull<const absl::Status*> status,
  173. absl::Nonnull<const char*> prefix);
  174. } // namespace status_internal
  175. namespace log_internal {
  176. // Convert a Status or a StatusOr to its underlying status value.
  177. //
  178. // (This implementation does not require a dep on absl::Status to work.)
  179. inline absl::Nonnull<const absl::Status*> AsStatus(const absl::Status& s) {
  180. return &s;
  181. }
  182. template <typename T>
  183. absl::Nonnull<const absl::Status*> AsStatus(const absl::StatusOr<T>& s) {
  184. return &s.status();
  185. }
  186. // A helper class for formatting `expr (V1 vs. V2)` in a `CHECK_XX` statement.
  187. // See `MakeCheckOpString` for sample usage.
  188. class CheckOpMessageBuilder final {
  189. public:
  190. // Inserts `exprtext` and ` (` to the stream.
  191. explicit CheckOpMessageBuilder(absl::Nonnull<const char*> exprtext);
  192. ~CheckOpMessageBuilder() = default;
  193. // For inserting the first variable.
  194. std::ostream& ForVar1() { return stream_; }
  195. // For inserting the second variable (adds an intermediate ` vs. `).
  196. std::ostream& ForVar2();
  197. // Get the result (inserts the closing `)`).
  198. absl::Nonnull<const char*> NewString();
  199. private:
  200. std::ostringstream stream_;
  201. };
  202. // This formats a value for a failing `CHECK_XX` statement. Ordinarily, it uses
  203. // the definition for `operator<<`, with a few special cases below.
  204. template <typename T>
  205. inline void MakeCheckOpValueString(std::ostream& os, const T& v) {
  206. os << log_internal::NullGuard<T>::Guard(v);
  207. }
  208. // Overloads for char types provide readable values for unprintable characters.
  209. void MakeCheckOpValueString(std::ostream& os, char v);
  210. void MakeCheckOpValueString(std::ostream& os, signed char v);
  211. void MakeCheckOpValueString(std::ostream& os, unsigned char v);
  212. void MakeCheckOpValueString(std::ostream& os, const void* p);
  213. namespace detect_specialization {
  214. // MakeCheckOpString is being specialized for every T and U pair that is being
  215. // passed to the CHECK_op macros. However, there is a lot of redundancy in these
  216. // specializations that creates unnecessary library and binary bloat.
  217. // The number of instantiations tends to be O(n^2) because we have two
  218. // independent inputs. This technique works by reducing `n`.
  219. //
  220. // Most user-defined types being passed to CHECK_op end up being printed as a
  221. // builtin type. For example, enums tend to be implicitly converted to its
  222. // underlying type when calling operator<<, and pointers are printed with the
  223. // `const void*` overload.
  224. // To reduce the number of instantiations we coerce these values before calling
  225. // MakeCheckOpString instead of inside it.
  226. //
  227. // To detect if this coercion is needed, we duplicate all the relevant
  228. // operator<< overloads as specified in the standard, just in a different
  229. // namespace. If the call to `stream << value` becomes ambiguous, it means that
  230. // one of these overloads is the one selected by overload resolution. We then
  231. // do overload resolution again just with our overload set to see which one gets
  232. // selected. That tells us which type to coerce to.
  233. // If the augmented call was not ambiguous, it means that none of these were
  234. // selected and we can't coerce the input.
  235. //
  236. // As a secondary step to reduce code duplication, we promote integral types to
  237. // their 64-bit variant. This does not change the printed value, but reduces the
  238. // number of instantiations even further. Promoting an integer is very cheap at
  239. // the call site.
  240. int64_t operator<<(std::ostream&, short value); // NOLINT
  241. int64_t operator<<(std::ostream&, unsigned short value); // NOLINT
  242. int64_t operator<<(std::ostream&, int value);
  243. int64_t operator<<(std::ostream&, unsigned int value);
  244. int64_t operator<<(std::ostream&, long value); // NOLINT
  245. uint64_t operator<<(std::ostream&, unsigned long value); // NOLINT
  246. int64_t operator<<(std::ostream&, long long value); // NOLINT
  247. uint64_t operator<<(std::ostream&, unsigned long long value); // NOLINT
  248. float operator<<(std::ostream&, float value);
  249. double operator<<(std::ostream&, double value);
  250. long double operator<<(std::ostream&, long double value);
  251. bool operator<<(std::ostream&, bool value);
  252. const void* operator<<(std::ostream&, const void* value);
  253. const void* operator<<(std::ostream&, std::nullptr_t);
  254. // These `char` overloads are specified like this in the standard, so we have to
  255. // write them exactly the same to ensure the call is ambiguous.
  256. // If we wrote it in a different way (eg taking std::ostream instead of the
  257. // template) then one call might have a higher rank than the other and it would
  258. // not be ambiguous.
  259. template <typename Traits>
  260. char operator<<(std::basic_ostream<char, Traits>&, char);
  261. template <typename Traits>
  262. signed char operator<<(std::basic_ostream<char, Traits>&, signed char);
  263. template <typename Traits>
  264. unsigned char operator<<(std::basic_ostream<char, Traits>&, unsigned char);
  265. template <typename Traits>
  266. const char* operator<<(std::basic_ostream<char, Traits>&, const char*);
  267. template <typename Traits>
  268. const signed char* operator<<(std::basic_ostream<char, Traits>&,
  269. const signed char*);
  270. template <typename Traits>
  271. const unsigned char* operator<<(std::basic_ostream<char, Traits>&,
  272. const unsigned char*);
  273. // This overload triggers when the call is not ambiguous.
  274. // It means that T is being printed with some overload not on this list.
  275. // We keep the value as `const T&`.
  276. template <typename T, typename = decltype(std::declval<std::ostream&>()
  277. << std::declval<const T&>())>
  278. const T& Detect(int);
  279. // This overload triggers when the call is ambiguous.
  280. // It means that T is either one from this list or printed as one from this
  281. // list. Eg an enum that decays to `int` for printing.
  282. // We ask the overload set to give us the type we want to convert it to.
  283. template <typename T>
  284. decltype(detect_specialization::operator<<(std::declval<std::ostream&>(),
  285. std::declval<const T&>()))
  286. Detect(char);
  287. // A sink for AbslStringify which redirects everything to a std::ostream.
  288. class StringifySink {
  289. public:
  290. explicit StringifySink(std::ostream& os ABSL_ATTRIBUTE_LIFETIME_BOUND);
  291. void Append(absl::string_view text);
  292. void Append(size_t length, char ch);
  293. friend void AbslFormatFlush(StringifySink* sink, absl::string_view text);
  294. private:
  295. std::ostream& os_;
  296. };
  297. // Wraps a type implementing AbslStringify, and implements operator<<.
  298. template <typename T>
  299. class StringifyToStreamWrapper {
  300. public:
  301. explicit StringifyToStreamWrapper(const T& v ABSL_ATTRIBUTE_LIFETIME_BOUND)
  302. : v_(v) {}
  303. friend std::ostream& operator<<(std::ostream& os,
  304. const StringifyToStreamWrapper& wrapper) {
  305. StringifySink sink(os);
  306. AbslStringify(sink, wrapper.v_);
  307. return os;
  308. }
  309. private:
  310. const T& v_;
  311. };
  312. // This overload triggers when T implements AbslStringify.
  313. // StringifyToStreamWrapper is used to allow MakeCheckOpString to use
  314. // operator<<.
  315. template <typename T>
  316. std::enable_if_t<HasAbslStringify<T>::value,
  317. StringifyToStreamWrapper<T>>
  318. Detect(...); // Ellipsis has lowest preference when int passed.
  319. } // namespace detect_specialization
  320. template <typename T>
  321. using CheckOpStreamType = decltype(detect_specialization::Detect<T>(0));
  322. // Build the error message string. Specify no inlining for code size.
  323. template <typename T1, typename T2>
  324. ABSL_ATTRIBUTE_RETURNS_NONNULL absl::Nonnull<const char*> MakeCheckOpString(
  325. T1 v1, T2 v2, absl::Nonnull<const char*> exprtext) ABSL_ATTRIBUTE_NOINLINE;
  326. template <typename T1, typename T2>
  327. absl::Nonnull<const char*> MakeCheckOpString(
  328. T1 v1, T2 v2, absl::Nonnull<const char*> exprtext) {
  329. CheckOpMessageBuilder comb(exprtext);
  330. MakeCheckOpValueString(comb.ForVar1(), v1);
  331. MakeCheckOpValueString(comb.ForVar2(), v2);
  332. return comb.NewString();
  333. }
  334. // Add a few commonly used instantiations as extern to reduce size of objects
  335. // files.
  336. #define ABSL_LOG_INTERNAL_DEFINE_MAKE_CHECK_OP_STRING_EXTERN(x) \
  337. extern template absl::Nonnull<const char*> MakeCheckOpString( \
  338. x, x, absl::Nonnull<const char*>)
  339. ABSL_LOG_INTERNAL_DEFINE_MAKE_CHECK_OP_STRING_EXTERN(bool);
  340. ABSL_LOG_INTERNAL_DEFINE_MAKE_CHECK_OP_STRING_EXTERN(int64_t);
  341. ABSL_LOG_INTERNAL_DEFINE_MAKE_CHECK_OP_STRING_EXTERN(uint64_t);
  342. ABSL_LOG_INTERNAL_DEFINE_MAKE_CHECK_OP_STRING_EXTERN(float);
  343. ABSL_LOG_INTERNAL_DEFINE_MAKE_CHECK_OP_STRING_EXTERN(double);
  344. ABSL_LOG_INTERNAL_DEFINE_MAKE_CHECK_OP_STRING_EXTERN(char);
  345. ABSL_LOG_INTERNAL_DEFINE_MAKE_CHECK_OP_STRING_EXTERN(unsigned char);
  346. ABSL_LOG_INTERNAL_DEFINE_MAKE_CHECK_OP_STRING_EXTERN(const std::string&);
  347. ABSL_LOG_INTERNAL_DEFINE_MAKE_CHECK_OP_STRING_EXTERN(const absl::string_view&);
  348. ABSL_LOG_INTERNAL_DEFINE_MAKE_CHECK_OP_STRING_EXTERN(const char*);
  349. ABSL_LOG_INTERNAL_DEFINE_MAKE_CHECK_OP_STRING_EXTERN(const signed char*);
  350. ABSL_LOG_INTERNAL_DEFINE_MAKE_CHECK_OP_STRING_EXTERN(const unsigned char*);
  351. ABSL_LOG_INTERNAL_DEFINE_MAKE_CHECK_OP_STRING_EXTERN(const void*);
  352. #undef ABSL_LOG_INTERNAL_DEFINE_MAKE_CHECK_OP_STRING_EXTERN
  353. // `ABSL_LOG_INTERNAL_CHECK_OP_IMPL_RESULT` skips formatting the Check_OP result
  354. // string iff `ABSL_MIN_LOG_LEVEL` exceeds `kFatal`, instead returning an empty
  355. // string.
  356. #ifdef ABSL_MIN_LOG_LEVEL
  357. #define ABSL_LOG_INTERNAL_CHECK_OP_IMPL_RESULT(U1, U2, v1, v2, exprtext) \
  358. ((::absl::LogSeverity::kFatal >= \
  359. static_cast<::absl::LogSeverity>(ABSL_MIN_LOG_LEVEL)) \
  360. ? MakeCheckOpString<U1, U2>(v1, v2, exprtext) \
  361. : "")
  362. #else
  363. #define ABSL_LOG_INTERNAL_CHECK_OP_IMPL_RESULT(U1, U2, v1, v2, exprtext) \
  364. MakeCheckOpString<U1, U2>(v1, v2, exprtext)
  365. #endif
  366. // Helper functions for `ABSL_LOG_INTERNAL_CHECK_OP` macro family. The
  367. // `(int, int)` override works around the issue that the compiler will not
  368. // instantiate the template version of the function on values of unnamed enum
  369. // type.
  370. #define ABSL_LOG_INTERNAL_CHECK_OP_IMPL(name, op) \
  371. template <typename T1, typename T2> \
  372. inline constexpr absl::Nullable<const char*> name##Impl( \
  373. const T1& v1, const T2& v2, absl::Nonnull<const char*> exprtext) { \
  374. using U1 = CheckOpStreamType<T1>; \
  375. using U2 = CheckOpStreamType<T2>; \
  376. return ABSL_PREDICT_TRUE(v1 op v2) \
  377. ? nullptr \
  378. : ABSL_LOG_INTERNAL_CHECK_OP_IMPL_RESULT(U1, U2, U1(v1), \
  379. U2(v2), exprtext); \
  380. } \
  381. inline constexpr absl::Nullable<const char*> name##Impl( \
  382. int v1, int v2, absl::Nonnull<const char*> exprtext) { \
  383. return name##Impl<int, int>(v1, v2, exprtext); \
  384. }
  385. ABSL_LOG_INTERNAL_CHECK_OP_IMPL(Check_EQ, ==)
  386. ABSL_LOG_INTERNAL_CHECK_OP_IMPL(Check_NE, !=)
  387. ABSL_LOG_INTERNAL_CHECK_OP_IMPL(Check_LE, <=)
  388. ABSL_LOG_INTERNAL_CHECK_OP_IMPL(Check_LT, <)
  389. ABSL_LOG_INTERNAL_CHECK_OP_IMPL(Check_GE, >=)
  390. ABSL_LOG_INTERNAL_CHECK_OP_IMPL(Check_GT, >)
  391. #undef ABSL_LOG_INTERNAL_CHECK_OP_IMPL_RESULT
  392. #undef ABSL_LOG_INTERNAL_CHECK_OP_IMPL
  393. absl::Nullable<const char*> CheckstrcmptrueImpl(
  394. absl::Nullable<const char*> s1, absl::Nullable<const char*> s2,
  395. absl::Nonnull<const char*> exprtext);
  396. absl::Nullable<const char*> CheckstrcmpfalseImpl(
  397. absl::Nullable<const char*> s1, absl::Nullable<const char*> s2,
  398. absl::Nonnull<const char*> exprtext);
  399. absl::Nullable<const char*> CheckstrcasecmptrueImpl(
  400. absl::Nullable<const char*> s1, absl::Nullable<const char*> s2,
  401. absl::Nonnull<const char*> exprtext);
  402. absl::Nullable<const char*> CheckstrcasecmpfalseImpl(
  403. absl::Nullable<const char*> s1, absl::Nullable<const char*> s2,
  404. absl::Nonnull<const char*> exprtext);
  405. // `CHECK_EQ` and friends want to pass their arguments by reference, however
  406. // this winds up exposing lots of cases where people have defined and
  407. // initialized static const data members but never declared them (i.e. in a .cc
  408. // file), meaning they are not referenceable. This function avoids that problem
  409. // for integers (the most common cases) by overloading for every primitive
  410. // integer type, even the ones we discourage, and returning them by value.
  411. // NOLINTBEGIN(runtime/int)
  412. // NOLINTBEGIN(google-runtime-int)
  413. template <typename T>
  414. inline constexpr const T& GetReferenceableValue(const T& t) {
  415. return t;
  416. }
  417. inline constexpr char GetReferenceableValue(char t) { return t; }
  418. inline constexpr unsigned char GetReferenceableValue(unsigned char t) {
  419. return t;
  420. }
  421. inline constexpr signed char GetReferenceableValue(signed char t) { return t; }
  422. inline constexpr short GetReferenceableValue(short t) { return t; }
  423. inline constexpr unsigned short GetReferenceableValue(unsigned short t) {
  424. return t;
  425. }
  426. inline constexpr int GetReferenceableValue(int t) { return t; }
  427. inline constexpr unsigned int GetReferenceableValue(unsigned int t) {
  428. return t;
  429. }
  430. inline constexpr long GetReferenceableValue(long t) { return t; }
  431. inline constexpr unsigned long GetReferenceableValue(unsigned long t) {
  432. return t;
  433. }
  434. inline constexpr long long GetReferenceableValue(long long t) { return t; }
  435. inline constexpr unsigned long long GetReferenceableValue(
  436. unsigned long long t) {
  437. return t;
  438. }
  439. // NOLINTEND(google-runtime-int)
  440. // NOLINTEND(runtime/int)
  441. } // namespace log_internal
  442. ABSL_NAMESPACE_END
  443. } // namespace absl
  444. #endif // ABSL_LOG_INTERNAL_CHECK_OP_H_