[llvm] [Support] Simplify has_StreamOperator (NFC) (PR #159242)
Kazu Hirata via llvm-commits
llvm-commits at lists.llvm.org
Tue Sep 16 22:13:09 PDT 2025
https://github.com/kazutakahirata created https://github.com/llvm/llvm-project/pull/159242
Without this patch, we are doing a roundtrip on types. Specifically,
if decltype(...) is well formed, std::is_same_v evaluates to a boolean
value. We then pass the boolean value to std::enable_if_t, go through
the sizeof(char)/sizeof(double) trick, and then come back to a boolean
value.
This patch simplifies all this by having test() return
std::is_same<...>. The "caller" attaches ::value, so effectively we
are using std::is_same<...>::value when decltype(...) is well formed,
bypassing std::enable_if_t and the sizeof(char)/sizeof(double) trick.
If we did not care about the return type of the shift operator, we
could use llvm::is_detected, but the return type check doesn't allow
us to simplify things that far.
>From 4be236df8af0719472e1a2a52acf09aeb7a0de70 Mon Sep 17 00:00:00 2001
From: Kazu Hirata <kazu at google.com>
Date: Tue, 16 Sep 2025 16:51:04 -0700
Subject: [PATCH] [Support] Simplify has_StreamOperator (NFC)
Without this patch, we are doing a roundtrip on types. Specifically,
if decltype(...) is well formed, std::is_same_v evaluates to a boolean
value. We then pass the boolean value to std::enable_if_t, go through
the sizeof(char)/sizeof(double) trick, and then come back to a boolean
value.
This patch simplifies all this by having test() return
std::is_same<...>. The "caller" attaches ::value, so effectively we
are using std::is_same<...>::value when decltype(...) is well formed,
bypassing std::enable_if_t and the sizeof(char)/sizeof(double) trick.
If we did not care about the return type of the shift operator, we
could use llvm::is_detected, but the return type check doesn't allow
us to simplify things that far.
---
llvm/include/llvm/Support/FormatVariadicDetails.h | 13 ++++++-------
1 file changed, 6 insertions(+), 7 deletions(-)
diff --git a/llvm/include/llvm/Support/FormatVariadicDetails.h b/llvm/include/llvm/Support/FormatVariadicDetails.h
index fa11d56fc1ada..4002caf76675c 100644
--- a/llvm/include/llvm/Support/FormatVariadicDetails.h
+++ b/llvm/include/llvm/Support/FormatVariadicDetails.h
@@ -78,15 +78,14 @@ template <class T> class has_StreamOperator {
using ConstRefT = const std::decay_t<T> &;
template <typename U>
- static char test(std::enable_if_t<
- std::is_same_v<decltype(std::declval<llvm::raw_ostream &>()
- << std::declval<U>()),
- llvm::raw_ostream &>,
- int *>);
+ static auto test(int)
+ -> std::is_same<decltype(std::declval<llvm::raw_ostream &>()
+ << std::declval<U>()),
+ llvm::raw_ostream &>;
- template <typename U> static double test(...);
+ template <typename U> static auto test(...) -> std::false_type;
- static bool const value = (sizeof(test<ConstRefT>(nullptr)) == 1);
+ static constexpr bool value = decltype(test<ConstRefT>(0))::value;
};
// Simple template that decides whether a type T should use the member-function
More information about the llvm-commits
mailing list