[libcxx] [llvm] [libc++] implement ranges::find_last (PR #91081)
Andrew Sukach via llvm-commits
llvm-commits at lists.llvm.org
Sat May 4 14:11:12 PDT 2024
https://github.com/soukatch updated https://github.com/llvm/llvm-project/pull/91081
>From 4ef4041a17fd8a06bebb959d6afdab105141c2ed Mon Sep 17 00:00:00 2001
From: Andrew Sukach <andrewsukach at gmail.com>
Date: Sat, 4 May 2024 15:30:06 -0400
Subject: [PATCH] [libc++] implement ranges::find_last
---
libcxx/include/CMakeLists.txt | 1 +
libcxx/include/__algorithm/ranges_find_last.h | 83 +++++++++++++++++++
libcxx/include/algorithm | 1 +
libcxx/include/module.modulemap | 1 +
.../gn/secondary/libcxx/include/BUILD.gn | 1 +
5 files changed, 87 insertions(+)
create mode 100644 libcxx/include/__algorithm/ranges_find_last.h
diff --git a/libcxx/include/CMakeLists.txt b/libcxx/include/CMakeLists.txt
index fd7eb125e007b6..56cce0a42ca771 100644
--- a/libcxx/include/CMakeLists.txt
+++ b/libcxx/include/CMakeLists.txt
@@ -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
diff --git a/libcxx/include/__algorithm/ranges_find_last.h b/libcxx/include/__algorithm/ranges_find_last.h
new file mode 100644
index 00000000000000..94413e673f0719
--- /dev/null
+++ b/libcxx/include/__algorithm/ranges_find_last.h
@@ -0,0 +1,83 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 <__config>
+#include <__functional/identity.h>
+#include <__functional/invoke.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/forward.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
diff --git a/libcxx/include/algorithm b/libcxx/include/algorithm
index 869fc19737b572..508579c75610a4 100644
--- a/libcxx/include/algorithm
+++ b/libcxx/include/algorithm
@@ -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
diff --git a/libcxx/include/module.modulemap b/libcxx/include/module.modulemap
index 2974d12500c4cb..f354bca3ca45b3 100644
--- a/libcxx/include/module.modulemap
+++ b/libcxx/include/module.modulemap
@@ -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
diff --git a/llvm/utils/gn/secondary/libcxx/include/BUILD.gn b/llvm/utils/gn/secondary/libcxx/include/BUILD.gn
index 9645bff18ae72b..789d03e66d3c37 100644
--- a/llvm/utils/gn/secondary/libcxx/include/BUILD.gn
+++ b/llvm/utils/gn/secondary/libcxx/include/BUILD.gn
@@ -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",
More information about the llvm-commits
mailing list