Skip to content

Commit 4ef4041

Browse files
committed
[libc++] implement ranges::find_last
1 parent 028f1b0 commit 4ef4041

File tree

5 files changed

+87
-0
lines changed

5 files changed

+87
-0
lines changed

libcxx/include/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,7 @@ set(files
113113
__algorithm/ranges_find_first_of.h
114114
__algorithm/ranges_find_if.h
115115
__algorithm/ranges_find_if_not.h
116+
__algorithm/ranges_find_last.h
116117
__algorithm/ranges_for_each.h
117118
__algorithm/ranges_for_each_n.h
118119
__algorithm/ranges_generate.h
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
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

libcxx/include/algorithm

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2004,6 +2004,7 @@ template <class BidirectionalIterator, class Compare>
20042004
# include <__algorithm/fold.h>
20052005
# include <__algorithm/ranges_contains_subrange.h>
20062006
# include <__algorithm/ranges_ends_with.h>
2007+
# include <__algorithm/ranges_find_last.h>
20072008
# include <__algorithm/ranges_starts_with.h>
20082009
#endif // _LIBCPP_STD_VER >= 23
20092010

libcxx/include/module.modulemap

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -787,6 +787,7 @@ module std_private_algorithm_ranges_find_end [system
787787
module std_private_algorithm_ranges_find_first_of [system] { header "__algorithm/ranges_find_first_of.h" }
788788
module std_private_algorithm_ranges_find_if [system] { header "__algorithm/ranges_find_if.h" }
789789
module std_private_algorithm_ranges_find_if_not [system] { header "__algorithm/ranges_find_if_not.h" }
790+
module std_private_algorithm_ranges_find_last [system] { header "__algorithm/ranges_find_last.h" }
790791
module std_private_algorithm_ranges_for_each [system] {
791792
header "__algorithm/ranges_for_each.h"
792793
export std_private_algorithm_in_fun_result

llvm/utils/gn/secondary/libcxx/include/BUILD.gn

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,7 @@ if (current_toolchain == default_toolchain) {
183183
"__algorithm/ranges_find_first_of.h",
184184
"__algorithm/ranges_find_if.h",
185185
"__algorithm/ranges_find_if_not.h",
186+
"__algorithm/ranges_find_last.h",
186187
"__algorithm/ranges_for_each.h",
187188
"__algorithm/ranges_for_each_n.h",
188189
"__algorithm/ranges_generate.h",

0 commit comments

Comments
 (0)