1010#define _LIBCPP___ALGORITHM_FILL_H
1111
1212#include < __algorithm/fill_n.h>
13+ #include < __algorithm/for_each_segment.h>
1314#include < __config>
1415#include < __iterator/iterator_traits.h>
16+ #include < __iterator/segmented_iterator.h>
17+ #include < __type_traits/enable_if.h>
1518
1619#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
1720# pragma GCC system_header
@@ -21,23 +24,52 @@ _LIBCPP_BEGIN_NAMESPACE_STD
2124
2225// fill isn't specialized for std::memset, because the compiler already optimizes the loop to a call to std::memset.
2326
24- template <class _ForwardIterator , class _Tp >
27+ template <class _ForwardIterator ,
28+ class _Sentinel ,
29+ class _Tp ,
30+ __enable_if_t <__has_forward_iterator_category<_ForwardIterator>::value, int > = 0 >
2531inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void
26- __fill (_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value, forward_iterator_tag ) {
32+ __fill (_ForwardIterator __first, _Sentinel __last, const _Tp& __value) {
2733 for (; __first != __last; ++__first)
2834 *__first = __value;
2935}
3036
31- template <class _RandomAccessIterator , class _Tp >
37+ template <class _OutIter , class _Tp >
38+ struct _FillSegment {
39+ using _Traits _LIBCPP_NODEBUG = __segmented_iterator_traits<_OutIter>;
40+
41+ const _Tp& __value_;
42+
43+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 explicit _FillSegment (const _Tp& __value) : __value_(__value) {}
44+
45+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 void
46+ operator ()(typename _Traits::__local_iterator __lfirst, typename _Traits::__local_iterator __llast) {
47+ std::__fill (__lfirst, __llast, __value_);
48+ }
49+ };
50+
51+ template <class _RandomAccessIterator ,
52+ class _Tp ,
53+ __enable_if_t <__has_random_access_iterator_category<_RandomAccessIterator>::value &&
54+ !__is_segmented_iterator<_RandomAccessIterator>::value,
55+ int > = 0 >
3256inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void
33- __fill (_RandomAccessIterator __first, _RandomAccessIterator __last, const _Tp& __value, random_access_iterator_tag ) {
57+ __fill (_RandomAccessIterator __first, _RandomAccessIterator __last, const _Tp& __value) {
3458 std::fill_n (__first, __last - __first, __value);
3559}
3660
61+ template <class _SegmentedIterator ,
62+ class _Tp ,
63+ __enable_if_t <__is_segmented_iterator<_SegmentedIterator>::value, int > = 0 >
64+ inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void
65+ __fill (_SegmentedIterator __first, _SegmentedIterator __last, const _Tp& __value) {
66+ std::__for_each_segment (__first, __last, _FillSegment<_SegmentedIterator, _Tp>(__value));
67+ }
68+
3769template <class _ForwardIterator , class _Tp >
3870inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void
3971fill (_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) {
40- std::__fill (__first, __last, __value, typename iterator_traits<_ForwardIterator>:: iterator_category () );
72+ std::__fill (__first, __last, __value);
4173}
4274
4375_LIBCPP_END_NAMESPACE_STD
0 commit comments