[libcxx] [llvm] [libc++] ranges::find_last (PR #91086)

via llvm-commits llvm-commits at lists.llvm.org
Sat May 4 14:25:55 PDT 2024


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-libcxx

Author: Andrew Sukach (soukatch)

<details>
<summary>Changes</summary>

Implemented ranges::find_last. First time contributing to libc++, so let me know if you have any suggestions. Thanks!

---
Full diff: https://github.com/llvm/llvm-project/pull/91086.diff


5 Files Affected:

- (modified) libcxx/include/CMakeLists.txt (+1) 
- (added) libcxx/include/__algorithm/ranges_find_last.h (+83) 
- (modified) libcxx/include/algorithm (+1) 
- (modified) libcxx/include/module.modulemap (+1) 
- (modified) llvm/utils/gn/secondary/libcxx/include/BUILD.gn (+1) 


``````````diff
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..b656d3b3e732ff
--- /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
\ No newline at end of file
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",

``````````

</details>


https://github.com/llvm/llvm-project/pull/91086


More information about the llvm-commits mailing list