Skip to content

Commit 6ff792d

Browse files
committed
[libc++] ranges::find_last
1 parent 3cbfc9d commit 6ff792d

File tree

5 files changed

+86
-0
lines changed

5 files changed

+86
-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: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
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 <__concepts/same_as.h>
14+
#include <__config>
15+
#include <__functional/identity.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/move.h>
25+
26+
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
27+
# pragma GCC system_header
28+
#endif
29+
30+
_LIBCPP_PUSH_MACROS
31+
#include <__undef_macros>
32+
33+
#if _LIBCPP_STD_VER >= 23
34+
35+
_LIBCPP_BEGIN_NAMESPACE_STD
36+
37+
namespace ranges {
38+
39+
namespace __find_last {
40+
struct __fn {
41+
template <forward_iterator _It, sentinel_for<_It> _Sent, typename _Tp, typename _Proj = identity>
42+
requires indirect_binary_predicate<equal_to, projected<_It, _Proj>, const _Tp*>
43+
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr subrange<_It>
44+
operator()(_It __first, _Sent __last, const _Tp& __value, _Proj __proj = {}) const {
45+
if constexpr (same_as<_It, _Sent> && bidirectional_iterator<_It>) {
46+
const auto __found{find(reverse_iterator{__last}, reverse_iterator{__first}, __value, std::move(__proj)).base()};
47+
if (__found == __first)
48+
return {__last, __last};
49+
return {prev(__found), __last};
50+
} else {
51+
auto __found{find(__first, __last, __value, __proj)};
52+
if (__found == __last)
53+
return {__last, __last};
54+
55+
for (__first = __found;; __found = __first++)
56+
if ((__first == find(__first, __last, __value, __proj)) == __last)
57+
return {__found, __last};
58+
}
59+
}
60+
61+
template <forward_range _Range, typename _Tp, typename _Proj = identity>
62+
requires indirect_binary_predicate<equal_to, projected<iterator_t<_Range>, _Proj>, const _Tp*>
63+
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr borrowed_subrange_t<_Range>
64+
operator()(_Range&& __r, const _Tp& __value, _Proj __proj = {}) const {
65+
return this->operator()(begin(__r), end(__r), __value, std::move(__proj));
66+
}
67+
};
68+
69+
} // namespace __find_last
70+
71+
inline namespace __cpo {
72+
inline constexpr __find_last::__fn find_last{};
73+
} // namespace __cpo
74+
} // namespace ranges
75+
76+
_LIBCPP_END_NAMESPACE_STD
77+
78+
#endif // _LIBCPP_STD_VER >= 23
79+
80+
_LIBCPP_POP_MACROS
81+
82+
#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)