10
10
#ifndef _LIBCPP___ITERATOR_DISTANCE_H
11
11
#define _LIBCPP___ITERATOR_DISTANCE_H
12
12
13
+ #include < __algorithm/for_each_segment.h>
13
14
#include < __config>
14
15
#include < __iterator/concepts.h>
15
16
#include < __iterator/incrementable_traits.h>
16
17
#include < __iterator/iterator_traits.h>
18
+ #include < __iterator/segmented_iterator.h>
17
19
#include < __ranges/access.h>
18
20
#include < __ranges/concepts.h>
19
21
#include < __ranges/size.h>
20
22
#include < __type_traits/decay.h>
23
+ #include < __type_traits/enable_if.h>
21
24
#include < __type_traits/remove_cvref.h>
25
+ #include < __utility/move.h>
22
26
23
27
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
24
28
# pragma GCC system_header
25
29
#endif
26
30
31
+ _LIBCPP_PUSH_MACROS
32
+ #include < __undef_macros>
33
+
27
34
_LIBCPP_BEGIN_NAMESPACE_STD
28
35
29
- template <class _InputIter >
30
- inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 typename iterator_traits<_InputIter>::difference_type
31
- __distance (_InputIter __first, _InputIter __last, input_iterator_tag) {
32
- typename iterator_traits<_InputIter>::difference_type __r (0 );
36
+ #if _LIBCPP_STD_VER >= 20
37
+ template <class _Iter >
38
+ using __iter_distance_t _LIBCPP_NODEBUG = std::iter_difference_t <_Iter>;
39
+ #else
40
+ template <class _Iter >
41
+ using __iter_distance_t _LIBCPP_NODEBUG = typename iterator_traits<_Iter>::difference_type;
42
+ #endif
43
+
44
+ template <class _InputIter , class _Sent >
45
+ inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 __iter_distance_t <_InputIter>
46
+ __distance (_InputIter __first, _Sent __last) {
47
+ __iter_distance_t <_InputIter> __r (0 );
33
48
for (; __first != __last; ++__first)
34
49
++__r;
35
50
return __r;
36
51
}
37
52
38
- template <class _RandIter >
39
- inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 typename iterator_traits <_RandIter>::difference_type
40
- __distance (_RandIter __first, _RandIter __last, random_access_iterator_tag ) {
53
+ template <class _RandIter , __enable_if_t <__has_random_access_iterator_category<_RandIter>::value, int > = 0 >
54
+ inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 __iter_distance_t <_RandIter>
55
+ __distance (_RandIter __first, _RandIter __last) {
41
56
return __last - __first;
42
57
}
43
58
59
+ template <class _SegmentedIter ,
60
+ __enable_if_t <!__has_random_access_iterator_category<_SegmentedIter>::value &&
61
+ __is_segmented_iterator<_SegmentedIter>::value,
62
+ int > = 0 >
63
+ inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 __iter_distance_t <_SegmentedIter>
64
+ __distance (_SegmentedIter __first, _SegmentedIter __last) {
65
+ __iter_distance_t <_SegmentedIter> __r (0 );
66
+ using __local_iterator = typename __segmented_iterator_traits<_SegmentedIter>::__local_iterator;
67
+ std::__for_each_segment (__first, __last, [&__r](__local_iterator __lfirst, __local_iterator __llast) {
68
+ __r += std::__distance (__lfirst, __llast);
69
+ });
70
+ return __r;
71
+ }
72
+
44
73
template <class _InputIter >
45
- inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 typename iterator_traits <_InputIter>::difference_type
74
+ inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 __iter_distance_t <_InputIter>
46
75
distance (_InputIter __first, _InputIter __last) {
47
- return std::__distance (__first, __last, typename iterator_traits<_InputIter>:: iterator_category () );
76
+ return std::__distance (__first, __last);
48
77
}
49
78
50
79
#if _LIBCPP_STD_VER >= 20
@@ -56,12 +85,7 @@ struct __distance {
56
85
template <class _Ip , sentinel_for<_Ip> _Sp>
57
86
requires (!sized_sentinel_for<_Sp, _Ip>)
58
87
_LIBCPP_HIDE_FROM_ABI constexpr iter_difference_t <_Ip> operator ()(_Ip __first, _Sp __last) const {
59
- iter_difference_t <_Ip> __n = 0 ;
60
- while (__first != __last) {
61
- ++__first;
62
- ++__n;
63
- }
64
- return __n;
88
+ return std::__distance (std::move (__first), std::move (__last));
65
89
}
66
90
67
91
template <class _Ip , sized_sentinel_for<decay_t <_Ip>> _Sp>
@@ -92,4 +116,6 @@ inline constexpr auto distance = __distance{};
92
116
93
117
_LIBCPP_END_NAMESPACE_STD
94
118
119
+ _LIBCPP_POP_MACROS
120
+
95
121
#endif // _LIBCPP___ITERATOR_DISTANCE_H
0 commit comments