Skip to content

Commit f676cca

Browse files
committed
[libc++] Use __detected_or_t to implement __has_iterator_{category,concept}_convertible_to
1 parent 4562efc commit f676cca

File tree

1 file changed

+11
-32
lines changed

1 file changed

+11
-32
lines changed

libcxx/include/__iterator/iterator_traits.h

Lines changed: 11 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#include <__iterator/readable_traits.h>
2525
#include <__type_traits/common_reference.h>
2626
#include <__type_traits/conditional.h>
27+
#include <__type_traits/detected_or.h>
2728
#include <__type_traits/disjunction.h>
2829
#include <__type_traits/enable_if.h>
2930
#include <__type_traits/integral_constant.h>
@@ -32,6 +33,7 @@
3233
#include <__type_traits/is_primary_template.h>
3334
#include <__type_traits/is_reference.h>
3435
#include <__type_traits/is_valid_expansion.h>
36+
#include <__type_traits/nat.h>
3537
#include <__type_traits/remove_const.h>
3638
#include <__type_traits/remove_cv.h>
3739
#include <__type_traits/remove_cvref.h>
@@ -126,30 +128,6 @@ struct __has_iterator_typedefs {
126128
static const bool value = decltype(__test<_Tp>(nullptr, nullptr, nullptr, nullptr, nullptr))::value;
127129
};
128130

129-
template <class _Tp>
130-
struct __has_iterator_category {
131-
private:
132-
template <class _Up>
133-
static false_type __test(...);
134-
template <class _Up>
135-
static true_type __test(typename _Up::iterator_category* = nullptr);
136-
137-
public:
138-
static const bool value = decltype(__test<_Tp>(nullptr))::value;
139-
};
140-
141-
template <class _Tp>
142-
struct __has_iterator_concept {
143-
private:
144-
template <class _Up>
145-
static false_type __test(...);
146-
template <class _Up>
147-
static true_type __test(typename _Up::iterator_concept* = nullptr);
148-
149-
public:
150-
static const bool value = decltype(__test<_Tp>(nullptr))::value;
151-
};
152-
153131
#if _LIBCPP_STD_VER >= 20
154132

155133
// 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*> {
417395
#endif
418396
};
419397

420-
template <class _Tp, class _Up, bool = __has_iterator_category<iterator_traits<_Tp> >::value>
421-
struct __has_iterator_category_convertible_to : is_convertible<typename iterator_traits<_Tp>::iterator_category, _Up> {
422-
};
398+
template <class _Tp>
399+
using __iterator_category _LIBCPP_NODEBUG = typename iterator_traits<_Tp>::iterator_category;
423400

424-
template <class _Tp, class _Up>
425-
struct __has_iterator_category_convertible_to<_Tp, _Up, false> : false_type {};
401+
template <class _Tp>
402+
using __iterator_concept _LIBCPP_NODEBUG = typename iterator_traits<_Tp>::iterator_concept;
426403

427-
template <class _Tp, class _Up, bool = __has_iterator_concept<_Tp>::value>
428-
struct __has_iterator_concept_convertible_to : is_convertible<typename _Tp::iterator_concept, _Up> {};
404+
template <class _Tp, class _Up>
405+
using __has_iterator_category_convertible_to _LIBCPP_NODEBUG =
406+
is_convertible<__detected_or_t<__nat, __iterator_category, _Tp>, _Up>;
429407

430408
template <class _Tp, class _Up>
431-
struct __has_iterator_concept_convertible_to<_Tp, _Up, false> : false_type {};
409+
using __has_iterator_concept_convertible_to _LIBCPP_NODEBUG =
410+
is_convertible<__detected_or_t<__nat, __iterator_concept, _Tp>, _Up>;
432411

433412
template <class _Tp>
434413
using __has_input_iterator_category _LIBCPP_NODEBUG = __has_iterator_category_convertible_to<_Tp, input_iterator_tag>;

0 commit comments

Comments
 (0)