[libcxx-commits] [libcxx] [libc++] Optimize lexicographical_compare (PR #65279)
Louis Dionne via libcxx-commits
libcxx-commits at lists.llvm.org
Thu Aug 1 08:49:15 PDT 2024
================
@@ -11,39 +11,101 @@
#include <__algorithm/comp.h>
#include <__algorithm/comp_ref_type.h>
+#include <__algorithm/min.h>
+#include <__algorithm/mismatch.h>
+#include <__algorithm/simd_utils.h>
+#include <__algorithm/unwrap_iter.h>
#include <__config>
+#include <__functional/identity.h>
#include <__iterator/iterator_traits.h>
+#include <__string/constexpr_c_functions.h>
+#include <__type_traits/desugars_to.h>
+#include <__type_traits/invoke.h>
+#include <__type_traits/is_equality_comparable.h>
+#include <__type_traits/is_integral.h>
+#include <__type_traits/is_trivially_lexicographically_comparable.h>
+#include <__type_traits/is_volatile.h>
+#include <cwchar>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
#endif
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
_LIBCPP_BEGIN_NAMESPACE_STD
-template <class _Compare, class _InputIterator1, class _InputIterator2>
+template <class _Iter1, class _Sent1, class _Iter2, class _Sent2, class _Proj1, class _Proj2, class _Comp>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool __lexicographical_compare(
- _InputIterator1 __first1,
- _InputIterator1 __last1,
- _InputIterator2 __first2,
- _InputIterator2 __last2,
- _Compare __comp) {
- for (; __first2 != __last2; ++__first1, (void)++__first2) {
- if (__first1 == __last1 || __comp(*__first1, *__first2))
+ _Iter1 __first1, _Sent1 __last1, _Iter2 __first2, _Sent2 __last2, _Comp& __comp, _Proj1& __proj1, _Proj2& __proj2) {
+ while (__first2 != __last2) {
+ if (__first1 == __last1 ||
+ std::__invoke(__comp, std::__invoke(__proj1, *__first1), std::__invoke(__proj2, *__first2)))
return true;
- if (__comp(*__first2, *__first1))
+ if (std::__invoke(__comp, std::__invoke(__proj2, *__first2), std::__invoke(__proj1, *__first1)))
return false;
+ ++__first1;
+ ++__first2;
}
return false;
}
+#ifndef _LIBCPP_CXX03_LANG
+
+template <class _Tp,
+ class _Proj1,
+ class _Proj2,
+ class _Comp,
+ __enable_if_t<__desugars_to_v<__totally_ordered_less_tag, _Comp, _Tp, _Tp> && !is_volatile<_Tp>::value &&
+ __libcpp_is_trivially_equality_comparable<_Tp, _Tp>::value &&
+ __is_identity<_Proj1>::value && __is_identity<_Proj2>::value,
+ int> = 0>
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool
+__lexicographical_compare(_Tp* __first1, _Tp* __last1, _Tp* __first2, _Tp* __last2, _Comp&, _Proj1&, _Proj2&) {
+ if constexpr (__is_trivially_lexicographically_comparable_v<_Tp, _Tp>) {
+ auto __res =
+ std::__constexpr_memcmp(__first1, __first2, __element_count(std::min(__last1 - __first1, __last2 - __first2)));
+ if (__res == 0)
+ return __last1 - __first1 < __last2 - __first2;
+ return __res < 0;
+ }
+#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
+ else if constexpr (is_same<__remove_cv_t<_Tp>, wchar_t>::value) {
+ auto __res = std::__constexpr_wmemcmp(__first1, __first2, std::min(__last1 - __first1, __last2 - __first2));
+ if (__res == 0)
+ return __last1 - __first1 < __last2 - __first2;
+ return __res < 0;
+ }
+#endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
+ else {
+ auto __res = std::mismatch(__first1, __last1, __first2, __last2);
+ if (__res.second == __last2)
+ return false;
+ if (__res.first == __last1)
+ return true;
+ return *__res.first < *__res.second;
+ }
+}
+
+#endif // _LIBCPP_CXX03_LANG
+
template <class _InputIterator1, class _InputIterator2, class _Compare>
_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool lexicographical_compare(
_InputIterator1 __first1,
_InputIterator1 __last1,
_InputIterator2 __first2,
_InputIterator2 __last2,
_Compare __comp) {
- return std::__lexicographical_compare<__comp_ref_type<_Compare> >(__first1, __last1, __first2, __last2, __comp);
----------------
ldionne wrote:
https://github.com/llvm/llvm-project/issues/101500
Don't have to fix in this PR, since I think we want to address this more generally. But it's worth noting that we are technically regressing coverage in this PR.
https://github.com/llvm/llvm-project/pull/65279
More information about the libcxx-commits
mailing list