1f8cbe3cdSNikolas Klauser //===----------------------------------------------------------------------===// 2f8cbe3cdSNikolas Klauser // 3f8cbe3cdSNikolas Klauser // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4f8cbe3cdSNikolas Klauser // See https://llvm.org/LICENSE.txt for license information. 5f8cbe3cdSNikolas Klauser // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6f8cbe3cdSNikolas Klauser // 7f8cbe3cdSNikolas Klauser //===----------------------------------------------------------------------===// 8f8cbe3cdSNikolas Klauser 9f8cbe3cdSNikolas Klauser #ifndef _LIBCPP___ALGORITHM_RANGES_REMOVE_IF_H 10f8cbe3cdSNikolas Klauser #define _LIBCPP___ALGORITHM_RANGES_REMOVE_IF_H 11f8cbe3cdSNikolas Klauser #include <__config> 12f8cbe3cdSNikolas Klauser 13f8cbe3cdSNikolas Klauser #include <__algorithm/ranges_find_if.h> 14f8cbe3cdSNikolas Klauser #include <__functional/identity.h> 15f8cbe3cdSNikolas Klauser #include <__functional/invoke.h> 16f8cbe3cdSNikolas Klauser #include <__functional/ranges_operations.h> 17f8cbe3cdSNikolas Klauser #include <__iterator/concepts.h> 18f8cbe3cdSNikolas Klauser #include <__iterator/iter_move.h> 19f8cbe3cdSNikolas Klauser #include <__iterator/permutable.h> 20f8cbe3cdSNikolas Klauser #include <__iterator/projected.h> 21f8cbe3cdSNikolas Klauser #include <__ranges/access.h> 22f8cbe3cdSNikolas Klauser #include <__ranges/concepts.h> 23f8cbe3cdSNikolas Klauser #include <__ranges/subrange.h> 24f8cbe3cdSNikolas Klauser #include <__utility/move.h> 25f8cbe3cdSNikolas Klauser 26f8cbe3cdSNikolas Klauser #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 27f8cbe3cdSNikolas Klauser # pragma GCC system_header 28f8cbe3cdSNikolas Klauser #endif 29f8cbe3cdSNikolas Klauser 307b462251SLouis Dionne _LIBCPP_PUSH_MACROS 317b462251SLouis Dionne #include <__undef_macros> 327b462251SLouis Dionne 334f15267dSNikolas Klauser #if _LIBCPP_STD_VER >= 20 34f8cbe3cdSNikolas Klauser 35f8cbe3cdSNikolas Klauser _LIBCPP_BEGIN_NAMESPACE_STD 36f8cbe3cdSNikolas Klauser 37f8cbe3cdSNikolas Klauser namespace ranges { 38f8cbe3cdSNikolas Klauser 39f8cbe3cdSNikolas Klauser template <class _Iter, class _Sent, class _Proj, class _Pred> 405aa03b64SLouis Dionne _LIBCPP_HIDE_FROM_ABI constexpr subrange<_Iter> 415aa03b64SLouis Dionne __remove_if_impl(_Iter __first, _Sent __last, _Pred& __pred, _Proj& __proj) { 42f8cbe3cdSNikolas Klauser auto __new_end = ranges::__find_if_impl(__first, __last, __pred, __proj); 43f8cbe3cdSNikolas Klauser if (__new_end == __last) 44f8cbe3cdSNikolas Klauser return {__new_end, __new_end}; 45f8cbe3cdSNikolas Klauser 46f8cbe3cdSNikolas Klauser _Iter __i = __new_end; 47f8cbe3cdSNikolas Klauser while (++__i != __last) { 48f8cbe3cdSNikolas Klauser if (!std::invoke(__pred, std::invoke(__proj, *__i))) { 49f8cbe3cdSNikolas Klauser *__new_end = ranges::iter_move(__i); 50f8cbe3cdSNikolas Klauser ++__new_end; 51f8cbe3cdSNikolas Klauser } 52f8cbe3cdSNikolas Klauser } 53f8cbe3cdSNikolas Klauser return {__new_end, __i}; 54f8cbe3cdSNikolas Klauser } 55f8cbe3cdSNikolas Klauser 56*d10dc5a0SChristopher Di Bella struct __remove_if { 575aa03b64SLouis Dionne template <permutable _Iter, 585aa03b64SLouis Dionne sentinel_for<_Iter> _Sent, 59f8cbe3cdSNikolas Klauser class _Proj = identity, 60f8cbe3cdSNikolas Klauser indirect_unary_predicate<projected<_Iter, _Proj>> _Pred> 6183bc7b57SNikolas Klauser [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr subrange<_Iter> 625aa03b64SLouis Dionne operator()(_Iter __first, _Sent __last, _Pred __pred, _Proj __proj = {}) const { 63f8cbe3cdSNikolas Klauser return ranges::__remove_if_impl(std::move(__first), std::move(__last), __pred, __proj); 64f8cbe3cdSNikolas Klauser } 65f8cbe3cdSNikolas Klauser 66f8cbe3cdSNikolas Klauser template <forward_range _Range, 67f8cbe3cdSNikolas Klauser class _Proj = identity, 68f8cbe3cdSNikolas Klauser indirect_unary_predicate<projected<iterator_t<_Range>, _Proj>> _Pred> 69f8cbe3cdSNikolas Klauser requires permutable<iterator_t<_Range>> 7083bc7b57SNikolas Klauser [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr borrowed_subrange_t<_Range> 715aa03b64SLouis Dionne operator()(_Range&& __range, _Pred __pred, _Proj __proj = {}) const { 72f8cbe3cdSNikolas Klauser return ranges::__remove_if_impl(ranges::begin(__range), ranges::end(__range), __pred, __proj); 73f8cbe3cdSNikolas Klauser } 74f8cbe3cdSNikolas Klauser }; 75f8cbe3cdSNikolas Klauser 76f8cbe3cdSNikolas Klauser inline namespace __cpo { 77*d10dc5a0SChristopher Di Bella inline constexpr auto remove_if = __remove_if{}; 78f8cbe3cdSNikolas Klauser } // namespace __cpo 79f8cbe3cdSNikolas Klauser } // namespace ranges 80f8cbe3cdSNikolas Klauser 81f8cbe3cdSNikolas Klauser _LIBCPP_END_NAMESPACE_STD 82f8cbe3cdSNikolas Klauser 834f15267dSNikolas Klauser #endif // _LIBCPP_STD_VER >= 20 84f8cbe3cdSNikolas Klauser 857b462251SLouis Dionne _LIBCPP_POP_MACROS 867b462251SLouis Dionne 87f8cbe3cdSNikolas Klauser #endif // _LIBCPP___ALGORITHM_RANGES_REMOVE_IF_H 88