1e78f53d1SNikolas Klauser //===----------------------------------------------------------------------===// 2e78f53d1SNikolas Klauser // 3e78f53d1SNikolas Klauser // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4e78f53d1SNikolas Klauser // See https://llvm.org/LICENSE.txt for license information. 5e78f53d1SNikolas Klauser // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6e78f53d1SNikolas Klauser // 7e78f53d1SNikolas Klauser //===----------------------------------------------------------------------===// 8e78f53d1SNikolas Klauser 9*ce777190SNikolas Klauser #ifndef _LIBCPP___CXX03___ALGORITHM_FILL_N_H 10*ce777190SNikolas Klauser #define _LIBCPP___CXX03___ALGORITHM_FILL_N_H 11e78f53d1SNikolas Klauser 1273fbae83SNikolas Klauser #include <__cxx03/__algorithm/min.h> 1373fbae83SNikolas Klauser #include <__cxx03/__config> 1473fbae83SNikolas Klauser #include <__cxx03/__fwd/bit_reference.h> 1573fbae83SNikolas Klauser #include <__cxx03/__iterator/iterator_traits.h> 1673fbae83SNikolas Klauser #include <__cxx03/__memory/pointer_traits.h> 1773fbae83SNikolas Klauser #include <__cxx03/__utility/convert_to_integral.h> 18e78f53d1SNikolas Klauser 19e78f53d1SNikolas Klauser #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 20e78f53d1SNikolas Klauser # pragma GCC system_header 21e78f53d1SNikolas Klauser #endif 22e78f53d1SNikolas Klauser 23e78f53d1SNikolas Klauser _LIBCPP_PUSH_MACROS 2473fbae83SNikolas Klauser #include <__cxx03/__undef_macros> 25e78f53d1SNikolas Klauser 26e78f53d1SNikolas Klauser _LIBCPP_BEGIN_NAMESPACE_STD 27e78f53d1SNikolas Klauser 28e78f53d1SNikolas Klauser // fill_n isn't specialized for std::memset, because the compiler already optimizes the loop to a call to std::memset. 29e78f53d1SNikolas Klauser 30e78f53d1SNikolas Klauser template <class _OutputIterator, class _Size, class _Tp> 31e78f53d1SNikolas Klauser inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator 32e78f53d1SNikolas Klauser __fill_n(_OutputIterator __first, _Size __n, const _Tp& __value); 33e78f53d1SNikolas Klauser 34e78f53d1SNikolas Klauser template <bool _FillVal, class _Cp> 35e78f53d1SNikolas Klauser _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void 36e78f53d1SNikolas Klauser __fill_n_bool(__bit_iterator<_Cp, false> __first, typename _Cp::size_type __n) { 37e78f53d1SNikolas Klauser using _It = __bit_iterator<_Cp, false>; 38e78f53d1SNikolas Klauser using __storage_type = typename _It::__storage_type; 39e78f53d1SNikolas Klauser 40e78f53d1SNikolas Klauser const int __bits_per_word = _It::__bits_per_word; 41e78f53d1SNikolas Klauser // do first partial word 42e78f53d1SNikolas Klauser if (__first.__ctz_ != 0) { 43e78f53d1SNikolas Klauser __storage_type __clz_f = static_cast<__storage_type>(__bits_per_word - __first.__ctz_); 44e78f53d1SNikolas Klauser __storage_type __dn = std::min(__clz_f, __n); 45e78f53d1SNikolas Klauser __storage_type __m = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz_f - __dn)); 46e78f53d1SNikolas Klauser if (_FillVal) 47e78f53d1SNikolas Klauser *__first.__seg_ |= __m; 48e78f53d1SNikolas Klauser else 49e78f53d1SNikolas Klauser *__first.__seg_ &= ~__m; 50e78f53d1SNikolas Klauser __n -= __dn; 51e78f53d1SNikolas Klauser ++__first.__seg_; 52e78f53d1SNikolas Klauser } 53e78f53d1SNikolas Klauser // do middle whole words 54e78f53d1SNikolas Klauser __storage_type __nw = __n / __bits_per_word; 55e78f53d1SNikolas Klauser std::__fill_n(std::__to_address(__first.__seg_), __nw, _FillVal ? static_cast<__storage_type>(-1) : 0); 56e78f53d1SNikolas Klauser __n -= __nw * __bits_per_word; 57e78f53d1SNikolas Klauser // do last partial word 58e78f53d1SNikolas Klauser if (__n > 0) { 59e78f53d1SNikolas Klauser __first.__seg_ += __nw; 60e78f53d1SNikolas Klauser __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n); 61e78f53d1SNikolas Klauser if (_FillVal) 62e78f53d1SNikolas Klauser *__first.__seg_ |= __m; 63e78f53d1SNikolas Klauser else 64e78f53d1SNikolas Klauser *__first.__seg_ &= ~__m; 65e78f53d1SNikolas Klauser } 66e78f53d1SNikolas Klauser } 67e78f53d1SNikolas Klauser 68e78f53d1SNikolas Klauser template <class _Cp, class _Size> 69e78f53d1SNikolas Klauser inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __bit_iterator<_Cp, false> 70e78f53d1SNikolas Klauser __fill_n(__bit_iterator<_Cp, false> __first, _Size __n, const bool& __value) { 71e78f53d1SNikolas Klauser if (__n > 0) { 72e78f53d1SNikolas Klauser if (__value) 73e78f53d1SNikolas Klauser std::__fill_n_bool<true>(__first, __n); 74e78f53d1SNikolas Klauser else 75e78f53d1SNikolas Klauser std::__fill_n_bool<false>(__first, __n); 76e78f53d1SNikolas Klauser } 77e78f53d1SNikolas Klauser return __first + __n; 78e78f53d1SNikolas Klauser } 79e78f53d1SNikolas Klauser 80e78f53d1SNikolas Klauser template <class _OutputIterator, class _Size, class _Tp> 81e78f53d1SNikolas Klauser inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator 82e78f53d1SNikolas Klauser __fill_n(_OutputIterator __first, _Size __n, const _Tp& __value) { 83e78f53d1SNikolas Klauser for (; __n > 0; ++__first, (void)--__n) 84e78f53d1SNikolas Klauser *__first = __value; 85e78f53d1SNikolas Klauser return __first; 86e78f53d1SNikolas Klauser } 87e78f53d1SNikolas Klauser 88e78f53d1SNikolas Klauser template <class _OutputIterator, class _Size, class _Tp> 89e78f53d1SNikolas Klauser inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator 90e78f53d1SNikolas Klauser fill_n(_OutputIterator __first, _Size __n, const _Tp& __value) { 91e78f53d1SNikolas Klauser return std::__fill_n(__first, std::__convert_to_integral(__n), __value); 92e78f53d1SNikolas Klauser } 93e78f53d1SNikolas Klauser 94e78f53d1SNikolas Klauser _LIBCPP_END_NAMESPACE_STD 95e78f53d1SNikolas Klauser 96e78f53d1SNikolas Klauser _LIBCPP_POP_MACROS 97e78f53d1SNikolas Klauser 98*ce777190SNikolas Klauser #endif // _LIBCPP___CXX03___ALGORITHM_FILL_N_H 99