Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions libcxx/include/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ set(files
__algorithm/ranges_find_first_of.h
__algorithm/ranges_find_if.h
__algorithm/ranges_find_if_not.h
__algorithm/ranges_find_last.h
__algorithm/ranges_for_each.h
__algorithm/ranges_for_each_n.h
__algorithm/ranges_generate.h
Expand Down
82 changes: 82 additions & 0 deletions libcxx/include/__algorithm/ranges_find_last.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#ifndef _LIBCPP___ALGORITHM_RANGES_FIND_LAST_H
#define _LIBCPP___ALGORITHM_RANGES_FIND_LAST_H

#include <__algorithm/ranges_find.h>
#include <__concepts/same_as.h>
#include <__config>
#include <__functional/identity.h>
#include <__functional/ranges_operations.h>
#include <__iterator/concepts.h>
#include <__iterator/projected.h>
#include <__iterator/reverse_iterator.h>
#include <__ranges/access.h>
#include <__ranges/concepts.h>
#include <__ranges/dangling.h>
#include <__ranges/subrange.h>
#include <__utility/move.h>

#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
#endif

_LIBCPP_PUSH_MACROS
#include <__undef_macros>

#if _LIBCPP_STD_VER >= 23

_LIBCPP_BEGIN_NAMESPACE_STD

namespace ranges {

namespace __find_last {
struct __fn {
template <forward_iterator _It, sentinel_for<_It> _Sent, typename _Tp, typename _Proj = identity>
requires indirect_binary_predicate<equal_to, projected<_It, _Proj>, const _Tp*>
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr subrange<_It>
operator()(_It __first, _Sent __last, const _Tp& __value, _Proj __proj = {}) const {
if constexpr (same_as<_It, _Sent> && bidirectional_iterator<_It>) {
const auto __found{find(reverse_iterator{__last}, reverse_iterator{__first}, __value, std::move(__proj)).base()};
if (__found == __first)
return {__last, __last};
return {prev(__found), __last};
} else {
auto __found{find(__first, __last, __value, __proj)};
if (__found == __last)
return {__last, __last};

for (__first = __found;; __found = __first++)
if ((__first == find(__first, __last, __value, __proj)) == __last)
return {__found, __last};
}
}

template <forward_range _Range, typename _Tp, typename _Proj = identity>
requires indirect_binary_predicate<equal_to, projected<iterator_t<_Range>, _Proj>, const _Tp*>
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr borrowed_subrange_t<_Range>
operator()(_Range&& __r, const _Tp& __value, _Proj __proj = {}) const {
return this->operator()(begin(__r), end(__r), __value, std::move(__proj));
}
};

} // namespace __find_last

inline namespace __cpo {
inline constexpr __find_last::__fn find_last{};
} // namespace __cpo
} // namespace ranges

_LIBCPP_END_NAMESPACE_STD

#endif // _LIBCPP_STD_VER >= 23

_LIBCPP_POP_MACROS

#endif // _LIBCPP___ALGORITHM_RANGES_FIND_LAST_H
1 change: 1 addition & 0 deletions libcxx/include/algorithm
Original file line number Diff line number Diff line change
Expand Up @@ -2004,6 +2004,7 @@ template <class BidirectionalIterator, class Compare>
# include <__algorithm/fold.h>
# include <__algorithm/ranges_contains_subrange.h>
# include <__algorithm/ranges_ends_with.h>
# include <__algorithm/ranges_find_last.h>
# include <__algorithm/ranges_starts_with.h>
#endif // _LIBCPP_STD_VER >= 23

Expand Down
1 change: 1 addition & 0 deletions libcxx/include/module.modulemap
Original file line number Diff line number Diff line change
Expand Up @@ -787,6 +787,7 @@ module std_private_algorithm_ranges_find_end [system
module std_private_algorithm_ranges_find_first_of [system] { header "__algorithm/ranges_find_first_of.h" }
module std_private_algorithm_ranges_find_if [system] { header "__algorithm/ranges_find_if.h" }
module std_private_algorithm_ranges_find_if_not [system] { header "__algorithm/ranges_find_if_not.h" }
module std_private_algorithm_ranges_find_last [system] { header "__algorithm/ranges_find_last.h" }
module std_private_algorithm_ranges_for_each [system] {
header "__algorithm/ranges_for_each.h"
export std_private_algorithm_in_fun_result
Expand Down
1 change: 1 addition & 0 deletions llvm/utils/gn/secondary/libcxx/include/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,7 @@ if (current_toolchain == default_toolchain) {
"__algorithm/ranges_find_first_of.h",
"__algorithm/ranges_find_if.h",
"__algorithm/ranges_find_if_not.h",
"__algorithm/ranges_find_last.h",
"__algorithm/ranges_for_each.h",
"__algorithm/ranges_for_each_n.h",
"__algorithm/ranges_generate.h",
Expand Down