1ff6d5deeSNikolas Klauser //===----------------------------------------------------------------------===// 2ff6d5deeSNikolas Klauser // 3ff6d5deeSNikolas Klauser // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4ff6d5deeSNikolas Klauser // See https://llvm.org/LICENSE.txt for license information. 5ff6d5deeSNikolas Klauser // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6ff6d5deeSNikolas Klauser // 7ff6d5deeSNikolas Klauser //===----------------------------------------------------------------------===// 8ff6d5deeSNikolas Klauser 9ff6d5deeSNikolas Klauser #ifndef _LIBCPP___ALGORITHM_RANGES_REPLACE_IF_H 10ff6d5deeSNikolas Klauser #define _LIBCPP___ALGORITHM_RANGES_REPLACE_IF_H 11ff6d5deeSNikolas Klauser 12ff6d5deeSNikolas Klauser #include <__config> 13ff6d5deeSNikolas Klauser #include <__functional/identity.h> 14ff6d5deeSNikolas Klauser #include <__functional/invoke.h> 15ff6d5deeSNikolas Klauser #include <__iterator/concepts.h> 16ff6d5deeSNikolas Klauser #include <__iterator/projected.h> 17ff6d5deeSNikolas Klauser #include <__ranges/access.h> 18ff6d5deeSNikolas Klauser #include <__ranges/concepts.h> 19ff6d5deeSNikolas Klauser #include <__ranges/dangling.h> 20ff6d5deeSNikolas Klauser #include <__utility/move.h> 21ff6d5deeSNikolas Klauser 22ff6d5deeSNikolas Klauser #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 23ff6d5deeSNikolas Klauser # pragma GCC system_header 24ff6d5deeSNikolas Klauser #endif 25ff6d5deeSNikolas Klauser 267b462251SLouis Dionne _LIBCPP_PUSH_MACROS 277b462251SLouis Dionne #include <__undef_macros> 287b462251SLouis Dionne 294f15267dSNikolas Klauser #if _LIBCPP_STD_VER >= 20 30ff6d5deeSNikolas Klauser 31ff6d5deeSNikolas Klauser _LIBCPP_BEGIN_NAMESPACE_STD 32ff6d5deeSNikolas Klauser 33ff6d5deeSNikolas Klauser namespace ranges { 34ff6d5deeSNikolas Klauser 35ff6d5deeSNikolas Klauser template <class _Iter, class _Sent, class _Type, class _Proj, class _Pred> 365aa03b64SLouis Dionne _LIBCPP_HIDE_FROM_ABI constexpr _Iter 375aa03b64SLouis Dionne __replace_if_impl(_Iter __first, _Sent __last, _Pred& __pred, const _Type& __new_value, _Proj& __proj) { 38ff6d5deeSNikolas Klauser for (; __first != __last; ++__first) { 39ff6d5deeSNikolas Klauser if (std::invoke(__pred, std::invoke(__proj, *__first))) 40ff6d5deeSNikolas Klauser *__first = __new_value; 41ff6d5deeSNikolas Klauser } 42ff6d5deeSNikolas Klauser return __first; 43ff6d5deeSNikolas Klauser } 44ff6d5deeSNikolas Klauser 45*d10dc5a0SChristopher Di Bella struct __replace_if { 465aa03b64SLouis Dionne template <input_iterator _Iter, 475aa03b64SLouis Dionne sentinel_for<_Iter> _Sent, 48ff6d5deeSNikolas Klauser class _Type, 49ff6d5deeSNikolas Klauser class _Proj = identity, 50ff6d5deeSNikolas Klauser indirect_unary_predicate<projected<_Iter, _Proj>> _Pred> 51ff6d5deeSNikolas Klauser requires indirectly_writable<_Iter, const _Type&> 525aa03b64SLouis Dionne _LIBCPP_HIDE_FROM_ABI constexpr _Iter 535aa03b64SLouis Dionne operator()(_Iter __first, _Sent __last, _Pred __pred, const _Type& __new_value, _Proj __proj = {}) const { 54ff6d5deeSNikolas Klauser return ranges::__replace_if_impl(std::move(__first), std::move(__last), __pred, __new_value, __proj); 55ff6d5deeSNikolas Klauser } 56ff6d5deeSNikolas Klauser 57ff6d5deeSNikolas Klauser template <input_range _Range, 58ff6d5deeSNikolas Klauser class _Type, 59ff6d5deeSNikolas Klauser class _Proj = identity, 60ff6d5deeSNikolas Klauser indirect_unary_predicate<projected<iterator_t<_Range>, _Proj>> _Pred> 61ff6d5deeSNikolas Klauser requires indirectly_writable<iterator_t<_Range>, const _Type&> 62ff6d5deeSNikolas Klauser _LIBCPP_HIDE_FROM_ABI constexpr borrowed_iterator_t<_Range> 63ff6d5deeSNikolas Klauser operator()(_Range&& __range, _Pred __pred, const _Type& __new_value, _Proj __proj = {}) const { 64ff6d5deeSNikolas Klauser return ranges::__replace_if_impl(ranges::begin(__range), ranges::end(__range), __pred, __new_value, __proj); 65ff6d5deeSNikolas Klauser } 66ff6d5deeSNikolas Klauser }; 67ff6d5deeSNikolas Klauser 68ff6d5deeSNikolas Klauser inline namespace __cpo { 69*d10dc5a0SChristopher Di Bella inline constexpr auto replace_if = __replace_if{}; 70ff6d5deeSNikolas Klauser } // namespace __cpo 71ff6d5deeSNikolas Klauser } // namespace ranges 72ff6d5deeSNikolas Klauser 73ff6d5deeSNikolas Klauser _LIBCPP_END_NAMESPACE_STD 74ff6d5deeSNikolas Klauser 754f15267dSNikolas Klauser #endif // _LIBCPP_STD_VER >= 20 76ff6d5deeSNikolas Klauser 777b462251SLouis Dionne _LIBCPP_POP_MACROS 787b462251SLouis Dionne 79ff6d5deeSNikolas Klauser #endif // _LIBCPP___ALGORITHM_RANGES_REPLACE_IF_H 80