[gcc(refs/users/ppalka/heads/libstdcxx-constrained-algos)] Optimize ranges::adjacent_find to apply each projection exactly once

Patrick Palka ppalka@gcc.gnu.org
Fri Jan 17 21:44:00 GMT 2020


https://gcc.gnu.org/g:202b9b73ad39e88df945d775e5f4c8dc90defed1

commit 202b9b73ad39e88df945d775e5f4c8dc90defed1
Author: Patrick Palka <ppalka@gcc.gnu.org>
Date:   Fri Jan 17 12:53:46 2020 -0500

    Optimize ranges::adjacent_find to apply each projection exactly once

Diff:
---
 libstdc++-v3/include/bits/ranges_algo.h                   |  7 ++++---
 .../testsuite/25_algorithms/adjacent_find/constrained.cc  | 15 +++++++++++++++
 2 files changed, 19 insertions(+), 3 deletions(-)

diff --git a/libstdc++-v3/include/bits/ranges_algo.h b/libstdc++-v3/include/bits/ranges_algo.h
index 0c53a54..8bb9bfa 100644
--- a/libstdc++-v3/include/bits/ranges_algo.h
+++ b/libstdc++-v3/include/bits/ranges_algo.h
@@ -512,13 +512,14 @@ namespace ranges
 	if (__first == __last)
 	  return __last;
 	auto __next = __first;
+	auto __proj_first = std::__invoke(__proj, *__first);
 	while (++__next != __last)
 	  {
-	    if (std::__invoke(__pred,
-			      std::__invoke(__proj, *__first),
-			      std::__invoke(__proj, *__next)))
+	    auto __proj_next = std::__invoke(__proj, *__next);
+	    if (std::__invoke(__pred, std::move(__proj_first), __proj_next))
 	      return __first;
 	    __first = __next;
+	    __proj_first = std::move(__proj_next);
 	  }
 	return __last;
       }
diff --git a/libstdc++-v3/testsuite/25_algorithms/adjacent_find/constrained.cc b/libstdc++-v3/testsuite/25_algorithms/adjacent_find/constrained.cc
index d56ac5a..36ce9b7 100644
--- a/libstdc++-v3/testsuite/25_algorithms/adjacent_find/constrained.cc
+++ b/libstdc++-v3/testsuite/25_algorithms/adjacent_find/constrained.cc
@@ -59,10 +59,25 @@ test02()
   static_assert(ranges::adjacent_find(y, {}, &X::i) == y+5);
 }
 
+void
+test03()
+{
+  static int proj_counter;
+  auto my_proj = [] (int x)
+  {
+    proj_counter++;
+    return x;
+  };
+  int x[] = { 1, 2, 3, 4, 4 };
+  ranges::adjacent_find(x, {}, my_proj);
+  VERIFY( proj_counter == 5 );
+}
+
 int
 main()
 {
   test01();
   test02();
+  test03();
 }



More information about the Libstdc++-cvs mailing list