[libcxx-commits] [libcxx] [libc++] Use __detected_or_t to implement __has_iterator_{category, concept}_convertible_to (PR #124456)

Nikolas Klauser via libcxx-commits libcxx-commits at lists.llvm.org
Mon Jan 27 03:35:42 PST 2025


https://github.com/philnik777 updated https://github.com/llvm/llvm-project/pull/124456

>From 5716995886c7e2a1511019a5fdc0959a1c9330ae Mon Sep 17 00:00:00 2001
From: Nikolas Klauser <nikolasklauser at berlin.de>
Date: Sun, 26 Jan 2025 09:54:21 +0100
Subject: [PATCH] [libc++] Use __detected_or_t to implement
 __has_iterator_{category,concept}_convertible_to

---
 libcxx/include/__iterator/iterator_traits.h | 43 ++++++---------------
 1 file changed, 11 insertions(+), 32 deletions(-)

diff --git a/libcxx/include/__iterator/iterator_traits.h b/libcxx/include/__iterator/iterator_traits.h
index db68dd2c377ace..a28162b63f493e 100644
--- a/libcxx/include/__iterator/iterator_traits.h
+++ b/libcxx/include/__iterator/iterator_traits.h
@@ -24,6 +24,7 @@
 #include <__iterator/readable_traits.h>
 #include <__type_traits/common_reference.h>
 #include <__type_traits/conditional.h>
+#include <__type_traits/detected_or.h>
 #include <__type_traits/disjunction.h>
 #include <__type_traits/enable_if.h>
 #include <__type_traits/integral_constant.h>
@@ -32,6 +33,7 @@
 #include <__type_traits/is_primary_template.h>
 #include <__type_traits/is_reference.h>
 #include <__type_traits/is_valid_expansion.h>
+#include <__type_traits/nat.h>
 #include <__type_traits/remove_const.h>
 #include <__type_traits/remove_cv.h>
 #include <__type_traits/remove_cvref.h>
@@ -126,30 +128,6 @@ struct __has_iterator_typedefs {
   static const bool value = decltype(__test<_Tp>(nullptr, nullptr, nullptr, nullptr, nullptr))::value;
 };
 
-template <class _Tp>
-struct __has_iterator_category {
-private:
-  template <class _Up>
-  static false_type __test(...);
-  template <class _Up>
-  static true_type __test(typename _Up::iterator_category* = nullptr);
-
-public:
-  static const bool value = decltype(__test<_Tp>(nullptr))::value;
-};
-
-template <class _Tp>
-struct __has_iterator_concept {
-private:
-  template <class _Up>
-  static false_type __test(...);
-  template <class _Up>
-  static true_type __test(typename _Up::iterator_concept* = nullptr);
-
-public:
-  static const bool value = decltype(__test<_Tp>(nullptr))::value;
-};
-
 #if _LIBCPP_STD_VER >= 20
 
 // The `cpp17-*-iterator` exposition-only concepts have very similar names to the `Cpp17*Iterator` named requirements
@@ -417,18 +395,19 @@ struct _LIBCPP_TEMPLATE_VIS iterator_traits<_Tp*> {
 #endif
 };
 
-template <class _Tp, class _Up, bool = __has_iterator_category<iterator_traits<_Tp> >::value>
-struct __has_iterator_category_convertible_to : is_convertible<typename iterator_traits<_Tp>::iterator_category, _Up> {
-};
+template <class _Tp>
+using __iterator_category _LIBCPP_NODEBUG = _Tp::iterator_category;
 
-template <class _Tp, class _Up>
-struct __has_iterator_category_convertible_to<_Tp, _Up, false> : false_type {};
+template <class _Tp>
+using __iterator_concept _LIBCPP_NODEBUG = _Tp::iterator_concept;
 
-template <class _Tp, class _Up, bool = __has_iterator_concept<_Tp>::value>
-struct __has_iterator_concept_convertible_to : is_convertible<typename _Tp::iterator_concept, _Up> {};
+template <class _Tp, class _Up>
+using __has_iterator_category_convertible_to _LIBCPP_NODEBUG =
+    is_convertible<__detected_or_t<__nat, __iterator_category, iterator_traits<_Tp> >, _Up>;
 
 template <class _Tp, class _Up>
-struct __has_iterator_concept_convertible_to<_Tp, _Up, false> : false_type {};
+using __has_iterator_concept_convertible_to _LIBCPP_NODEBUG =
+    is_convertible<__detected_or_t<__nat, __iterator_concept, _Tp>, _Up>;
 
 template <class _Tp>
 using __has_input_iterator_category _LIBCPP_NODEBUG = __has_iterator_category_convertible_to<_Tp, input_iterator_tag>;



More information about the libcxx-commits mailing list