diff options
Diffstat (limited to 'libcxx/include/__iterator/distance.h')
-rw-r--r-- | libcxx/include/__iterator/distance.h | 55 |
1 files changed, 41 insertions, 14 deletions
diff --git a/libcxx/include/__iterator/distance.h b/libcxx/include/__iterator/distance.h index 1732aa5..9be9db0 100644 --- a/libcxx/include/__iterator/distance.h +++ b/libcxx/include/__iterator/distance.h @@ -10,41 +10,71 @@ #ifndef _LIBCPP___ITERATOR_DISTANCE_H #define _LIBCPP___ITERATOR_DISTANCE_H +#include <__algorithm/for_each_segment.h> #include <__config> #include <__iterator/concepts.h> #include <__iterator/incrementable_traits.h> #include <__iterator/iterator_traits.h> +#include <__iterator/segmented_iterator.h> #include <__ranges/access.h> #include <__ranges/concepts.h> #include <__ranges/size.h> #include <__type_traits/decay.h> +#include <__type_traits/enable_if.h> #include <__type_traits/remove_cvref.h> +#include <__utility/move.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) # pragma GCC system_header #endif +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + _LIBCPP_BEGIN_NAMESPACE_STD -template <class _InputIter> -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 typename iterator_traits<_InputIter>::difference_type -__distance(_InputIter __first, _InputIter __last, input_iterator_tag) { - typename iterator_traits<_InputIter>::difference_type __r(0); +#if _LIBCPP_STD_VER >= 20 +template <class _Iter> +using __iter_distance_t _LIBCPP_NODEBUG = std::iter_difference_t<_Iter>; +#else +template <class _Iter> +using __iter_distance_t _LIBCPP_NODEBUG = typename iterator_traits<_Iter>::difference_type; +#endif + +template <class _InputIter, class _Sent> +inline _LIBCPP_HIDE_FROM_ABI +_LIBCPP_CONSTEXPR_SINCE_CXX17 __iter_distance_t<_InputIter> __distance(_InputIter __first, _Sent __last) { + __iter_distance_t<_InputIter> __r(0); for (; __first != __last; ++__first) ++__r; return __r; } -template <class _RandIter> -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 typename iterator_traits<_RandIter>::difference_type -__distance(_RandIter __first, _RandIter __last, random_access_iterator_tag) { +template <class _RandIter, __enable_if_t<__has_random_access_iterator_category<_RandIter>::value, int> = 0> +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 __iter_distance_t<_RandIter> +__distance(_RandIter __first, _RandIter __last) { return __last - __first; } +#if _LIBCPP_STD_VER >= 20 +template <class _SegmentedIter, + __enable_if_t<!__has_random_access_iterator_category<_SegmentedIter>::value && + __is_segmented_iterator_v<_SegmentedIter>, + int> = 0> +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 __iter_distance_t<_SegmentedIter> +__distance(_SegmentedIter __first, _SegmentedIter __last) { + __iter_distance_t<_SegmentedIter> __r(0); + std::__for_each_segment(__first, __last, [&__r](auto __lfirst, auto __llast) { + __r += std::__distance(__lfirst, __llast); + }); + return __r; +} +#endif // _LIBCPP_STD_VER >= 20 + template <class _InputIter> inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 typename iterator_traits<_InputIter>::difference_type distance(_InputIter __first, _InputIter __last) { - return std::__distance(__first, __last, typename iterator_traits<_InputIter>::iterator_category()); + return std::__distance(__first, __last); } #if _LIBCPP_STD_VER >= 20 @@ -56,12 +86,7 @@ struct __distance { template <class _Ip, sentinel_for<_Ip> _Sp> requires(!sized_sentinel_for<_Sp, _Ip>) _LIBCPP_HIDE_FROM_ABI constexpr iter_difference_t<_Ip> operator()(_Ip __first, _Sp __last) const { - iter_difference_t<_Ip> __n = 0; - while (__first != __last) { - ++__first; - ++__n; - } - return __n; + return std::__distance(std::move(__first), std::move(__last)); } template <class _Ip, sized_sentinel_for<decay_t<_Ip>> _Sp> @@ -92,4 +117,6 @@ inline constexpr auto distance = __distance{}; _LIBCPP_END_NAMESPACE_STD +_LIBCPP_POP_MACROS + #endif // _LIBCPP___ITERATOR_DISTANCE_H |