[gcc(refs/users/ppalka/heads/libstdcxx-constrained-algos)] Finish ranges::search_n

Patrick Palka ppalka@gcc.gnu.org
Sat Jan 18 04:46:00 GMT 2020


https://gcc.gnu.org/g:f779c0e10ea30e26d8b24db91917c3c54d576aef

commit f779c0e10ea30e26d8b24db91917c3c54d576aef
Author: Patrick Palka <ppalka@gcc.gnu.org>
Date:   Fri Jan 17 19:57:39 2020 -0500

    Finish ranges::search_n
    
    The non-modifying constrained algorithms are done!

Diff:
---
 libstdc++-v3/include/bits/ranges_algo.h            | 49 +++++++++++++++-------
 .../25_algorithms/search_n/constrained.cc          |  2 +-
 2 files changed, 36 insertions(+), 15 deletions(-)

diff --git a/libstdc++-v3/include/bits/ranges_algo.h b/libstdc++-v3/include/bits/ranges_algo.h
index 79ba19a..c63b2a1 100644
--- a/libstdc++-v3/include/bits/ranges_algo.h
+++ b/libstdc++-v3/include/bits/ranges_algo.h
@@ -445,25 +445,46 @@ namespace ranges
 	    }
 	}
 
-      __first = ranges::find_if(__first, __last, __value_comp, __proj);
-      while (__first != __last)
+      if constexpr (sized_sentinel_for<_Sent, _Iter>)
 	{
-	  auto __n = __count;
-	  auto __i = __first;
-	  ++__i;
-	  while (__i != __last && __n != 1
-		 && std::__invoke(__pred, __value, std::__invoke(__proj, *__i)))
+	  auto __tail_size = __last - __first;
+	  auto __remainder = __count;
+
+	  while (__remainder <= __tail_size)
 	    {
-	      ++__i;
-	      --__n;
+	      __first += __remainder;
+	      __tail_size -= __remainder;
+	      auto __backtrack = __first;
+	      while (__value_comp(std::__invoke(__proj, *--__backtrack)))
+		{
+		  if (--__remainder == 0)
+		    return {__first - __count, __first};
+		}
 	    }
-	  if (__n == 1)
-	    return {__first, __i};
-	  if (__i == __last)
-	    return {__last, __last};
+	  return {__last, __last};
+	}
+      else
+	{
 	  __first = ranges::find_if(__first, __last, __value_comp, __proj);
+	  while (__first != __last)
+	    {
+	      auto __n = __count;
+	      auto __i = __first;
+	      ++__i;
+	      while (__i != __last && __n != 1
+		     && __value_comp(std::__invoke(__proj, *__i)))
+		{
+		  ++__i;
+		  --__n;
+		}
+	      if (__n == 1)
+		return {__first, __i};
+	      if (__i == __last)
+		return {__last, __last};
+	      __first = ranges::find_if(++__i, __last, __value_comp, __proj);
+	    }
+	  return {__last, __last};
 	}
-      return {__last, __last};
     }
 
   template<forward_range _Range, typename _Tp,
diff --git a/libstdc++-v3/testsuite/25_algorithms/search_n/constrained.cc b/libstdc++-v3/testsuite/25_algorithms/search_n/constrained.cc
index b0733a6..de9b171 100644
--- a/libstdc++-v3/testsuite/25_algorithms/search_n/constrained.cc
+++ b/libstdc++-v3/testsuite/25_algorithms/search_n/constrained.cc
@@ -49,7 +49,7 @@ test01()
 
   int y[] = { {2}, {2}, {8}, {2}, {2}, {2}, {5} };
   test_range<int, forward_iterator_wrapper> ry(y);
-  auto res3 = ranges::search_n(ry, 2, 3);
+  auto res3 = ranges::search_n(ry, 3, 2);
   VERIFY( *res3.begin() == 2 && *res3.end() == 5 );
 }



More information about the Libstdc++-cvs mailing list