Skip to content

Commit 3b2b918

Browse files
authored
[libc++] Use __detected_or_t to implement __has_iterator_{category,concept}_convertible_to (#124456)
This simplifies the implementation a bit.
1 parent e2202b9 commit 3b2b918

File tree

2 files changed

+16
-33
lines changed

2 files changed

+16
-33
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>
@@ -128,30 +130,6 @@ struct __has_iterator_typedefs {
128130
static const bool value = decltype(__test<_Tp>(nullptr, nullptr, nullptr, nullptr, nullptr))::value;
129131
};
130132

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

157135
// The `cpp17-*-iterator` exposition-only concepts have very similar names to the `Cpp17*Iterator` named requirements
@@ -419,18 +397,19 @@ struct _LIBCPP_TEMPLATE_VIS iterator_traits<_Tp*> {
419397
#endif
420398
};
421399

422-
template <class _Tp, class _Up, bool = __has_iterator_category<iterator_traits<_Tp> >::value>
423-
struct __has_iterator_category_convertible_to : is_convertible<typename iterator_traits<_Tp>::iterator_category, _Up> {
424-
};
400+
template <class _Tp>
401+
using __iterator_category _LIBCPP_NODEBUG = typename _Tp::iterator_category;
425402

426-
template <class _Tp, class _Up>
427-
struct __has_iterator_category_convertible_to<_Tp, _Up, false> : false_type {};
403+
template <class _Tp>
404+
using __iterator_concept _LIBCPP_NODEBUG = typename _Tp::iterator_concept;
428405

429-
template <class _Tp, class _Up, bool = __has_iterator_concept<_Tp>::value>
430-
struct __has_iterator_concept_convertible_to : is_convertible<typename _Tp::iterator_concept, _Up> {};
406+
template <class _Tp, class _Up>
407+
using __has_iterator_category_convertible_to _LIBCPP_NODEBUG =
408+
is_convertible<__detected_or_t<__nat, __iterator_category, iterator_traits<_Tp> >, _Up>;
431409

432410
template <class _Tp, class _Up>
433-
struct __has_iterator_concept_convertible_to<_Tp, _Up, false> : false_type {};
411+
using __has_iterator_concept_convertible_to _LIBCPP_NODEBUG =
412+
is_convertible<__detected_or_t<__nat, __iterator_concept, _Tp>, _Up>;
434413

435414
template <class _Tp>
436415
using __has_input_iterator_category _LIBCPP_NODEBUG = __has_iterator_category_convertible_to<_Tp, input_iterator_tag>;

libcxx/include/module.modulemap

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -418,7 +418,10 @@ module std [system] {
418418
module copy_backward { header "__algorithm/copy_backward.h" }
419419
module copy_if { header "__algorithm/copy_if.h" }
420420
module copy_move_common { header "__algorithm/copy_move_common.h" }
421-
module copy_n { header "__algorithm/copy_n.h" }
421+
module copy_n {
422+
header "__algorithm/copy_n.h"
423+
export std.iterator_traits
424+
}
422425
module copy { header "__algorithm/copy.h" }
423426
module count_if { header "__algorithm/count_if.h" }
424427
module count { header "__algorithm/count.h" }
@@ -1499,6 +1502,7 @@ module std [system] {
14991502
module iterator_traits {
15001503
header "__iterator/iterator_traits.h"
15011504
export std_core.type_traits.integral_constant
1505+
export std_core.type_traits.is_convertible
15021506
}
15031507
module iterator_with_data { header "__iterator/iterator_with_data.h" }
15041508
module iterator { header "__iterator/iterator.h" }

0 commit comments

Comments
 (0)