[libcxx-commits] [libcxx] [libc++] implement ranges::find_last (PR #91081)

via libcxx-commits libcxx-commits at lists.llvm.org
Sat May 4 12:32:42 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/91081.diff


3 Files Affected:

- (modified) libcxx/include/CMakeLists.txt (+1) 
- (added) libcxx/include/__algorithm/ranges_find_last.h (+81) 
- (modified) libcxx/include/algorithm (+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..485069dcaa771c
--- /dev/null
+++ b/libcxx/include/__algorithm/ranges_find_last.h
@@ -0,0 +1,81 @@
+//===----------------------------------------------------------------------===//
+//
+// 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_if.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 <__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 {
+
+template <typename _I, typename _S, typename _T, typename _P>
+_LIBCPP_HIDE_FROM_ABI constexpr subrange<_I> __find_last_impl(_I __first, _S __last, const _T& __value, _P& __proj) {
+  _I __ret{};
+  for (; __first != __last; ++__first)
+    if (std::invoke(__proj, *__first) == __value)
+      __ret = __first;
+
+  if (__ret == _I{})
+    return {__first, __first};
+
+  return {__ret, std::ranges::next(__ret, __last)};
+}
+
+namespace __find_last {
+struct __fn {
+  template <forward_iterator _I, sentinel_for<_I> _S, typename _T, typename _Proj = identity>
+    requires indirect_binary_predicate<equal_to, projected<_I, _Proj>, const _T*>
+  [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr subrange<_I>
+  operator()(_I __first, _S __last, const _T& __value, _Proj __proj = {}) const {
+    return __find_last_impl(std::move(__first), std::move(__last), __value, __proj);
+  }
+
+  template <forward_range _R, typename _T, typename _P = identity>
+    requires indirect_binary_predicate<equal_to, projected<iterator_t<_R>, _P>, const _T*>
+  constexpr ranges::borrowed_subrange_t<_R> operator()(_R&& __r, const _T& __value, _P __proj = {}) const {
+    return this->operator()(begin(__r), end(__r), __value, ref(__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
 

``````````

</details>


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


More information about the libcxx-commits mailing list