Coverage Report

Created: 2025-08-25 06:55

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