Skip to content

Commit 5cb7bf6

Browse files
[Support] Simplify has_StreamOperator (NFC) (#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.
1 parent 0d989b2 commit 5cb7bf6

File tree

1 file changed

+6
-7
lines changed

1 file changed

+6
-7
lines changed

llvm/include/llvm/Support/FormatVariadicDetails.h

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -78,15 +78,14 @@ template <class T> class has_StreamOperator {
7878
using ConstRefT = const std::decay_t<T> &;
7979

8080
template <typename U>
81-
static char test(std::enable_if_t<
82-
std::is_same_v<decltype(std::declval<llvm::raw_ostream &>()
83-
<< std::declval<U>()),
84-
llvm::raw_ostream &>,
85-
int *>);
81+
static auto test(int)
82+
-> std::is_same<decltype(std::declval<llvm::raw_ostream &>()
83+
<< std::declval<U>()),
84+
llvm::raw_ostream &>;
8685

87-
template <typename U> static double test(...);
86+
template <typename U> static auto test(...) -> std::false_type;
8887

89-
static bool const value = (sizeof(test<ConstRefT>(nullptr)) == 1);
88+
static constexpr bool value = decltype(test<ConstRefT>(0))::value;
9089
};
9190

9291
// Simple template that decides whether a type T should use the member-function

0 commit comments

Comments
 (0)