1 //===----------------------------------------------------------------------===//
2 //
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
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #ifndef _LIBCPP___ALGORITHM_PSTL_REPLACE_H
10 #define _LIBCPP___ALGORITHM_PSTL_REPLACE_H
11 
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>
16 #include <__config>
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>
21 
22 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
23 #  pragma GCC system_header
24 #endif
25 
26 #if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
27 
28 _LIBCPP_BEGIN_NAMESPACE_STD
29 
30 template <class>
31 void __pstl_replace_if();
32 
33 template <class _ExecutionPolicy,
34           class _ForwardIterator,
35           class _Pred,
36           class _Tp,
37           class _RawPolicy                                    = __remove_cvref_t<_ExecutionPolicy>,
38           enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
39 _LIBCPP_HIDE_FROM_ABI void
40 replace_if(_ExecutionPolicy&& __policy,
41            _ForwardIterator __first,
42            _ForwardIterator __last,
43            _Pred __pred,
44            const _Tp& __new_value) {
45   std::__pstl_frontend_dispatch(
46       _LIBCPP_PSTL_CUSTOMIZATION_POINT(__pstl_replace_if),
47       [&__policy](_ForwardIterator __g_first, _ForwardIterator __g_last, _Pred __g_pred, const _Tp& __g_new_value) {
48         std::for_each(__policy, __g_first, __g_last, [&](__iter_reference<_ForwardIterator> __element) {
49           if (__g_pred(__element))
50             __element = __g_new_value;
51         });
52       },
53       std::move(__first),
54       std::move(__last),
55       std::move(__pred),
56       __new_value);
57 }
58 
59 template <class>
60 void __pstl_replace();
61 
62 template <class _ExecutionPolicy,
63           class _ForwardIterator,
64           class _Tp,
65           class _RawPolicy                                    = __remove_cvref_t<_ExecutionPolicy>,
66           enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
67 _LIBCPP_HIDE_FROM_ABI void
68 replace(_ExecutionPolicy&& __policy,
69         _ForwardIterator __first,
70         _ForwardIterator __last,
71         const _Tp& __old_value,
72         const _Tp& __new_value) {
73   std::__pstl_frontend_dispatch(
74       _LIBCPP_PSTL_CUSTOMIZATION_POINT(__pstl_replace),
75       [&__policy](
76           _ForwardIterator __g_first, _ForwardIterator __g_last, const _Tp& __g_old_value, const _Tp& __g_new_value) {
77         std::replace_if(
78             __policy,
79             std::move(__g_first),
80             std::move(__g_last),
81             [&](__iter_reference<_ForwardIterator> __element) { return __element == __g_old_value; },
82             __g_new_value);
83       },
84       std::move(__first),
85       std::move(__last),
86       __old_value,
87       __new_value);
88 }
89 
90 template <class>
91 void __pstl_replace_copy_if();
92 
93 template <class _ExecutionPolicy,
94           class _ForwardIterator,
95           class _ForwardOutIterator,
96           class _Pred,
97           class _Tp,
98           class _RawPolicy                                    = __remove_cvref_t<_ExecutionPolicy>,
99           enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
100 _LIBCPP_HIDE_FROM_ABI void replace_copy_if(
101     _ExecutionPolicy&& __policy,
102     _ForwardIterator __first,
103     _ForwardIterator __last,
104     _ForwardOutIterator __result,
105     _Pred __pred,
106     const _Tp& __new_value) {
107   std::__pstl_frontend_dispatch(
108       _LIBCPP_PSTL_CUSTOMIZATION_POINT(__pstl_replace_copy_if),
109       [&__policy](_ForwardIterator __g_first,
110                   _ForwardIterator __g_last,
111                   _ForwardOutIterator __g_result,
112                   _Pred __g_pred,
113                   const _Tp& __g_new_value) {
114         std::transform(__policy, __g_first, __g_last, __g_result, [&](__iter_reference<_ForwardIterator> __element) {
115           return __g_pred(__element) ? __g_new_value : __element;
116         });
117       },
118       std::move(__first),
119       std::move(__last),
120       std::move(__result),
121       std::move(__pred),
122       __new_value);
123 }
124 
125 template <class>
126 void __pstl_replace_copy();
127 
128 template <class _ExecutionPolicy,
129           class _ForwardIterator,
130           class _ForwardOutIterator,
131           class _Tp,
132           class _RawPolicy                                    = __remove_cvref_t<_ExecutionPolicy>,
133           enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
134 _LIBCPP_HIDE_FROM_ABI void replace_copy(
135     _ExecutionPolicy&& __policy,
136     _ForwardIterator __first,
137     _ForwardIterator __last,
138     _ForwardOutIterator __result,
139     const _Tp& __old_value,
140     const _Tp& __new_value) {
141   std::__pstl_frontend_dispatch(
142       _LIBCPP_PSTL_CUSTOMIZATION_POINT(__pstl_replace_copy),
143       [&__policy](_ForwardIterator __g_first,
144                   _ForwardIterator __g_last,
145                   _ForwardOutIterator __g_result,
146                   const _Tp& __g_old_value,
147                   const _Tp& __g_new_value) {
148         return std::replace_copy_if(
149             __policy,
150             std::move(__g_first),
151             std::move(__g_last),
152             std::move(__g_result),
153             [&](__iter_reference<_ForwardIterator> __element) { return __element == __g_old_value; },
154             __g_new_value);
155       },
156       std::move(__first),
157       std::move(__last),
158       std::move(__result),
159       __old_value,
160       __new_value);
161 }
162 
163 _LIBCPP_END_NAMESPACE_STD
164 
165 #endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
166 
167 #endif // _LIBCPP___ALGORITHM_PSTL_REPLACE_H
168