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 _LIBCPP_PUSH_MACROS 28 #include <__undef_macros> 29 30 #if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17 31 32 _LIBCPP_BEGIN_NAMESPACE_STD 33 34 template <class> 35 void __pstl_replace_if(); 36 37 template <class _ExecutionPolicy, 38 class _ForwardIterator, 39 class _Pred, 40 class _Tp, 41 class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>, 42 enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0> 43 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<__empty> 44 __replace_if(_ExecutionPolicy&& __policy, 45 _ForwardIterator&& __first, 46 _ForwardIterator&& __last, 47 _Pred&& __pred, 48 const _Tp& __new_value) noexcept { 49 return std::__pstl_frontend_dispatch( 50 _LIBCPP_PSTL_CUSTOMIZATION_POINT(__pstl_replace_if, _RawPolicy), 51 [&__policy]( 52 _ForwardIterator&& __g_first, _ForwardIterator&& __g_last, _Pred&& __g_pred, const _Tp& __g_new_value) { 53 std::for_each(__policy, __g_first, __g_last, [&](__iter_reference<_ForwardIterator> __element) { 54 if (__g_pred(__element)) 55 __element = __g_new_value; 56 }); 57 return optional<__empty>{__empty{}}; 58 }, 59 std::move(__first), 60 std::move(__last), 61 std::move(__pred), 62 __new_value); 63 } 64 65 template <class _ExecutionPolicy, 66 class _ForwardIterator, 67 class _Pred, 68 class _Tp, 69 class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>, 70 enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0> 71 _LIBCPP_HIDE_FROM_ABI void 72 replace_if(_ExecutionPolicy&& __policy, 73 _ForwardIterator __first, 74 _ForwardIterator __last, 75 _Pred __pred, 76 const _Tp& __new_value) { 77 auto __res = std::__replace_if(__policy, std::move(__first), std::move(__last), std::move(__pred), __new_value); 78 if (!__res) 79 std::__throw_bad_alloc(); 80 } 81 82 template <class> 83 void __pstl_replace(); 84 85 template <class _ExecutionPolicy, 86 class _ForwardIterator, 87 class _Tp, 88 class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>, 89 enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0> 90 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<__empty> 91 __replace(_ExecutionPolicy&& __policy, 92 _ForwardIterator __first, 93 _ForwardIterator __last, 94 const _Tp& __old_value, 95 const _Tp& __new_value) noexcept { 96 return std::__pstl_frontend_dispatch( 97 _LIBCPP_PSTL_CUSTOMIZATION_POINT(__pstl_replace, _RawPolicy), 98 [&__policy]( 99 _ForwardIterator __g_first, _ForwardIterator __g_last, const _Tp& __g_old_value, const _Tp& __g_new_value) { 100 return std::__replace_if( 101 __policy, 102 std::move(__g_first), 103 std::move(__g_last), 104 [&](__iter_reference<_ForwardIterator> __element) { return __element == __g_old_value; }, 105 __g_new_value); 106 }, 107 std::move(__first), 108 std::move(__last), 109 __old_value, 110 __new_value); 111 } 112 113 template <class _ExecutionPolicy, 114 class _ForwardIterator, 115 class _Tp, 116 class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>, 117 enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0> 118 _LIBCPP_HIDE_FROM_ABI void 119 replace(_ExecutionPolicy&& __policy, 120 _ForwardIterator __first, 121 _ForwardIterator __last, 122 const _Tp& __old_value, 123 const _Tp& __new_value) { 124 if (!std::__replace(__policy, std::move(__first), std::move(__last), __old_value, __new_value)) 125 std::__throw_bad_alloc(); 126 } 127 128 template <class> 129 void __pstl_replace_copy_if(); 130 131 template <class _ExecutionPolicy, 132 class _ForwardIterator, 133 class _ForwardOutIterator, 134 class _Pred, 135 class _Tp, 136 class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>, 137 enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0> 138 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<__empty> __replace_copy_if( 139 _ExecutionPolicy&& __policy, 140 _ForwardIterator&& __first, 141 _ForwardIterator&& __last, 142 _ForwardOutIterator&& __result, 143 _Pred&& __pred, 144 const _Tp& __new_value) { 145 return std::__pstl_frontend_dispatch( 146 _LIBCPP_PSTL_CUSTOMIZATION_POINT(__pstl_replace_copy_if, _RawPolicy), 147 [&__policy](_ForwardIterator __g_first, 148 _ForwardIterator __g_last, 149 _ForwardOutIterator __g_result, 150 _Pred __g_pred, 151 const _Tp& __g_new_value) -> optional<__empty> { 152 if (!std::__transform( 153 __policy, __g_first, __g_last, __g_result, [&](__iter_reference<_ForwardIterator> __element) { 154 return __g_pred(__element) ? __g_new_value : __element; 155 })) 156 return nullopt; 157 return __empty{}; 158 }, 159 std::move(__first), 160 std::move(__last), 161 std::move(__result), 162 std::move(__pred), 163 __new_value); 164 } 165 166 template <class _ExecutionPolicy, 167 class _ForwardIterator, 168 class _ForwardOutIterator, 169 class _Pred, 170 class _Tp, 171 class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>, 172 enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0> 173 _LIBCPP_HIDE_FROM_ABI void replace_copy_if( 174 _ExecutionPolicy&& __policy, 175 _ForwardIterator __first, 176 _ForwardIterator __last, 177 _ForwardOutIterator __result, 178 _Pred __pred, 179 const _Tp& __new_value) { 180 if (!std::__replace_copy_if( 181 __policy, std::move(__first), std::move(__last), std::move(__result), std::move(__pred), __new_value)) 182 std::__throw_bad_alloc(); 183 } 184 185 template <class> 186 void __pstl_replace_copy(); 187 188 template <class _ExecutionPolicy, 189 class _ForwardIterator, 190 class _ForwardOutIterator, 191 class _Tp, 192 class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>, 193 enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0> 194 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<__empty> __replace_copy( 195 _ExecutionPolicy&& __policy, 196 _ForwardIterator&& __first, 197 _ForwardIterator&& __last, 198 _ForwardOutIterator&& __result, 199 const _Tp& __old_value, 200 const _Tp& __new_value) noexcept { 201 return std::__pstl_frontend_dispatch( 202 _LIBCPP_PSTL_CUSTOMIZATION_POINT(__pstl_replace_copy, _RawPolicy), 203 [&__policy](_ForwardIterator __g_first, 204 _ForwardIterator __g_last, 205 _ForwardOutIterator __g_result, 206 const _Tp& __g_old_value, 207 const _Tp& __g_new_value) { 208 return std::__replace_copy_if( 209 __policy, 210 std::move(__g_first), 211 std::move(__g_last), 212 std::move(__g_result), 213 [&](__iter_reference<_ForwardIterator> __element) { return __element == __g_old_value; }, 214 __g_new_value); 215 }, 216 std::move(__first), 217 std::move(__last), 218 std::move(__result), 219 __old_value, 220 __new_value); 221 } 222 223 template <class _ExecutionPolicy, 224 class _ForwardIterator, 225 class _ForwardOutIterator, 226 class _Tp, 227 class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>, 228 enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0> 229 _LIBCPP_HIDE_FROM_ABI void replace_copy( 230 _ExecutionPolicy&& __policy, 231 _ForwardIterator __first, 232 _ForwardIterator __last, 233 _ForwardOutIterator __result, 234 const _Tp& __old_value, 235 const _Tp& __new_value) { 236 if (!std::__replace_copy( 237 __policy, std::move(__first), std::move(__last), std::move(__result), __old_value, __new_value)) 238 std::__throw_bad_alloc(); 239 } 240 241 _LIBCPP_END_NAMESPACE_STD 242 243 #endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17 244 245 _LIBCPP_POP_MACROS 246 247 #endif // _LIBCPP___ALGORITHM_PSTL_REPLACE_H 248