libstdc++: Micro-optimisations for lexicographical_compare_three_way
authorJonathan Wakely <jwakely@redhat.com>
Tue, 3 Mar 2020 11:06:26 +0000 (11:06 +0000)
committerJonathan Wakely <jwakely@redhat.com>
Tue, 3 Mar 2020 11:06:26 +0000 (11:06 +0000)
As noted in LWG 3410 the specification in the C++20 draft performs more
iterator comparisons than necessary when the end of either range is
reached. Our implementation followed that specification. This removes
the redundant comparisons so that we do no unnecessary work as soon as
we find that we've reached the end of either range.

The odd-looking return statement is because it generates better code
than the original version that copied the global constants.

* include/bits/stl_algobase.h (lexicographical_compare_three_way):
Avoid redundant iterator comparisons (LWG 3410).

libstdc++-v3/ChangeLog
libstdc++-v3/include/bits/stl_algobase.h

index 28957dc5c990e9065f9769c56f5a24c56bc82953..b8cf579fdb3d6693329de944a6690d6b98ceb02f 100644 (file)
@@ -1,3 +1,8 @@
+2020-03-03  Jonathan Wakely  <jwakely@redhat.com>
+
+       * include/bits/stl_algobase.h (lexicographical_compare_three_way):
+       Avoid redundant iterator comparisons (LWG 3410).
+
 2020-03-02  Jonathan Wakely  <jwakely@redhat.com>
 
        PR libstdc++/93972
index 7a9d932b4210e40bfacabe4f423d9f22bdadc41c..4b63086965db29bbf8c1920f8ef80cb2b24e8e64 100644 (file)
@@ -1711,15 +1711,16 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
                return __lencmp;
              }
 #endif // is_constant_evaluated
-      while (__first1 != __last1 && __first2 != __last2)
+      while (__first1 != __last1)
        {
+         if (__first2 == __last2)
+           return strong_ordering::greater;
          if (auto __cmp = __comp(*__first1, *__first2); __cmp != 0)
            return __cmp;
          ++__first1;
          ++__first2;
        }
-      return __first1 != __last1 ? strong_ordering::greater
-       : __first2 != __last2 ? strong_ordering::less : strong_ordering::equal;
+      return (__first2 == __last2) <=> true; // See PR 94006
     }
 
   template<typename _InputIter1, typename _InputIter2>