[libcxx-commits] [libcxx] [libc++][ranges] P1223R5: `find_last` (PR #99312)
Louis Dionne via libcxx-commits
libcxx-commits at lists.llvm.org
Thu Jul 18 12:56:29 PDT 2024
================
@@ -0,0 +1,175 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 <__config>
+#include <__functional/identity.h>
+#include <__functional/invoke.h>
+#include <__functional/ranges_operations.h>
+#include <__iterator/concepts.h>
+#include <__iterator/indirectly_comparable.h>
+#include <__iterator/next.h>
+#include <__iterator/prev.h>
+#include <__iterator/projected.h>
+#include <__ranges/access.h>
+#include <__ranges/concepts.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 {
+
+template <class _Iter, class _Sent, class _Pred, class _Proj>
+_LIBCPP_HIDE_FROM_ABI constexpr static subrange<_Iter>
+__find_last_impl(_Iter __first, _Sent __last, _Pred __pred, _Proj& __proj) {
+ if (__first == __last) {
+ return subrange<_Iter>(__first, __first);
+ }
+
+ if constexpr (bidirectional_iterator<_Iter>) {
----------------
ldionne wrote:
In case of an iterator that is bidirectional but where `ranges::next(iterator, sentinel)` is `O(N)`, this is potentially wasteful. We will first walk all the way to `__last` inside `ranges::next`, and then walk back until we find something that satisfies the predicate.
Writing this, I realize that the alternative is not necessarily better -- if you search from the start, then you potentially call the predicate all the way from the beginning. This depends on whether we expect the predicate to generally match near the end of the sequence or not.
I think it's a fair assumption to optimize this for finding stuff near the end of the sequence. So no change required, I was just thinking out loud.
https://github.com/llvm/llvm-project/pull/99312
More information about the libcxx-commits
mailing list