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___ALGORITHM_PSTL_REPLACE_H
10 #define _LIBCPP___ALGORITHM_PSTL_REPLACE_H
12 #include <__algorithm/pstl_backend.h>
13 #include <__algorithm/pstl_for_each.h>
14 #include <__algorithm/pstl_frontend_dispatch.h>
15 #include <__algorithm/pstl_transform.h>
17 #include <__iterator/iterator_traits.h>
18 #include <__type_traits/enable_if.h>
19 #include <__type_traits/remove_cvref.h>
20 #include <__utility/move.h>
23 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
24 # pragma GCC system_header
27 #if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
29 _LIBCPP_BEGIN_NAMESPACE_STD
32 void __pstl_replace_if();
34 template <class _ExecutionPolicy
,
35 class _ForwardIterator
,
38 class _RawPolicy
= __remove_cvref_t
<_ExecutionPolicy
>,
39 enable_if_t
<is_execution_policy_v
<_RawPolicy
>, int> = 0>
40 [[nodiscard
]] _LIBCPP_HIDE_FROM_ABI optional
<__empty
>
41 __replace_if(_ExecutionPolicy
&& __policy
,
42 _ForwardIterator
&& __first
,
43 _ForwardIterator
&& __last
,
45 const _Tp
& __new_value
) noexcept
{
46 return std::__pstl_frontend_dispatch(
47 _LIBCPP_PSTL_CUSTOMIZATION_POINT(__pstl_replace_if
, _RawPolicy
),
49 _ForwardIterator
&& __g_first
, _ForwardIterator
&& __g_last
, _Pred
&& __g_pred
, const _Tp
& __g_new_value
) {
50 std::for_each(__policy
, __g_first
, __g_last
, [&](__iter_reference
<_ForwardIterator
> __element
) {
51 if (__g_pred(__element
))
52 __element
= __g_new_value
;
54 return optional
<__empty
>{__empty
{}};
62 template <class _ExecutionPolicy
,
63 class _ForwardIterator
,
66 class _RawPolicy
= __remove_cvref_t
<_ExecutionPolicy
>,
67 enable_if_t
<is_execution_policy_v
<_RawPolicy
>, int> = 0>
68 _LIBCPP_HIDE_FROM_ABI
void
69 replace_if(_ExecutionPolicy
&& __policy
,
70 _ForwardIterator __first
,
71 _ForwardIterator __last
,
73 const _Tp
& __new_value
) {
74 auto __res
= std::__replace_if(__policy
, std::move(__first
), std::move(__last
), std::move(__pred
), __new_value
);
76 std::__throw_bad_alloc();
80 void __pstl_replace();
82 template <class _ExecutionPolicy
,
83 class _ForwardIterator
,
85 class _RawPolicy
= __remove_cvref_t
<_ExecutionPolicy
>,
86 enable_if_t
<is_execution_policy_v
<_RawPolicy
>, int> = 0>
87 [[nodiscard
]] _LIBCPP_HIDE_FROM_ABI optional
<__empty
>
88 __replace(_ExecutionPolicy
&& __policy
,
89 _ForwardIterator __first
,
90 _ForwardIterator __last
,
91 const _Tp
& __old_value
,
92 const _Tp
& __new_value
) noexcept
{
93 return std::__pstl_frontend_dispatch(
94 _LIBCPP_PSTL_CUSTOMIZATION_POINT(__pstl_replace
, _RawPolicy
),
96 _ForwardIterator __g_first
, _ForwardIterator __g_last
, const _Tp
& __g_old_value
, const _Tp
& __g_new_value
) {
97 return std::__replace_if(
101 [&](__iter_reference
<_ForwardIterator
> __element
) { return __element
== __g_old_value
; },
110 template <class _ExecutionPolicy
,
111 class _ForwardIterator
,
113 class _RawPolicy
= __remove_cvref_t
<_ExecutionPolicy
>,
114 enable_if_t
<is_execution_policy_v
<_RawPolicy
>, int> = 0>
115 _LIBCPP_HIDE_FROM_ABI
void
116 replace(_ExecutionPolicy
&& __policy
,
117 _ForwardIterator __first
,
118 _ForwardIterator __last
,
119 const _Tp
& __old_value
,
120 const _Tp
& __new_value
) {
121 if (!std::__replace(__policy
, std::move(__first
), std::move(__last
), __old_value
, __new_value
))
122 std::__throw_bad_alloc();
126 void __pstl_replace_copy_if();
128 template <class _ExecutionPolicy
,
129 class _ForwardIterator
,
130 class _ForwardOutIterator
,
133 class _RawPolicy
= __remove_cvref_t
<_ExecutionPolicy
>,
134 enable_if_t
<is_execution_policy_v
<_RawPolicy
>, int> = 0>
135 [[nodiscard
]] _LIBCPP_HIDE_FROM_ABI optional
<__empty
> __replace_copy_if(
136 _ExecutionPolicy
&& __policy
,
137 _ForwardIterator
&& __first
,
138 _ForwardIterator
&& __last
,
139 _ForwardOutIterator
&& __result
,
141 const _Tp
& __new_value
) {
142 return std::__pstl_frontend_dispatch(
143 _LIBCPP_PSTL_CUSTOMIZATION_POINT(__pstl_replace_copy_if
, _RawPolicy
),
144 [&__policy
](_ForwardIterator __g_first
,
145 _ForwardIterator __g_last
,
146 _ForwardOutIterator __g_result
,
148 const _Tp
& __g_new_value
) -> optional
<__empty
> {
149 if (!std::__transform(
150 __policy
, __g_first
, __g_last
, __g_result
, [&](__iter_reference
<_ForwardIterator
> __element
) {
151 return __g_pred(__element
) ? __g_new_value
: __element
;
163 template <class _ExecutionPolicy
,
164 class _ForwardIterator
,
165 class _ForwardOutIterator
,
168 class _RawPolicy
= __remove_cvref_t
<_ExecutionPolicy
>,
169 enable_if_t
<is_execution_policy_v
<_RawPolicy
>, int> = 0>
170 _LIBCPP_HIDE_FROM_ABI
void replace_copy_if(
171 _ExecutionPolicy
&& __policy
,
172 _ForwardIterator __first
,
173 _ForwardIterator __last
,
174 _ForwardOutIterator __result
,
176 const _Tp
& __new_value
) {
177 if (!std::__replace_copy_if(
178 __policy
, std::move(__first
), std::move(__last
), std::move(__result
), std::move(__pred
), __new_value
))
179 std::__throw_bad_alloc();
183 void __pstl_replace_copy();
185 template <class _ExecutionPolicy
,
186 class _ForwardIterator
,
187 class _ForwardOutIterator
,
189 class _RawPolicy
= __remove_cvref_t
<_ExecutionPolicy
>,
190 enable_if_t
<is_execution_policy_v
<_RawPolicy
>, int> = 0>
191 [[nodiscard
]] _LIBCPP_HIDE_FROM_ABI optional
<__empty
> __replace_copy(
192 _ExecutionPolicy
&& __policy
,
193 _ForwardIterator
&& __first
,
194 _ForwardIterator
&& __last
,
195 _ForwardOutIterator
&& __result
,
196 const _Tp
& __old_value
,
197 const _Tp
& __new_value
) noexcept
{
198 return std::__pstl_frontend_dispatch(
199 _LIBCPP_PSTL_CUSTOMIZATION_POINT(__pstl_replace_copy
, _RawPolicy
),
200 [&__policy
](_ForwardIterator __g_first
,
201 _ForwardIterator __g_last
,
202 _ForwardOutIterator __g_result
,
203 const _Tp
& __g_old_value
,
204 const _Tp
& __g_new_value
) {
205 return std::__replace_copy_if(
207 std::move(__g_first
),
209 std::move(__g_result
),
210 [&](__iter_reference
<_ForwardIterator
> __element
) { return __element
== __g_old_value
; },
220 template <class _ExecutionPolicy
,
221 class _ForwardIterator
,
222 class _ForwardOutIterator
,
224 class _RawPolicy
= __remove_cvref_t
<_ExecutionPolicy
>,
225 enable_if_t
<is_execution_policy_v
<_RawPolicy
>, int> = 0>
226 _LIBCPP_HIDE_FROM_ABI
void replace_copy(
227 _ExecutionPolicy
&& __policy
,
228 _ForwardIterator __first
,
229 _ForwardIterator __last
,
230 _ForwardOutIterator __result
,
231 const _Tp
& __old_value
,
232 const _Tp
& __new_value
) {
233 if (!std::__replace_copy(
234 __policy
, std::move(__first
), std::move(__last
), std::move(__result
), __old_value
, __new_value
))
235 std::__throw_bad_alloc();
238 _LIBCPP_END_NAMESPACE_STD
240 #endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
242 #endif // _LIBCPP___ALGORITHM_PSTL_REPLACE_H