Skip to content

Commit faf7890

Browse files
committed
Algorithms for ranges_find_last, find_last_if, and find_last_if_not
1 parent b13df77 commit faf7890

File tree

3 files changed

+217
-0
lines changed

3 files changed

+217
-0
lines changed

libcxx/include/__algorithm/ranges_find_last.h

+55
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#include <__functional/invoke.h>
1515
#include <__functional/ranges_operations.h>
1616
#include <__iterator/concepts.h>
17+
<<<<<<< HEAD
1718
#include <__iterator/indirectly_comparable.h>
1819
#include <__iterator/next.h>
1920
#include <__iterator/prev.h>
@@ -23,6 +24,15 @@
2324
#include <__ranges/subrange.h>
2425
#include <__utility/forward.h>
2526
#include <__utility/move.h>
27+
=======
28+
#include <__iterator/projected.h>
29+
#include <__ranges/access.h>
30+
#include <__ranges/concepts.h>
31+
#include <__ranges/dangling.h>
32+
#include <__utility/forward.h>
33+
#include <__utility/move.h>
34+
#include <optional>
35+
>>>>>>> cfed7b885225 (Algorithms for ranges_find_last, find_last_if, and find_last_if_not)
2636

2737
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
2838
# pragma GCC system_header
@@ -31,12 +41,17 @@
3141
_LIBCPP_PUSH_MACROS
3242
#include <__undef_macros>
3343

44+
<<<<<<< HEAD
3445
#if _LIBCPP_STD_VER >= 23
46+
=======
47+
#if _LIBCPP_STD_VER >= 20
48+
>>>>>>> cfed7b885225 (Algorithms for ranges_find_last, find_last_if, and find_last_if_not)
3549

3650
_LIBCPP_BEGIN_NAMESPACE_STD
3751

3852
namespace ranges {
3953

54+
<<<<<<< HEAD
4055
template <class _Iter, class _Sent, class _Pred, class _Proj>
4156
_LIBCPP_HIDE_FROM_ABI constexpr subrange<_Iter>
4257
__find_last_impl(_Iter __first, _Sent __last, _Pred __pred, _Proj& __proj) {
@@ -159,11 +174,51 @@ inline constexpr auto find_last = __find_last{};
159174
inline constexpr auto find_last_if = __find_last_if{};
160175
inline constexpr auto find_last_if_not = __find_last_if_not{};
161176
} // namespace __cpo
177+
=======
178+
namespace __find_last {
179+
180+
struct __fn {
181+
template <forward_iterator _Ip, sentinel_for<_Ip> _Sp, class _Tp, class _Proj = identity>
182+
requires indirect_binary_predicate<ranges::equal_to, projected<_Ip, _Proj>, const _Tp*>
183+
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr subrange<_Ip>
184+
operator()(_Ip __first, _Sp __last, const _Tp& __value, _Proj __proj = {}) const {
185+
std::optional<_Ip> __found;
186+
for (; __first != __last; ++__first) {
187+
if (std::invoke(__proj, *__first) == __value) {
188+
__found = __first;
189+
}
190+
}
191+
if (!__found)
192+
return {__first, __first};
193+
return {*__found, std::ranges::next(*__found, __last)};
194+
}
195+
196+
template <forward_range _Rp, class _Tp, class _Proj = identity>
197+
requires indirect_binary_predicate<ranges::equal_to, projected<iterator_t<_Rp>, _Proj>, const _Tp*>
198+
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr borrowed_subrange_t<_Rp>
199+
operator()(_Rp&& __r, const _Tp& __value, _Proj __proj = {}) const {
200+
return this->operator()(ranges::begin(__r), ranges::end(__r), __value, std::ref(__proj));
201+
}
202+
};
203+
204+
} // namespace __find_last
205+
206+
inline namespace __cpo {
207+
inline constexpr auto find_last = __find_last::__fn{};
208+
inline constexpr auto find_last_if = __find_last::__fn{};
209+
inline constexpr auto find_last_if_not = __find_last::__fn{};
210+
} // namespace __cpo
211+
212+
>>>>>>> cfed7b885225 (Algorithms for ranges_find_last, find_last_if, and find_last_if_not)
162213
} // namespace ranges
163214

164215
_LIBCPP_END_NAMESPACE_STD
165216

217+
<<<<<<< HEAD
166218
#endif // _LIBCPP_STD_VER >= 23
219+
=======
220+
#endif // _LIBCPP_STD_VER >= 20
221+
>>>>>>> cfed7b885225 (Algorithms for ranges_find_last, find_last_if, and find_last_if_not)
167222

168223
_LIBCPP_POP_MACROS
169224

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
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_IF_H
10+
#define _LIBCPP___ALGORITHM_RANGES_FIND_LAST_IF_H
11+
12+
#include <__config>
13+
#include <__functional/identity.h>
14+
#include <__functional/invoke.h>
15+
#include <__functional/ranges_operations.h>
16+
#include <__iterator/concepts.h>
17+
#include <__iterator/projected.h>
18+
#include <__ranges/access.h>
19+
#include <__ranges/concepts.h>
20+
#include <__ranges/dangling.h>
21+
#include <__utility/forward.h>
22+
#include <__utility/move.h>
23+
#include <optional>
24+
25+
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
26+
# pragma GCC system_header
27+
#endif
28+
29+
_LIBCPP_PUSH_MACROS
30+
#include <__undef_macros>
31+
32+
#if _LIBCPP_STD_VER >= 20
33+
34+
_LIBCPP_BEGIN_NAMESPACE_STD
35+
36+
namespace ranges {
37+
38+
namespace __find_last_if {
39+
40+
struct __fn {
41+
template <forward_iterator _Ip,
42+
sentinel_for<_Ip> _Sp,
43+
class _Proj = identity,
44+
indirect_unary_predicate<projected<_Ip, _Proj>> _Pred>
45+
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr subrange<_Ip>
46+
operator()(_Ip __first, _Sp __last, _Pred __pred, _Proj __proj = {}) const {
47+
std::optional<_Ip> __found;
48+
for (; __first != __last; ++__first) {
49+
if (std::invoke(__pred, std::invoke(__proj, *__first))) {
50+
__found = __first;
51+
}
52+
}
53+
if (!__found)
54+
return {__first, __first};
55+
return {*__found, std::ranges::next(*__found, __last)};
56+
}
57+
58+
template <forward_range _Rp,
59+
class _Proj = identity,
60+
indirect_unary_predicate<projected<iterator_t<_Rp>, _Proj>> _Pred>
61+
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr borrowed_subrange_t<_Rp>
62+
operator()(_Rp&& __r, _Pred __pred, _Proj __proj = {}) const {
63+
return this->operator()(ranges::begin(__r), ranges::end(__r), std::ref(__pred), std::ref(__proj));
64+
}
65+
};
66+
67+
} // namespace __find_last_if
68+
69+
inline namespace __cpo {
70+
inline constexpr auto find_last_if = __find_last_if::__fn{};
71+
} // namespace __cpo
72+
73+
} // namespace ranges
74+
75+
_LIBCPP_END_NAMESPACE_STD
76+
77+
#endif // _LIBCPP_STD_VER >= 20
78+
79+
_LIBCPP_POP_MACROS
80+
81+
#endif // _LIBCPP___ALGORITHM_RANGES_FIND_LAST_IF_H
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
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_IF_NOT_H
10+
#define _LIBCPP___ALGORITHM_RANGES_FIND_LAST_IF_NOT_H
11+
12+
#include <__config>
13+
#include <__functional/identity.h>
14+
#include <__functional/invoke.h>
15+
#include <__functional/ranges_operations.h>
16+
#include <__iterator/concepts.h>
17+
#include <__iterator/projected.h>
18+
#include <__ranges/access.h>
19+
#include <__ranges/concepts.h>
20+
#include <__ranges/dangling.h>
21+
#include <__utility/forward.h>
22+
#include <__utility/move.h>
23+
#include <optional>
24+
25+
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
26+
# pragma GCC system_header
27+
#endif
28+
29+
_LIBCPP_PUSH_MACROS
30+
#include <__undef_macros>
31+
32+
#if _LIBCPP_STD_VER >= 20
33+
34+
_LIBCPP_BEGIN_NAMESPACE_STD
35+
36+
namespace ranges {
37+
38+
namespace __find_last_if_not {
39+
40+
struct __fn {
41+
template <forward_iterator _Ip,
42+
sentinel_for<_Ip> _Sp,
43+
class _Proj = identity,
44+
indirect_unary_predicate<projected<_Ip, _Proj>> _Pred>
45+
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr subrange<_Ip>
46+
operator()(_Ip __first, _Sp __last, _Pred __pred, _Proj __proj = {}) const {
47+
std::optional<_Ip> __found;
48+
for (; __first != __last; ++__first) {
49+
if (!std::invoke(__pred, std::invoke(__proj, *__first))) {
50+
__found = __first;
51+
}
52+
}
53+
if (!__found)
54+
return {__first, __first};
55+
return {*__found, std::ranges::next(*__found, __last)};
56+
}
57+
58+
template <forward_range _Rp,
59+
class _Proj = identity,
60+
indirect_unary_predicate<projected<iterator_t<_Rp>, _Proj>> _Pred>
61+
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr borrowed_subrange_t<_Rp>
62+
operator()(_Rp&& __r, _Pred __pred, _Proj __proj = {}) const {
63+
return this->operator()(ranges::begin(__r), ranges::end(__r), std::ref(__pred), std::ref(__proj));
64+
}
65+
};
66+
67+
} // namespace __find_last_if_not
68+
69+
inline namespace __cpo {
70+
inline constexpr auto find_last_if_not = __find_last_if_not::__fn{};
71+
} // namespace __cpo
72+
73+
} // namespace ranges
74+
75+
_LIBCPP_END_NAMESPACE_STD
76+
77+
#endif // _LIBCPP_STD_VER >= 20
78+
79+
_LIBCPP_POP_MACROS
80+
81+
#endif // _LIBCPP___ALGORITHM_RANGES_FIND_LAST_IF_NOT_H

0 commit comments

Comments
 (0)