[libcxx-commits] [libcxx] [libc++] Remove projection from __lower_bound_onesided (PR #206676)

Nikolas Klauser via libcxx-commits libcxx-commits at lists.llvm.org
Tue Jun 30 01:17:18 PDT 2026


https://github.com/philnik777 created https://github.com/llvm/llvm-project/pull/206676

The projection argument isn't made use of very much, since it's only ever called with an identity. We can remove it to simplify the code a bit.


>From d28a6c01ebd475703cdc7c89e4c1653645cd93b3 Mon Sep 17 00:00:00 2001
From: Nikolas Klauser <nikolasklauser at berlin.de>
Date: Tue, 30 Jun 2026 10:10:31 +0200
Subject: [PATCH] [libc++] Remove projection from __lower_bound_onesided

---
 libcxx/include/__algorithm/lower_bound.h      | 9 +++++----
 libcxx/include/__algorithm/set_intersection.h | 7 ++-----
 2 files changed, 7 insertions(+), 9 deletions(-)

diff --git a/libcxx/include/__algorithm/lower_bound.h b/libcxx/include/__algorithm/lower_bound.h
index 4fba6748e6d71..aa1d4c4744452 100644
--- a/libcxx/include/__algorithm/lower_bound.h
+++ b/libcxx/include/__algorithm/lower_bound.h
@@ -56,11 +56,11 @@ template <class _AlgPolicy, class _Iter, class _Type, class _Proj, class _Comp>
 // would yield \Omega(n*log(n)) comparisons and, for non-random-access iterators, \Omega(n^2) iterator increments,
 // whereas the one-sided version will yield O(n) operations on both counts, with a \Omega(log(n)) bound on the number of
 // comparisons.
-template <class _AlgPolicy, class _ForwardIterator, class _Sent, class _Type, class _Proj, class _Comp>
+template <class _AlgPolicy, class _ForwardIterator, class _Sent, class _Type, class _Comp>
 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator
-__lower_bound_onesided(_ForwardIterator __first, _Sent __last, const _Type& __value, _Comp& __comp, _Proj& __proj) {
+__lower_bound_onesided(_ForwardIterator __first, _Sent __last, const _Type& __value, _Comp& __comp) {
   // step = 0, ensuring we can always short-circuit when distance is 1 later on
-  if (__first == __last || !std::__invoke(__comp, std::__invoke(__proj, *__first), __value))
+  if (__first == __last || !std::__invoke(__comp, *__first, __value))
     return __first;
 
   using _Distance = typename iterator_traits<_ForwardIterator>::difference_type;
@@ -69,11 +69,12 @@ __lower_bound_onesided(_ForwardIterator __first, _Sent __last, const _Type& __va
     auto __dist = __step - _IterOps<_AlgPolicy>::__advance_to(__it, __step, __last);
     // once we reach the last range where needle can be we must start
     // looking inwards, bisecting that range
-    if (__it == __last || !std::__invoke(__comp, std::__invoke(__proj, *__it), __value)) {
+    if (__it == __last || !std::__invoke(__comp, *__it, __value)) {
       // we've already checked the previous value and it was less, we can save
       // one comparison by skipping bisection
       if (__dist == 1)
         return __it;
+      __identity __proj;
       return std::__lower_bound_bisecting<_AlgPolicy>(__first, __value, __dist, __comp, __proj);
     }
     // range not found, move forward!
diff --git a/libcxx/include/__algorithm/set_intersection.h b/libcxx/include/__algorithm/set_intersection.h
index 6246e24b9ca4e..d048b5fe08e62 100644
--- a/libcxx/include/__algorithm/set_intersection.h
+++ b/libcxx/include/__algorithm/set_intersection.h
@@ -96,12 +96,10 @@ __set_intersection(
     _Compare&& __comp,
     std::forward_iterator_tag,
     std::forward_iterator_tag) {
-  _LIBCPP_CONSTEXPR std::__identity __proj;
   bool __prev_may_be_equal = false;
 
   while (__first2 != __last2) {
-    _InForwardIter1 __first1_next =
-        std::__lower_bound_onesided<_AlgPolicy>(__first1, __last1, *__first2, __comp, __proj);
+    _InForwardIter1 __first1_next = std::__lower_bound_onesided<_AlgPolicy>(__first1, __last1, *__first2, __comp);
     std::swap(__first1_next, __first1);
     // keeping in mind that a==b iff !(a<b) && !(b<a):
     // if we can't advance __first1, that means !(*__first1 < *_first2), therefore __may_be_equal==true
@@ -110,8 +108,7 @@ __set_intersection(
     if (__first1 == __last1)
       break;
 
-    _InForwardIter2 __first2_next =
-        std::__lower_bound_onesided<_AlgPolicy>(__first2, __last2, *__first1, __comp, __proj);
+    _InForwardIter2 __first2_next = std::__lower_bound_onesided<_AlgPolicy>(__first2, __last2, *__first1, __comp);
     std::swap(__first2_next, __first2);
     std::__set_intersection_add_output_if_equal(
         __first2 == __first2_next, __first1, __first2, __result, __prev_may_be_equal);



More information about the libcxx-commits mailing list