aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonathan Wakely <jwakely@redhat.com>2020-03-03 11:06:26 +0000
committerJonathan Wakely <jwakely@redhat.com>2020-03-03 11:06:26 +0000
commit9b4f00dd3f799337d8b8ef5e79f5a682c8059ab9 (patch)
treeb443d9547c4ac12c012084225ec211a52d9d5695
parentb07e4e7c7520ca3e798f514dec0711eea2c027be (diff)
downloadgcc-9b4f00dd3f799337d8b8ef5e79f5a682c8059ab9.zip
gcc-9b4f00dd3f799337d8b8ef5e79f5a682c8059ab9.tar.gz
gcc-9b4f00dd3f799337d8b8ef5e79f5a682c8059ab9.tar.bz2
libstdc++: Micro-optimisations for lexicographical_compare_three_way
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).
-rw-r--r--libstdc++-v3/ChangeLog5
-rw-r--r--libstdc++-v3/include/bits/stl_algobase.h7
2 files changed, 9 insertions, 3 deletions
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index 28957dc..b8cf579 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -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
diff --git a/libstdc++-v3/include/bits/stl_algobase.h b/libstdc++-v3/include/bits/stl_algobase.h
index 7a9d932..4b63086 100644
--- a/libstdc++-v3/include/bits/stl_algobase.h
+++ b/libstdc++-v3/include/bits/stl_algobase.h
@@ -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>