[llvm] [ADT] Simplify a constructor of iterator_range (NFC) (PR #158005)
Kazu Hirata via llvm-commits
llvm-commits at lists.llvm.org
Thu Sep 11 00:13:38 PDT 2025
https://github.com/kazutakahirata created https://github.com/llvm/llvm-project/pull/158005
Without this patch, we determine whether one iterator type can be
converted to another in a roundabout way. Specifically,
explicitly_convertible uses std::void_t to determine whether the given
conversion expression is well formed, yielding
std::true_type/std::false_type. Then the boolean value is passed to
std::enable_if_t to obtain void again. That is, we are doing a
roundtrip from void to a boolean value and back.
This patch removes the roundtrip by directly using std::void_t inside
the constructor's template parameter list.
Now, explicitly_converted_t is very similar to std::is_constructible,
but there a couple of corner cases where they evaluate to different
values. For now, this patch sticks to the same expression
decltype(static_cast<To>(...)) to be safe.
>From 8ba6acf92569b4147f7b0389d1a5b7e060920342 Mon Sep 17 00:00:00 2001
From: Kazu Hirata <kazu at google.com>
Date: Tue, 9 Sep 2025 22:19:20 -0700
Subject: [PATCH] [ADT] Simplify a constructor of iterator_range (NFC)
Without this patch, we determine whether one iterator type can be
converted to another in a roundabout way. Specifically,
explicitly_convertible uses std::void_t to determine whether the given
conversion expression is well formed, yielding
std::true_type/std::false_type. Then the boolean value is passed to
std::enable_if_t to obtain void again. That is, we are doing a
roundtrip from void to a boolean value and back.
This patch removes the roundtrip by directly using std::void_t inside
the constructor's template parameter list.
Now, explicitly_converted_t is very similar to std::is_constructible,
but there a couple of corner cases where they evaluate to different
values. For now, this patch sticks to the same expression
decltype(static_cast<To>(...)) to be safe.
---
llvm/include/llvm/ADT/iterator_range.h | 21 +++++++--------------
1 file changed, 7 insertions(+), 14 deletions(-)
diff --git a/llvm/include/llvm/ADT/iterator_range.h b/llvm/include/llvm/ADT/iterator_range.h
index 8e9b22f2d4dfa..cc8070eb4d528 100644
--- a/llvm/include/llvm/ADT/iterator_range.h
+++ b/llvm/include/llvm/ADT/iterator_range.h
@@ -24,16 +24,6 @@
namespace llvm {
-template <typename From, typename To, typename = void>
-struct explicitly_convertible : std::false_type {};
-
-template <typename From, typename To>
-struct explicitly_convertible<
- From, To,
- std::void_t<decltype(static_cast<To>(
- std::declval<std::add_rvalue_reference_t<From>>()))>> : std::true_type {
-};
-
/// A range adaptor for a pair of iterators.
///
/// This just wraps two iterators into a range-compatible interface. Nothing
@@ -42,6 +32,10 @@ template <typename IteratorT>
class iterator_range {
IteratorT begin_iterator, end_iterator;
+ template <typename From, typename To>
+ using explicitly_converted_t = decltype(static_cast<To>(
+ std::declval<std::add_rvalue_reference_t<From>>()));
+
public:
#if defined(__GNUC__) && \
(__GNUC__ == 7 || (__GNUC__ == 8 && __GNUC_MINOR__ < 4))
@@ -49,10 +43,9 @@ class iterator_range {
// See https://github.com/llvm/llvm-project/issues/63843
template <typename Container>
#else
- template <
- typename Container,
- std::enable_if_t<explicitly_convertible<
- llvm::detail::IterOfRange<Container>, IteratorT>::value> * = nullptr>
+ template <typename Container,
+ std::void_t<explicitly_converted_t<
+ llvm::detail::IterOfRange<Container>, IteratorT>> * = nullptr>
#endif
iterator_range(Container &&c)
: begin_iterator(adl_begin(c)), end_iterator(adl_end(c)) {
More information about the llvm-commits
mailing list