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 34template <class> 35void __pstl_replace_if(); 36 37template <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 65template <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 72replace_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 82template <class> 83void __pstl_replace(); 84 85template <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 113template <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 119replace(_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 128template <class> 129void __pstl_replace_copy_if(); 130 131template <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 166template <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 185template <class> 186void __pstl_replace_copy(); 187 188template <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 223template <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