11diff --git a/absl/flags/declare.h b/absl/flags/declare.h
2- index 8d2a856..a154046 100644
2+ index 8d2a856e..a1540467 100644
33--- a/absl/flags/declare.h
44+++ b/absl/flags/declare.h
55@@ -59,10 +59,15 @@ ABSL_NAMESPACE_END
@@ -18,3 +18,108 @@ index 8d2a856..a154046 100644
1818+ #endif // _MSC_VER
1919
2020 #endif // ABSL_FLAGS_DECLARE_H_
21+ diff --git a/absl/log/CMakeLists.txt b/absl/log/CMakeLists.txt
22+ index eb19bec0..13b2d240 100644
23+ --- a/absl/log/CMakeLists.txt
24+ +++ b/absl/log/CMakeLists.txt
25+ @@ -47,6 +47,7 @@ absl_cc_library(
26+ absl::base
27+ absl::config
28+ absl::core_headers
29+ + absl::has_ostream_operator
30+ absl::leak_check
31+ absl::log_internal_nullguard
32+ absl::log_internal_nullstream
33+ diff --git a/absl/log/check_test_impl.inc b/absl/log/check_test_impl.inc
34+ index 5a7caf47..7bcedd40 100644
35+ --- a/absl/log/check_test_impl.inc
36+ +++ b/absl/log/check_test_impl.inc
37+ @@ -13,6 +13,8 @@
38+ // See the License for the specific language governing permissions and
39+ // limitations under the License.
40+
41+ + // SKIP_ABSL_INLINE_NAMESPACE_CHECK
42+ +
43+ #ifndef ABSL_LOG_CHECK_TEST_IMPL_H_
44+ #define ABSL_LOG_CHECK_TEST_IMPL_H_
45+
46+ @@ -241,6 +243,18 @@ TEST(CHECKTest, TestBinaryChecksWithPrimitives) {
47+ ABSL_TEST_CHECK_LT(1, 2);
48+ }
49+
50+ + TEST(CHECKTest, TestBinaryChecksWithStringComparison) {
51+ + const std::string a = "a";
52+ + ABSL_TEST_CHECK_EQ(a, "a");
53+ + ABSL_TEST_CHECK_NE(a, "b");
54+ + ABSL_TEST_CHECK_GE(a, a);
55+ + ABSL_TEST_CHECK_GE("b", a);
56+ + ABSL_TEST_CHECK_LE(a, "a");
57+ + ABSL_TEST_CHECK_LE(a, "b");
58+ + ABSL_TEST_CHECK_GT("b", a);
59+ + ABSL_TEST_CHECK_LT(a, "b");
60+ + }
61+ +
62+ // For testing using CHECK*() on anonymous enums.
63+ enum { CASE_A, CASE_B };
64+
65+ diff --git a/absl/log/internal/BUILD.bazel b/absl/log/internal/BUILD.bazel
66+ index 1ba9d766..005861f9 100644
67+ --- a/absl/log/internal/BUILD.bazel
68+ +++ b/absl/log/internal/BUILD.bazel
69+ @@ -82,6 +82,7 @@ cc_library(
70+ "//absl/base:nullability",
71+ "//absl/debugging:leak_check",
72+ "//absl/strings",
73+ + "//absl/strings:has_ostream_operator",
74+ ],
75+ )
76+
77+ diff --git a/absl/log/internal/check_op.h b/absl/log/internal/check_op.h
78+ index 4554475d..c6078640 100644
79+ --- a/absl/log/internal/check_op.h
80+ +++ b/absl/log/internal/check_op.h
81+ @@ -40,6 +40,7 @@
82+ #include "absl/log/internal/nullstream.h"
83+ #include "absl/log/internal/strip.h"
84+ #include "absl/strings/has_absl_stringify.h"
85+ + #include "absl/strings/has_ostream_operator.h"
86+ #include "absl/strings/string_view.h"
87+
88+ // `ABSL_LOG_INTERNAL_STRIP_STRING_LITERAL` wraps string literals that
89+ @@ -357,21 +358,12 @@ std::enable_if_t<HasAbslStringify<T>::value,
90+ StringifyToStreamWrapper<T>>
91+ Detect(...); // Ellipsis has lowest preference when int passed.
92+
93+ - // is_streamable is true for types that have an output stream operator<<.
94+ - template <class T, class = void>
95+ - struct is_streamable : std::false_type {};
96+ -
97+ - template <class T>
98+ - struct is_streamable<T, std::void_t<decltype(std::declval<std::ostream&>()
99+ - << std::declval<T>())>>
100+ - : std::true_type {};
101+ -
102+ // This overload triggers when T is neither possible to print nor an enum.
103+ template <typename T>
104+ std::enable_if_t<std::negation_v<std::disjunction<
105+ std::is_convertible<T, int>, std::is_enum<T>,
106+ std::is_pointer<T>, std::is_same<T, std::nullptr_t>,
107+ - is_streamable<T>, HasAbslStringify<T>>>,
108+ + HasOstreamOperator<T>, HasAbslStringify<T>>>,
109+ UnprintableWrapper>
110+ Detect(...);
111+
112+ @@ -382,9 +374,10 @@ Detect(...);
113+ // one backed by another integer is converted to (u)int64_t.
114+ template <typename T>
115+ std::enable_if_t<
116+ - std::conjunction_v<
117+ - std::is_enum<T>, std::negation<std::is_convertible<T, int>>,
118+ - std::negation<is_streamable<T>>, std::negation<HasAbslStringify<T>>>,
119+ + std::conjunction_v<std::is_enum<T>,
120+ + std::negation<std::is_convertible<T, int>>,
121+ + std::negation<HasOstreamOperator<T>>,
122+ + std::negation<HasAbslStringify<T>>>,
123+ std::conditional_t<
124+ std::is_same_v<std::underlying_type_t<T>, bool> ||
125+ std::is_same_v<std::underlying_type_t<T>, char> ||
0 commit comments