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