1b79b2b67SNikolas Klauser //===----------------------------------------------------------------------===// 2b79b2b67SNikolas Klauser // 3b79b2b67SNikolas Klauser // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4b79b2b67SNikolas Klauser // See https://llvm.org/LICENSE.txt for license information. 5b79b2b67SNikolas Klauser // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6b79b2b67SNikolas Klauser // 7b79b2b67SNikolas Klauser //===----------------------------------------------------------------------===// 8b79b2b67SNikolas Klauser 9b79b2b67SNikolas Klauser #ifndef _LIBCPP___ALGORITHM_RANGES_FIND_FIRST_OF_H 10b79b2b67SNikolas Klauser #define _LIBCPP___ALGORITHM_RANGES_FIND_FIRST_OF_H 11b79b2b67SNikolas Klauser 12b79b2b67SNikolas Klauser #include <__config> 13b79b2b67SNikolas Klauser #include <__functional/identity.h> 14b79b2b67SNikolas Klauser #include <__functional/invoke.h> 15b79b2b67SNikolas Klauser #include <__functional/ranges_operations.h> 16b79b2b67SNikolas Klauser #include <__iterator/concepts.h> 17b79b2b67SNikolas Klauser #include <__iterator/indirectly_comparable.h> 18b79b2b67SNikolas Klauser #include <__ranges/access.h> 19b79b2b67SNikolas Klauser #include <__ranges/concepts.h> 20b79b2b67SNikolas Klauser #include <__ranges/dangling.h> 21b79b2b67SNikolas Klauser #include <__utility/move.h> 22b79b2b67SNikolas Klauser 23b79b2b67SNikolas Klauser #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 24b79b2b67SNikolas Klauser # pragma GCC system_header 25b79b2b67SNikolas Klauser #endif 26b79b2b67SNikolas Klauser 277b462251SLouis Dionne _LIBCPP_PUSH_MACROS 287b462251SLouis Dionne #include <__undef_macros> 297b462251SLouis Dionne 304f15267dSNikolas Klauser #if _LIBCPP_STD_VER >= 20 31b79b2b67SNikolas Klauser 32b79b2b67SNikolas Klauser _LIBCPP_BEGIN_NAMESPACE_STD 33b79b2b67SNikolas Klauser 34b79b2b67SNikolas Klauser namespace ranges { 35*d10dc5a0SChristopher Di Bella struct __find_first_of { 36b79b2b67SNikolas Klauser template <class _Iter1, class _Sent1, class _Iter2, class _Sent2, class _Pred, class _Proj1, class _Proj2> 375aa03b64SLouis Dionne _LIBCPP_HIDE_FROM_ABI constexpr static _Iter1 __find_first_of_impl( 385aa03b64SLouis Dionne _Iter1 __first1, 395aa03b64SLouis Dionne _Sent1 __last1, 405aa03b64SLouis Dionne _Iter2 __first2, 415aa03b64SLouis Dionne _Sent2 __last2, 42b79b2b67SNikolas Klauser _Pred& __pred, 43b79b2b67SNikolas Klauser _Proj1& __proj1, 44b79b2b67SNikolas Klauser _Proj2& __proj2) { 45b79b2b67SNikolas Klauser for (; __first1 != __last1; ++__first1) { 46b79b2b67SNikolas Klauser for (auto __j = __first2; __j != __last2; ++__j) { 47b79b2b67SNikolas Klauser if (std::invoke(__pred, std::invoke(__proj1, *__first1), std::invoke(__proj2, *__j))) 48b79b2b67SNikolas Klauser return __first1; 49b79b2b67SNikolas Klauser } 50b79b2b67SNikolas Klauser } 51b79b2b67SNikolas Klauser return __first1; 52b79b2b67SNikolas Klauser } 53b79b2b67SNikolas Klauser 545aa03b64SLouis Dionne template <input_iterator _Iter1, 555aa03b64SLouis Dionne sentinel_for<_Iter1> _Sent1, 565aa03b64SLouis Dionne forward_iterator _Iter2, 575aa03b64SLouis Dionne sentinel_for<_Iter2> _Sent2, 58b79b2b67SNikolas Klauser class _Pred = ranges::equal_to, 59b79b2b67SNikolas Klauser class _Proj1 = identity, 60b79b2b67SNikolas Klauser class _Proj2 = identity> 61b79b2b67SNikolas Klauser requires indirectly_comparable<_Iter1, _Iter2, _Pred, _Proj1, _Proj2> 6283bc7b57SNikolas Klauser [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _Iter1 operator()( 635aa03b64SLouis Dionne _Iter1 __first1, 645aa03b64SLouis Dionne _Sent1 __last1, 655aa03b64SLouis Dionne _Iter2 __first2, 665aa03b64SLouis Dionne _Sent2 __last2, 67b79b2b67SNikolas Klauser _Pred __pred = {}, 68b79b2b67SNikolas Klauser _Proj1 __proj1 = {}, 69b79b2b67SNikolas Klauser _Proj2 __proj2 = {}) const { 705aa03b64SLouis Dionne return __find_first_of_impl( 715aa03b64SLouis Dionne std::move(__first1), std::move(__last1), std::move(__first2), std::move(__last2), __pred, __proj1, __proj2); 72b79b2b67SNikolas Klauser } 73b79b2b67SNikolas Klauser 74b79b2b67SNikolas Klauser template <input_range _Range1, 75b79b2b67SNikolas Klauser forward_range _Range2, 76b79b2b67SNikolas Klauser class _Pred = ranges::equal_to, 77b79b2b67SNikolas Klauser class _Proj1 = identity, 78b79b2b67SNikolas Klauser class _Proj2 = identity> 79b79b2b67SNikolas Klauser requires indirectly_comparable<iterator_t<_Range1>, iterator_t<_Range2>, _Pred, _Proj1, _Proj2> 8083bc7b57SNikolas Klauser [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr borrowed_iterator_t<_Range1> operator()( 815aa03b64SLouis Dionne _Range1&& __range1, _Range2&& __range2, _Pred __pred = {}, _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const { 825aa03b64SLouis Dionne return __find_first_of_impl( 835aa03b64SLouis Dionne ranges::begin(__range1), 845aa03b64SLouis Dionne ranges::end(__range1), 855aa03b64SLouis Dionne ranges::begin(__range2), 865aa03b64SLouis Dionne ranges::end(__range2), 87b79b2b67SNikolas Klauser __pred, 88b79b2b67SNikolas Klauser __proj1, 89b79b2b67SNikolas Klauser __proj2); 90b79b2b67SNikolas Klauser } 91b79b2b67SNikolas Klauser }; 92b79b2b67SNikolas Klauser 93b79b2b67SNikolas Klauser inline namespace __cpo { 94*d10dc5a0SChristopher Di Bella inline constexpr auto find_first_of = __find_first_of{}; 95b79b2b67SNikolas Klauser } // namespace __cpo 96b79b2b67SNikolas Klauser } // namespace ranges 97b79b2b67SNikolas Klauser 98b79b2b67SNikolas Klauser _LIBCPP_END_NAMESPACE_STD 99b79b2b67SNikolas Klauser 1004f15267dSNikolas Klauser #endif // _LIBCPP_STD_VER >= 20 101b79b2b67SNikolas Klauser 1027b462251SLouis Dionne _LIBCPP_POP_MACROS 1037b462251SLouis Dionne 104b79b2b67SNikolas Klauser #endif // _LIBCPP___ALGORITHM_RANGES_FIND_FIRST_OF_H 105