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_RANGES_FIND_LAST_H
10+ #define _LIBCPP___ALGORITHM_RANGES_FIND_LAST_H
11+
12+ #include < __algorithm/ranges_find.h>
13+ #include < __config>
14+ #include < __functional/identity.h>
15+ #include < __functional/invoke.h>
16+ #include < __functional/ranges_operations.h>
17+ #include < __iterator/concepts.h>
18+ #include < __iterator/projected.h>
19+ #include < __iterator/reverse_iterator.h>
20+ #include < __ranges/access.h>
21+ #include < __ranges/concepts.h>
22+ #include < __ranges/dangling.h>
23+ #include < __ranges/subrange.h>
24+ #include < __utility/forward.h>
25+ #include < __utility/move.h>
26+
27+ #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
28+ # pragma GCC system_header
29+ #endif
30+
31+ _LIBCPP_PUSH_MACROS
32+ #include < __undef_macros>
33+
34+ #if _LIBCPP_STD_VER >= 23
35+
36+ _LIBCPP_BEGIN_NAMESPACE_STD
37+
38+ namespace ranges {
39+
40+ namespace __find_last {
41+ struct __fn {
42+ template <forward_iterator _It, sentinel_for<_It> _Sent, typename _Tp, typename _Proj = identity>
43+ requires indirect_binary_predicate<equal_to, projected<_It, _Proj>, const _Tp*>
44+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr subrange<_It>
45+ operator ()(_It __first, _Sent __last, const _Tp& __value, _Proj __proj = {}) const {
46+ if constexpr (same_as<_It, _Sent> && bidirectional_iterator<_It>) {
47+ const auto __found{find (reverse_iterator{__last}, reverse_iterator{__first}, __value, std::move (__proj)).base ()};
48+ if (__found == __first)
49+ return {__last, __last};
50+ return {prev (__found), __last};
51+ } else {
52+ auto __found{find (__first, __last, __value, __proj)};
53+ if (__found == __last)
54+ return {__last, __last};
55+
56+ for (__first = __found;; __found = __first++)
57+ if ((__first == find (__first, __last, __value, __proj)) == __last)
58+ return {__found, __last};
59+ }
60+ }
61+
62+ template <forward_range _Range, typename _Tp, typename _Proj = identity>
63+ requires indirect_binary_predicate<equal_to, projected<iterator_t <_Range>, _Proj>, const _Tp*>
64+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr borrowed_subrange_t <_Range>
65+ operator ()(_Range&& __r, const _Tp& __value, _Proj __proj = {}) const {
66+ return this ->operator ()(begin (__r), end (__r), __value, std::move (__proj));
67+ }
68+ };
69+
70+ } // namespace __find_last
71+
72+ inline namespace __cpo {
73+ inline constexpr __find_last::__fn find_last{};
74+ } // namespace __cpo
75+ } // namespace ranges
76+
77+ _LIBCPP_END_NAMESPACE_STD
78+
79+ #endif // _LIBCPP_STD_VER >= 23
80+
81+ _LIBCPP_POP_MACROS
82+
83+ #endif // _LIBCPP___ALGORITHM_RANGES_FIND_LAST_H
0 commit comments