[libcxx-commits] [libcxx] [libc++] Tiny optimizations for is_permutation (PR #129565)

Louis Dionne via libcxx-commits libcxx-commits at lists.llvm.org
Thu Mar 20 12:16:50 PDT 2025


================
@@ -79,31 +83,31 @@ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool __is_permutation_impl(
     _Proj1&& __proj1,
     _Proj2&& __proj2) {
   using _D1 = __iter_diff_t<_Iter1>;
+  using _Ref1 = typename iterator_traits<_Iter1>::reference;
+  using _Ref2 = typename iterator_traits<_Iter2>::reference;
+  __identity __ident;
 
   for (auto __i = __first1; __i != __last1; ++__i) {
     //  Have we already counted the number of *__i in [f1, l1)?
-    auto __match = __first1;
-    for (; __match != __i; ++__match) {
-      if (std::__invoke(__pred, std::__invoke(__proj1, *__match), std::__invoke(__proj1, *__i)))
-        break;
-    }
+    auto __match = std::find_if(__first1, __i, [&](_Ref1 __x) -> bool {
+      return std::__invoke(__pred, std::__invoke(__proj1, __x), std::__invoke(__proj1, *__i));
+    });
 
     if (__match == __i) {
       // Count number of *__i in [f2, l2)
-      _D1 __c2 = 0;
-      for (auto __j = __first2; __j != __last2; ++__j) {
-        if (std::__invoke(__pred, std::__invoke(__proj1, *__i), std::__invoke(__proj2, *__j)))
-          ++__c2;
-      }
+      auto __predicate2 = [&](_Ref2 __x) -> bool {
+        return std::__invoke(__pred, std::__invoke(__proj1, *__i), std::__invoke(__proj2, __x));
+      };
+      _D1 __c2 = std::__count_if<_AlgPolicy>(__first2, __last2, __predicate2, __ident);
----------------
ldionne wrote:

Ugh, it's one of those places where we take an lvalue reference to the predicate. We should fix that, but I agree for the time being you can disregard my suggestion.

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


More information about the libcxx-commits mailing list