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 #include <optional> 22 23 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 24 # pragma GCC system_header 25 #endif 26 27 #if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17 28 29 _LIBCPP_BEGIN_NAMESPACE_STD 30 31 template <class> 32 void __pstl_replace_if(); 33 34 template <class _ExecutionPolicy, 35 class _ForwardIterator, 36 class _Pred, 37 class _Tp, 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, 44 _Pred&& __pred, 45 const _Tp& __new_value) noexcept { 46 return std::__pstl_frontend_dispatch( 47 _LIBCPP_PSTL_CUSTOMIZATION_POINT(__pstl_replace_if, _RawPolicy), 48 [&__policy]( 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; 53 }); 54 return optional<__empty>{__empty{}}; 55 }, 56 std::move(__first), 57 std::move(__last), 58 std::move(__pred), 59 __new_value); 60 } 61 62 template <class _ExecutionPolicy, 63 class _ForwardIterator, 64 class _Pred, 65 class _Tp, 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, 72 _Pred __pred, 73 const _Tp& __new_value) { 74 auto __res = std::__replace_if(__policy, std::move(__first), std::move(__last), std::move(__pred), __new_value); 75 if (!__res) 76 std::__throw_bad_alloc(); 77 } 78 79 template <class> 80 void __pstl_replace(); 81 82 template <class _ExecutionPolicy, 83 class _ForwardIterator, 84 class _Tp, 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), 95 [&__policy]( 96 _ForwardIterator __g_first, _ForwardIterator __g_last, const _Tp& __g_old_value, const _Tp& __g_new_value) { 97 return std::__replace_if( 98 __policy, 99 std::move(__g_first), 100 std::move(__g_last), 101 [&](__iter_reference<_ForwardIterator> __element) { return __element == __g_old_value; }, 102 __g_new_value); 103 }, 104 std::move(__first), 105 std::move(__last), 106 __old_value, 107 __new_value); 108 } 109 110 template <class _ExecutionPolicy, 111 class _ForwardIterator, 112 class _Tp, 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(); 123 } 124 125 template <class> 126 void __pstl_replace_copy_if(); 127 128 template <class _ExecutionPolicy, 129 class _ForwardIterator, 130 class _ForwardOutIterator, 131 class _Pred, 132 class _Tp, 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, 140 _Pred&& __pred, 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, 147 _Pred __g_pred, 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; 152 })) 153 return nullopt; 154 return __empty{}; 155 }, 156 std::move(__first), 157 std::move(__last), 158 std::move(__result), 159 std::move(__pred), 160 __new_value); 161 } 162 163 template <class _ExecutionPolicy, 164 class _ForwardIterator, 165 class _ForwardOutIterator, 166 class _Pred, 167 class _Tp, 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, 175 _Pred __pred, 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(); 180 } 181 182 template <class> 183 void __pstl_replace_copy(); 184 185 template <class _ExecutionPolicy, 186 class _ForwardIterator, 187 class _ForwardOutIterator, 188 class _Tp, 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( 206 __policy, 207 std::move(__g_first), 208 std::move(__g_last), 209 std::move(__g_result), 210 [&](__iter_reference<_ForwardIterator> __element) { return __element == __g_old_value; }, 211 __g_new_value); 212 }, 213 std::move(__first), 214 std::move(__last), 215 std::move(__result), 216 __old_value, 217 __new_value); 218 } 219 220 template <class _ExecutionPolicy, 221 class _ForwardIterator, 222 class _ForwardOutIterator, 223 class _Tp, 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(); 236 } 237 238 _LIBCPP_END_NAMESPACE_STD 239 240 #endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17 241 242 #endif // _LIBCPP___ALGORITHM_PSTL_REPLACE_H 243