1*0fca6ea1SDimitry Andric //===----------------------------------------------------------------------===// 2*0fca6ea1SDimitry Andric // 3*0fca6ea1SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*0fca6ea1SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 5*0fca6ea1SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*0fca6ea1SDimitry Andric // 7*0fca6ea1SDimitry Andric //===----------------------------------------------------------------------===// 8*0fca6ea1SDimitry Andric 9*0fca6ea1SDimitry Andric #ifndef _LIBCPP___PSTL_CPU_ALGOS_FILL_H 10*0fca6ea1SDimitry Andric #define _LIBCPP___PSTL_CPU_ALGOS_FILL_H 11*0fca6ea1SDimitry Andric 12*0fca6ea1SDimitry Andric #include <__algorithm/fill.h> 13*0fca6ea1SDimitry Andric #include <__assert> 14*0fca6ea1SDimitry Andric #include <__config> 15*0fca6ea1SDimitry Andric #include <__iterator/concepts.h> 16*0fca6ea1SDimitry Andric #include <__pstl/backend_fwd.h> 17*0fca6ea1SDimitry Andric #include <__pstl/cpu_algos/cpu_traits.h> 18*0fca6ea1SDimitry Andric #include <__type_traits/is_execution_policy.h> 19*0fca6ea1SDimitry Andric #include <__utility/empty.h> 20*0fca6ea1SDimitry Andric #include <optional> 21*0fca6ea1SDimitry Andric 22*0fca6ea1SDimitry Andric #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 23*0fca6ea1SDimitry Andric # pragma GCC system_header 24*0fca6ea1SDimitry Andric #endif 25*0fca6ea1SDimitry Andric 26*0fca6ea1SDimitry Andric _LIBCPP_BEGIN_NAMESPACE_STD 27*0fca6ea1SDimitry Andric namespace __pstl { 28*0fca6ea1SDimitry Andric 29*0fca6ea1SDimitry Andric template <class _Index, class _DifferenceType, class _Tp> 30*0fca6ea1SDimitry Andric _LIBCPP_HIDE_FROM_ABI _Index __simd_fill_n(_Index __first, _DifferenceType __n, const _Tp& __value) noexcept { 31*0fca6ea1SDimitry Andric _PSTL_USE_NONTEMPORAL_STORES_IF_ALLOWED 32*0fca6ea1SDimitry Andric _PSTL_PRAGMA_SIMD 33*0fca6ea1SDimitry Andric for (_DifferenceType __i = 0; __i < __n; ++__i) 34*0fca6ea1SDimitry Andric __first[__i] = __value; 35*0fca6ea1SDimitry Andric return __first + __n; 36*0fca6ea1SDimitry Andric } 37*0fca6ea1SDimitry Andric 38*0fca6ea1SDimitry Andric template <class _Backend, class _RawExecutionPolicy> 39*0fca6ea1SDimitry Andric struct __cpu_parallel_fill { 40*0fca6ea1SDimitry Andric template <class _Policy, class _ForwardIterator, class _Tp> 41*0fca6ea1SDimitry Andric _LIBCPP_HIDE_FROM_ABI optional<__empty> 42*0fca6ea1SDimitry Andric operator()(_Policy&& __policy, _ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) const noexcept { 43*0fca6ea1SDimitry Andric if constexpr (__is_parallel_execution_policy_v<_RawExecutionPolicy> && 44*0fca6ea1SDimitry Andric __has_random_access_iterator_category_or_concept<_ForwardIterator>::value) { 45*0fca6ea1SDimitry Andric return __cpu_traits<_Backend>::__for_each( 46*0fca6ea1SDimitry Andric __first, __last, [&__policy, &__value](_ForwardIterator __brick_first, _ForwardIterator __brick_last) { 47*0fca6ea1SDimitry Andric using _FillUnseq = __pstl::__fill<_Backend, __remove_parallel_policy_t<_RawExecutionPolicy>>; 48*0fca6ea1SDimitry Andric [[maybe_unused]] auto __res = 49*0fca6ea1SDimitry Andric _FillUnseq()(std::__remove_parallel_policy(__policy), __brick_first, __brick_last, __value); 50*0fca6ea1SDimitry Andric _LIBCPP_ASSERT_INTERNAL(__res, "unseq/seq should never try to allocate!"); 51*0fca6ea1SDimitry Andric }); 52*0fca6ea1SDimitry Andric } else if constexpr (__is_unsequenced_execution_policy_v<_RawExecutionPolicy> && 53*0fca6ea1SDimitry Andric __has_random_access_iterator_category_or_concept<_ForwardIterator>::value) { 54*0fca6ea1SDimitry Andric __pstl::__simd_fill_n(__first, __last - __first, __value); 55*0fca6ea1SDimitry Andric return __empty{}; 56*0fca6ea1SDimitry Andric } else { 57*0fca6ea1SDimitry Andric std::fill(__first, __last, __value); 58*0fca6ea1SDimitry Andric return __empty{}; 59*0fca6ea1SDimitry Andric } 60*0fca6ea1SDimitry Andric } 61*0fca6ea1SDimitry Andric }; 62*0fca6ea1SDimitry Andric 63*0fca6ea1SDimitry Andric } // namespace __pstl 64*0fca6ea1SDimitry Andric _LIBCPP_END_NAMESPACE_STD 65*0fca6ea1SDimitry Andric 66*0fca6ea1SDimitry Andric #endif // _LIBCPP___PSTL_CPU_ALGOS_FILL_H 67