Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 10 additions & 12 deletions libcxx/include/__algorithm/fill.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include <__iterator/iterator_traits.h>
#include <__iterator/segmented_iterator.h>
#include <__type_traits/enable_if.h>
#include <__type_traits/is_same.h>

#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
Expand All @@ -27,6 +28,15 @@ _LIBCPP_BEGIN_NAMESPACE_STD
template <class _ForwardIterator, class _Sentinel, class _Tp>
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator
__fill(_ForwardIterator __first, _Sentinel __last, const _Tp& __value) {
#ifndef _LIBCPP_CXX03_LANG
if constexpr (is_same<_ForwardIterator, _Sentinel>::value && __is_segmented_iterator_v<_ForwardIterator>) {
using __local_iterator_t = typename __segmented_iterator_traits<_ForwardIterator>::__local_iterator;
std::__for_each_segment(__first, __last, [&](__local_iterator_t __lfirst, __local_iterator_t __llast) {
std::__fill(__lfirst, __llast, __value);
});
return __last;
}
#endif
for (; __first != __last; ++__first)
*__first = __value;
return __first;
Expand All @@ -42,18 +52,6 @@ __fill(_RandomAccessIterator __first, _RandomAccessIterator __last, const _Tp& _
return std::__fill_n(__first, __last - __first, __value);
}

#ifndef _LIBCPP_CXX03_LANG
template <class _SegmentedIterator, class _Tp, __enable_if_t<__is_segmented_iterator_v<_SegmentedIterator>, int> = 0>
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
_SegmentedIterator __fill(_SegmentedIterator __first, _SegmentedIterator __last, const _Tp& __value) {
using __local_iterator_t = typename __segmented_iterator_traits<_SegmentedIterator>::__local_iterator;
std::__for_each_segment(__first, __last, [&](__local_iterator_t __lfirst, __local_iterator_t __llast) {
std::__fill(__lfirst, __llast, __value);
});
return __last;
}
#endif // !_LIBCPP_CXX03_LANG

template <class _ForwardIterator, class _Tp>
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void
fill(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) {
Expand Down
41 changes: 11 additions & 30 deletions libcxx/include/__algorithm/fill_n.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,6 @@
#include <__iterator/iterator_traits.h>
#include <__iterator/segmented_iterator.h>
#include <__memory/pointer_traits.h>
#include <__type_traits/conjunction.h>
#include <__type_traits/enable_if.h>
#include <__type_traits/integral_constant.h>
#include <__type_traits/negation.h>
#include <__utility/convert_to_integral.h>

#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
Expand All @@ -33,39 +29,24 @@ _LIBCPP_BEGIN_NAMESPACE_STD

// fill_n isn't specialized for std::memset, because the compiler already optimizes the loop to a call to std::memset.

template <class _OutputIterator,
class _Size,
class _Tp
#ifndef _LIBCPP_CXX03_LANG
,
__enable_if_t<!_And<_BoolConstant<__is_segmented_iterator_v<_OutputIterator>>,
__has_random_access_local_iterator<_OutputIterator>>::value,
int> = 0
#endif
>
template <class _OutputIterator, class _Size, class _Tp>
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator
__fill_n(_OutputIterator __first, _Size __n, const _Tp& __value) {
#ifndef _LIBCPP_CXX03_LANG
if constexpr (__is_segmented_iterator_v<_OutputIterator>) {
using __local_iterator = typename __segmented_iterator_traits<_OutputIterator>::__local_iterator;
if constexpr (__has_random_access_iterator_category<__local_iterator>::value) {
return std::__for_each_n_segment(__first, __n, [&](__local_iterator __lfirst, __local_iterator __llast) {
std::__fill_n(__lfirst, __llast - __lfirst, __value);
});
}
}
#endif
for (; __n > 0; ++__first, (void)--__n)
*__first = __value;
return __first;
}

#ifndef _LIBCPP_CXX03_LANG
template < class _OutputIterator,
class _Size,
class _Tp,
__enable_if_t<_And<_BoolConstant<__is_segmented_iterator_v<_OutputIterator>>,
__has_random_access_local_iterator<_OutputIterator>>::value,
int> = 0>
inline _LIBCPP_HIDE_FROM_ABI
_LIBCPP_CONSTEXPR_SINCE_CXX14 _OutputIterator __fill_n(_OutputIterator __first, _Size __n, const _Tp& __value) {
using __local_iterator_t = typename __segmented_iterator_traits<_OutputIterator>::__local_iterator;
return std::__for_each_n_segment(__first, __n, [&](__local_iterator_t __lfirst, __local_iterator_t __llast) {
std::__fill_n(__lfirst, __llast - __lfirst, __value);
});
}
#endif // !_LIBCPP_CXX03_LANG

template <bool _FillVal, class _Cp>
_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void
__fill_n_bool(__bit_iterator<_Cp, false> __first, typename __size_difference_type_traits<_Cp>::size_type __n) {
Expand Down
30 changes: 12 additions & 18 deletions libcxx/include/__algorithm/for_each.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@
#include <__config>
#include <__functional/identity.h>
#include <__iterator/segmented_iterator.h>
#include <__type_traits/enable_if.h>
#include <__type_traits/invoke.h>
#include <__type_traits/is_same.h>

#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
Expand All @@ -25,27 +25,21 @@ _LIBCPP_BEGIN_NAMESPACE_STD

template <class _InputIterator, class _Sent, class _Func, class _Proj>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _InputIterator
__for_each(_InputIterator __first, _Sent __last, _Func& __f, _Proj& __proj) {
__for_each(_InputIterator __first, _Sent __last, _Func& __func, _Proj& __proj) {
#ifndef _LIBCPP_CXX03_LANG
if constexpr (is_same<_InputIterator, _Sent>::value && __is_segmented_iterator_v<_InputIterator>) {
using __local_iterator_t = typename __segmented_iterator_traits<_InputIterator>::__local_iterator;
std::__for_each_segment(__first, __last, [&](__local_iterator_t __lfirst, __local_iterator_t __llast) {
std::__for_each(__lfirst, __llast, __func, __proj);
});
return __last;
}
#endif
for (; __first != __last; ++__first)
std::__invoke(__f, std::__invoke(__proj, *__first));
std::__invoke(__func, std::__invoke(__proj, *__first));
return __first;
}

#ifndef _LIBCPP_CXX03_LANG
template <class _SegmentedIterator,
class _Func,
class _Proj,
__enable_if_t<__is_segmented_iterator_v<_SegmentedIterator>, int> = 0>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _SegmentedIterator
__for_each(_SegmentedIterator __first, _SegmentedIterator __last, _Func& __func, _Proj& __proj) {
using __local_iterator_t = typename __segmented_iterator_traits<_SegmentedIterator>::__local_iterator;
std::__for_each_segment(__first, __last, [&](__local_iterator_t __lfirst, __local_iterator_t __llast) {
std::__for_each(__lfirst, __llast, __func, __proj);
});
return __last;
}
#endif // !_LIBCPP_CXX03_LANG

template <class _InputIterator, class _Func>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _Func
for_each(_InputIterator __first, _InputIterator __last, _Func __f) {
Expand Down
67 changes: 20 additions & 47 deletions libcxx/include/__algorithm/for_each_n.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,7 @@
#include <__functional/identity.h>
#include <__iterator/iterator_traits.h>
#include <__iterator/segmented_iterator.h>
#include <__type_traits/disjunction.h>
#include <__type_traits/enable_if.h>
#include <__type_traits/invoke.h>
#include <__type_traits/negation.h>
#include <__utility/convert_to_integral.h>
#include <__utility/move.h>

Expand All @@ -32,57 +29,33 @@ _LIBCPP_PUSH_MACROS

_LIBCPP_BEGIN_NAMESPACE_STD

template <class _InputIterator,
class _Size,
class _Func,
class _Proj,
__enable_if_t<!__has_random_access_iterator_category<_InputIterator>::value &&
_Or<integral_constant<bool, !__is_segmented_iterator_v<_InputIterator> >,
_Not<__has_random_access_local_iterator<_InputIterator> > >::value,
int> = 0>
template <class _InputIterator, class _Size, class _Func, class _Proj>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _InputIterator
__for_each_n(_InputIterator __first, _Size __orig_n, _Func& __f, _Proj& __proj) {
typedef decltype(std::__convert_to_integral(__orig_n)) _IntegralSize;
_IntegralSize __n = __orig_n;
while (__n > 0) {
std::__invoke(__f, std::__invoke(__proj, *__first));
++__first;
--__n;
}
return std::move(__first);
}

template <class _RandIter,
class _Size,
class _Func,
class _Proj,
__enable_if_t<__has_random_access_iterator_category<_RandIter>::value, int> = 0>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _RandIter
__for_each_n(_RandIter __first, _Size __orig_n, _Func& __f, _Proj& __proj) {
typename std::iterator_traits<_RandIter>::difference_type __n = __orig_n;
auto __last = __first + __n;
std::__for_each(__first, __last, __f, __proj);
return __last;
}

#ifndef _LIBCPP_CXX03_LANG
template <class _SegmentedIterator,
class _Size,
class _Func,
class _Proj,
__enable_if_t<!__has_random_access_iterator_category<_SegmentedIterator>::value &&
__is_segmented_iterator_v<_SegmentedIterator> &&
__has_random_access_iterator_category<
typename __segmented_iterator_traits<_SegmentedIterator>::__local_iterator>::value,
int> = 0>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _SegmentedIterator
__for_each_n(_SegmentedIterator __first, _Size __orig_n, _Func& __f, _Proj& __proj) {
using __local_iterator_t = typename __segmented_iterator_traits<_SegmentedIterator>::__local_iterator;
return std::__for_each_n_segment(__first, __orig_n, [&](__local_iterator_t __lfirst, __local_iterator_t __llast) {
std::__for_each(__lfirst, __llast, __f, __proj);
});
if constexpr (__is_segmented_iterator_v<_InputIterator>) {
using __local_iterator = typename __segmented_iterator_traits<_InputIterator>::__local_iterator;
if constexpr (__has_random_access_iterator_category<__local_iterator>::value) {
return std::__for_each_n_segment(__first, __orig_n, [&](__local_iterator __lfirst, __local_iterator __llast) {
std::__for_each(__lfirst, __llast, __f, __proj);
});
} else {
return std::__for_each(__first, __first + __n, __f, __proj);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Previously, we were explicitly converting to std::iterator_traits<_RandIter>::difference_type before doing __first + __n. There's gotta be a reason?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it was to convert to an integral type, but we already do that above.

}
} else
#endif
{
while (__n > 0) {
std::__invoke(__f, std::__invoke(__proj, *__first));
++__first;
--__n;
}
return std::move(__first);
}
}
#endif // !_LIBCPP_CXX03_LANG

#if _LIBCPP_STD_VER >= 17

Expand Down
35 changes: 15 additions & 20 deletions libcxx/include/__iterator/distance.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#define _LIBCPP___ITERATOR_DISTANCE_H

#include <__algorithm/for_each_segment.h>
#include <__concepts/same_as.h>
#include <__config>
#include <__iterator/concepts.h>
#include <__iterator/incrementable_traits.h>
Expand Down Expand Up @@ -41,35 +42,29 @@ 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, __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;
}

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);
#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);
});
if constexpr (same_as<_InputIter, _Sent> && __is_segmented_iterator_v<_InputIter>) {
std::__for_each_segment(__first, __last, [&__r](auto __lfirst, auto __llast) {
__r += std::__distance(__lfirst, __llast);
});
} else
#endif
{
for (; __first != __last; ++__first)
++__r;
}
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
Expand Down
5 changes: 0 additions & 5 deletions libcxx/include/__iterator/segmented_iterator.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,11 +75,6 @@ inline const bool __has_specialization_v<_Tp, sizeof(_Tp) * 0> = true;
template <class _Iterator>
inline const bool __is_segmented_iterator_v = __has_specialization_v<__segmented_iterator_traits<_Iterator> >;

template <class _SegmentedIterator>
struct __has_random_access_local_iterator
: __has_random_access_iterator_category<
typename __segmented_iterator_traits< _SegmentedIterator >::__local_iterator > {};

_LIBCPP_END_NAMESPACE_STD

#endif // _LIBCPP___SEGMENTED_ITERATOR_H
Loading