1010#define _LIBCPP___ALGORITHM_FILL_N_H
1111
1212#include < __algorithm/for_each_n_segment.h>
13- #include < __algorithm/min .h>
13+ #include < __algorithm/specialized_algorithms .h>
1414#include < __config>
15- #include < __fwd/bit_reference.h>
1615#include < __iterator/iterator_traits.h>
1716#include < __iterator/segmented_iterator.h>
18- #include < __memory/pointer_traits .h>
17+ #include < __type_traits/enable_if .h>
1918#include < __utility/convert_to_integral.h>
19+ #include < __utility/move.h>
2020
2121#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
2222# pragma GCC system_header
@@ -29,7 +29,12 @@ _LIBCPP_BEGIN_NAMESPACE_STD
2929
3030// fill_n isn't specialized for std::memset, because the compiler already optimizes the loop to a call to std::memset.
3131
32- template <class _OutputIterator , class _Size , class _Tp >
32+ template <
33+ class _OutputIterator ,
34+ class _Size ,
35+ class _Tp ,
36+ __enable_if_t <!__specialized_algorithm<_Algorithm::__fill_n, __single_iterator<_OutputIterator> >::__has_algorithm,
37+ int > = 0 >
3338inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator
3439__fill_n (_OutputIterator __first, _Size __n, const _Tp& __value) {
3540#ifndef _LIBCPP_CXX03_LANG
@@ -47,42 +52,14 @@ __fill_n(_OutputIterator __first, _Size __n, const _Tp& __value) {
4752 return __first;
4853}
4954
50- template <bool _FillVal, class _Cp >
51- _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void
52- __fill_n_bool (__bit_iterator<_Cp, false > __first, typename __size_difference_type_traits<_Cp>::size_type __n) {
53- using _It = __bit_iterator<_Cp, false >;
54- using __storage_type = typename _It::__storage_type;
55-
56- const int __bits_per_word = _It::__bits_per_word;
57- // do first partial word
58- if (__first.__ctz_ != 0 ) {
59- __storage_type __clz_f = static_cast <__storage_type>(__bits_per_word - __first.__ctz_ );
60- __storage_type __dn = std::min (__clz_f, __n);
61- std::__fill_masked_range (std::__to_address (__first.__seg_ ), __clz_f - __dn, __first.__ctz_ , _FillVal);
62- __n -= __dn;
63- ++__first.__seg_ ;
64- }
65- // do middle whole words
66- __storage_type __nw = __n / __bits_per_word;
67- std::__fill_n (std::__to_address (__first.__seg_ ), __nw, _FillVal ? static_cast <__storage_type>(-1 ) : 0 );
68- __n -= __nw * __bits_per_word;
69- // do last partial word
70- if (__n > 0 ) {
71- __first.__seg_ += __nw;
72- std::__fill_masked_range (std::__to_address (__first.__seg_ ), __bits_per_word - __n, 0u , _FillVal);
73- }
74- }
75-
76- template <class _Cp , class _Size >
77- inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __bit_iterator<_Cp, false >
78- __fill_n (__bit_iterator<_Cp, false > __first, _Size __n, const bool & __value) {
79- if (__n > 0 ) {
80- if (__value)
81- std::__fill_n_bool<true >(__first, __n);
82- else
83- std::__fill_n_bool<false >(__first, __n);
84- }
85- return __first + __n;
55+ template <class _OutIter ,
56+ class _Size ,
57+ class _Tp ,
58+ __enable_if_t <__specialized_algorithm<_Algorithm::__fill_n, __single_iterator<_OutIter> >::__has_algorithm,
59+ int > = 0 >
60+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutIter __fill_n (_OutIter __first, _Size __n, const _Tp& __value) {
61+ return __specialized_algorithm<_Algorithm::__fill_n, __single_iterator<_OutIter> >()(
62+ std::move (__first), __n, __value);
8663}
8764
8865template <class _OutputIterator , class _Size , class _Tp >
0 commit comments