-
Notifications
You must be signed in to change notification settings - Fork 13.6k
[libc++] Backport segmented iterator optimization for std::for_each to C++11 #134960
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
1cdf3c6
to
d677723
Compare
d677723
to
5aa59ab
Compare
✅ With the latest revision this PR passed the C/C++ code formatter. |
1113999
to
db2a070
Compare
@llvm/pr-subscribers-libcxx Author: Peng Liu (winner245) ChangesPreviously, the segmented iterator optimization for By backporting this enhancement, we improve performance across older standards and create opportunities to extend similar optimizations to other algorithms by forwarding their calls to Patch is 28.62 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/134960.diff 14 Files Affected:
diff --git a/libcxx/include/__algorithm/for_each.h b/libcxx/include/__algorithm/for_each.h
index e08f583504c01..ad021dd962ee5 100644
--- a/libcxx/include/__algorithm/for_each.h
+++ b/libcxx/include/__algorithm/for_each.h
@@ -13,7 +13,7 @@
#include <__algorithm/for_each_segment.h>
#include <__config>
#include <__iterator/segmented_iterator.h>
-#include <__ranges/movable_box.h>
+#include <__type_traits/enable_if.h>
#include <__utility/in_place.h>
#include <__utility/move.h>
@@ -26,28 +26,32 @@ _LIBCPP_PUSH_MACROS
_LIBCPP_BEGIN_NAMESPACE_STD
-template <class _InputIterator, class _Function>
-_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _Function
-for_each(_InputIterator __first, _InputIterator __last, _Function __f) {
+template <class _InputIterator, class _Sent, class _Func>
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __for_each(_InputIterator __first, _Sent __last, _Func& __f) {
for (; __first != __last; ++__first)
__f(*__first);
- return __f;
}
-// __movable_box is available in C++20, but is actually a copyable-box, so optimization is only correct in C++23
-#if _LIBCPP_STD_VER >= 23
-template <class _SegmentedIterator, class _Function>
- requires __is_segmented_iterator<_SegmentedIterator>::value
-_LIBCPP_HIDE_FROM_ABI constexpr _Function
-for_each(_SegmentedIterator __first, _SegmentedIterator __last, _Function __func) {
- ranges::__movable_box<_Function> __wrapped_func(in_place, std::move(__func));
- std::__for_each_segment(__first, __last, [&](auto __lfirst, auto __llast) {
- __wrapped_func =
- ranges::__movable_box<_Function>(in_place, std::for_each(__lfirst, __llast, std::move(*__wrapped_func)));
- });
- return std::move(*__wrapped_func);
+#ifndef _LIBCPP_CXX03_LANG
+template <class _SegmentedIterator,
+ class _Function,
+ __enable_if_t<__is_segmented_iterator<_SegmentedIterator>::value, int> = 0>
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void
+__for_each(_SegmentedIterator __first, _SegmentedIterator __last, _Function& __func) {
+ using _Traits = __segmented_iterator_traits<_SegmentedIterator>;
+ std::__for_each_segment(
+ __first, __last, [&](typename _Traits::__local_iterator __lfirst, typename _Traits::__local_iterator __llast) {
+ std::__for_each(__lfirst, __llast, __func);
+ });
+}
+#endif
+
+template <class _InputIterator, class _Function>
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _Function
+for_each(_InputIterator __first, _InputIterator __last, _Function __f) {
+ std::__for_each(__first, __last, __f);
+ return __f;
}
-#endif // _LIBCPP_STD_VER >= 23
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/algorithm b/libcxx/include/algorithm
index bf67d3363a595..64e9fa6306145 100644
--- a/libcxx/include/algorithm
+++ b/libcxx/include/algorithm
@@ -2061,6 +2061,7 @@ template <class BidirectionalIterator, class Compare>
# include <cstring>
# include <iterator>
# include <memory>
+# include <optional>
# include <stdexcept>
# include <type_traits>
# include <utility>
diff --git a/libcxx/include/array b/libcxx/include/array
index 6e3a1d82abb1b..ff46838e2e8e2 100644
--- a/libcxx/include/array
+++ b/libcxx/include/array
@@ -566,6 +566,7 @@ _LIBCPP_POP_MACROS
# include <cstdlib>
# include <iterator>
# include <new>
+# include <optional>
# include <type_traits>
# include <utility>
# endif
diff --git a/libcxx/include/bitset b/libcxx/include/bitset
index c403c533db7e9..9273ccabbb4e3 100644
--- a/libcxx/include/bitset
+++ b/libcxx/include/bitset
@@ -973,6 +973,7 @@ _LIBCPP_POP_MACROS
# if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
# include <concepts>
# include <cstdlib>
+# include <optional>
# include <type_traits>
# endif
#endif // __cplusplus < 201103L && defined(_LIBCPP_USE_FROZEN_CXX03_HEADERS)
diff --git a/libcxx/include/codecvt b/libcxx/include/codecvt
index 9f241b734d694..33ade1d298a7e 100644
--- a/libcxx/include/codecvt
+++ b/libcxx/include/codecvt
@@ -596,6 +596,7 @@ _LIBCPP_END_NAMESPACE_STD
# include <limits>
# include <mutex>
# include <new>
+# include <optional>
# include <stdexcept>
# include <type_traits>
# include <typeinfo>
diff --git a/libcxx/include/condition_variable b/libcxx/include/condition_variable
index 7f44990547f55..99c74b02807ae 100644
--- a/libcxx/include/condition_variable
+++ b/libcxx/include/condition_variable
@@ -357,6 +357,7 @@ _LIBCPP_POP_MACROS
# include <initializer_list>
# include <iosfwd>
# include <new>
+# include <optional>
# include <stdexcept>
# include <system_error>
# include <type_traits>
diff --git a/libcxx/include/ios b/libcxx/include/ios
index 9d2968753c507..9e48ec88ce59d 100644
--- a/libcxx/include/ios
+++ b/libcxx/include/ios
@@ -887,6 +887,7 @@ _LIBCPP_POP_MACROS
# include <limits>
# include <mutex>
# include <new>
+# include <optional>
# include <stdexcept>
# include <system_error>
# include <type_traits>
diff --git a/libcxx/include/locale b/libcxx/include/locale
index 8e07b8be9ce0d..40f9dd2608fb6 100644
--- a/libcxx/include/locale
+++ b/libcxx/include/locale
@@ -3666,6 +3666,7 @@ _LIBCPP_POP_MACROS
# include <cstdarg>
# include <iterator>
# include <mutex>
+# include <optional>
# include <stdexcept>
# include <type_traits>
# include <typeinfo>
diff --git a/libcxx/include/streambuf b/libcxx/include/streambuf
index eed7eb4d75ecb..85f3af1b88ae7 100644
--- a/libcxx/include/streambuf
+++ b/libcxx/include/streambuf
@@ -386,6 +386,7 @@ _LIBCPP_POP_MACROS
# if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
# include <cstdint>
+# include <optional>
# endif
#endif // __cplusplus < 201103L && defined(_LIBCPP_USE_FROZEN_CXX03_HEADERS)
diff --git a/libcxx/include/string b/libcxx/include/string
index e7e541e31432d..f3f97655d79ea 100644
--- a/libcxx/include/string
+++ b/libcxx/include/string
@@ -4027,6 +4027,7 @@ _LIBCPP_POP_MACROS
# include <cstdlib>
# include <iterator>
# include <new>
+# include <optional>
# include <type_traits>
# include <typeinfo>
# include <utility>
diff --git a/libcxx/include/string_view b/libcxx/include/string_view
index 5054b14efd2d5..861187c0640e1 100644
--- a/libcxx/include/string_view
+++ b/libcxx/include/string_view
@@ -952,6 +952,7 @@ _LIBCPP_POP_MACROS
# include <concepts>
# include <cstdlib>
# include <iterator>
+# include <optional>
# include <type_traits>
# endif
#endif // __cplusplus < 201103L && defined(_LIBCPP_USE_FROZEN_CXX03_HEADERS)
diff --git a/libcxx/include/system_error b/libcxx/include/system_error
index 4dadc0a6ab483..2b668e5f8f1bc 100644
--- a/libcxx/include/system_error
+++ b/libcxx/include/system_error
@@ -168,6 +168,7 @@ template <> struct hash<std::error_condition>;
# include <cstdint>
# include <cstring>
# include <limits>
+# include <optional>
# include <type_traits>
# endif
#endif // __cplusplus < 201103L && defined(_LIBCPP_USE_FROZEN_CXX03_HEADERS)
diff --git a/libcxx/include/vector b/libcxx/include/vector
index 9fa81dcb7e76e..d2d5fcf4a3199 100644
--- a/libcxx/include/vector
+++ b/libcxx/include/vector
@@ -362,6 +362,7 @@ template<class T, class charT> requires is-vector-bool-reference<T> // Since C++
# if _LIBCPP_HAS_LOCALIZATION
# include <locale>
# endif
+# include <optional>
# include <string>
# include <string_view>
# include <tuple>
diff --git a/libcxx/test/libcxx/algorithms/robust_against_copying_comparators.pass.cpp b/libcxx/test/libcxx/algorithms/robust_against_copying_comparators.pass.cpp
index df656f296bd05..256251686bb3e 100644
--- a/libcxx/test/libcxx/algorithms/robust_against_copying_comparators.pass.cpp
+++ b/libcxx/test/libcxx/algorithms/robust_against_copying_comparators.pass.cpp
@@ -12,209 +12,312 @@
#include <cassert>
#include <compare>
#include <cstddef>
+#include <deque>
+#include <ranges>
#include <type_traits>
+#include <vector>
#include "test_macros.h"
template <class T>
struct Less {
- int *copies_;
- TEST_CONSTEXPR explicit Less(int *copies) : copies_(copies) {}
- TEST_CONSTEXPR_CXX14 Less(const Less& rhs) : copies_(rhs.copies_) { *copies_ += 1; }
- TEST_CONSTEXPR_CXX14 Less& operator=(const Less&) = default;
- TEST_CONSTEXPR bool operator()(T, T) const { return false; }
+ int* copies_;
+ TEST_CONSTEXPR explicit Less(int* copies) : copies_(copies) {}
+ TEST_CONSTEXPR_CXX14 Less(const Less& rhs) : copies_(rhs.copies_) { *copies_ += 1; }
+ TEST_CONSTEXPR_CXX14 Less& operator=(const Less&) = default;
+ TEST_CONSTEXPR bool operator()(T, T) const { return false; }
};
template <class T>
struct Equal {
- int *copies_;
- TEST_CONSTEXPR explicit Equal(int *copies) : copies_(copies) {}
- TEST_CONSTEXPR_CXX14 Equal(const Equal& rhs) : copies_(rhs.copies_) { *copies_ += 1; }
- TEST_CONSTEXPR_CXX14 Equal& operator=(const Equal&) = default;
- TEST_CONSTEXPR bool operator()(T, T) const { return true; }
+ int* copies_;
+ TEST_CONSTEXPR explicit Equal(int* copies) : copies_(copies) {}
+ TEST_CONSTEXPR_CXX14 Equal(const Equal& rhs) : copies_(rhs.copies_) { *copies_ += 1; }
+ TEST_CONSTEXPR_CXX14 Equal& operator=(const Equal&) = default;
+ TEST_CONSTEXPR bool operator()(T, T) const { return true; }
};
template <class T>
struct UnaryVoid {
- int *copies_;
- TEST_CONSTEXPR explicit UnaryVoid(int *copies) : copies_(copies) {}
- TEST_CONSTEXPR_CXX14 UnaryVoid(const UnaryVoid& rhs) : copies_(rhs.copies_) { *copies_ += 1; }
- TEST_CONSTEXPR_CXX14 UnaryVoid& operator=(const UnaryVoid&) = default;
- TEST_CONSTEXPR_CXX14 void operator()(T) const {}
+ int* copies_;
+ TEST_CONSTEXPR explicit UnaryVoid(int* copies) : copies_(copies) {}
+ TEST_CONSTEXPR_CXX14 UnaryVoid(const UnaryVoid& rhs) : copies_(rhs.copies_) { *copies_ += 1; }
+ TEST_CONSTEXPR_CXX14 UnaryVoid& operator=(const UnaryVoid&) = default;
+ TEST_CONSTEXPR_CXX14 void operator()(T) const {}
};
template <class T>
struct UnaryTrue {
- int *copies_;
- TEST_CONSTEXPR explicit UnaryTrue(int *copies) : copies_(copies) {}
- TEST_CONSTEXPR_CXX14 UnaryTrue(const UnaryTrue& rhs) : copies_(rhs.copies_) { *copies_ += 1; }
- TEST_CONSTEXPR_CXX14 UnaryTrue& operator=(const UnaryTrue&) = default;
- TEST_CONSTEXPR bool operator()(T) const { return true; }
+ int* copies_;
+ TEST_CONSTEXPR explicit UnaryTrue(int* copies) : copies_(copies) {}
+ TEST_CONSTEXPR_CXX14 UnaryTrue(const UnaryTrue& rhs) : copies_(rhs.copies_) { *copies_ += 1; }
+ TEST_CONSTEXPR_CXX14 UnaryTrue& operator=(const UnaryTrue&) = default;
+ TEST_CONSTEXPR bool operator()(T) const { return true; }
};
template <class T>
struct NullaryValue {
- int *copies_;
- TEST_CONSTEXPR explicit NullaryValue(int *copies) : copies_(copies) {}
- TEST_CONSTEXPR_CXX14 NullaryValue(const NullaryValue& rhs) : copies_(rhs.copies_) { *copies_ += 1; }
- TEST_CONSTEXPR_CXX14 NullaryValue& operator=(const NullaryValue&) = default;
- TEST_CONSTEXPR T operator()() const { return 0; }
+ int* copies_;
+ TEST_CONSTEXPR explicit NullaryValue(int* copies) : copies_(copies) {}
+ TEST_CONSTEXPR_CXX14 NullaryValue(const NullaryValue& rhs) : copies_(rhs.copies_) { *copies_ += 1; }
+ TEST_CONSTEXPR_CXX14 NullaryValue& operator=(const NullaryValue&) = default;
+ TEST_CONSTEXPR T operator()() const { return 0; }
};
template <class T>
struct UnaryTransform {
- int *copies_;
- TEST_CONSTEXPR explicit UnaryTransform(int *copies) : copies_(copies) {}
- TEST_CONSTEXPR_CXX14 UnaryTransform(const UnaryTransform& rhs) : copies_(rhs.copies_) { *copies_ += 1; }
- TEST_CONSTEXPR_CXX14 UnaryTransform& operator=(const UnaryTransform&) = default;
- TEST_CONSTEXPR T operator()(T) const { return 0; }
+ int* copies_;
+ TEST_CONSTEXPR explicit UnaryTransform(int* copies) : copies_(copies) {}
+ TEST_CONSTEXPR_CXX14 UnaryTransform(const UnaryTransform& rhs) : copies_(rhs.copies_) { *copies_ += 1; }
+ TEST_CONSTEXPR_CXX14 UnaryTransform& operator=(const UnaryTransform&) = default;
+ TEST_CONSTEXPR T operator()(T) const { return 0; }
};
template <class T>
struct BinaryTransform {
- int *copies_;
- TEST_CONSTEXPR explicit BinaryTransform(int *copies) : copies_(copies) {}
- TEST_CONSTEXPR_CXX14 BinaryTransform(const BinaryTransform& rhs) : copies_(rhs.copies_) { *copies_ += 1; }
- TEST_CONSTEXPR_CXX14 BinaryTransform& operator=(const BinaryTransform&) = default;
- TEST_CONSTEXPR T operator()(T, T) const { return 0; }
+ int* copies_;
+ TEST_CONSTEXPR explicit BinaryTransform(int* copies) : copies_(copies) {}
+ TEST_CONSTEXPR_CXX14 BinaryTransform(const BinaryTransform& rhs) : copies_(rhs.copies_) { *copies_ += 1; }
+ TEST_CONSTEXPR_CXX14 BinaryTransform& operator=(const BinaryTransform&) = default;
+ TEST_CONSTEXPR T operator()(T, T) const { return 0; }
};
#if TEST_STD_VER > 17
template <class T>
struct ThreeWay {
- int *copies_;
- constexpr explicit ThreeWay(int *copies) : copies_(copies) {}
- constexpr ThreeWay(const ThreeWay& rhs) : copies_(rhs.copies_) { *copies_ += 1; }
- constexpr ThreeWay& operator=(const ThreeWay&) = default;
- constexpr std::strong_ordering operator()(T, T) const { return std::strong_ordering::equal; }
+ int* copies_;
+ constexpr explicit ThreeWay(int* copies) : copies_(copies) {}
+ constexpr ThreeWay(const ThreeWay& rhs) : copies_(rhs.copies_) { *copies_ += 1; }
+ constexpr ThreeWay& operator=(const ThreeWay&) = default;
+ constexpr std::strong_ordering operator()(T, T) const { return std::strong_ordering::equal; }
};
#endif
template <class T>
-TEST_CONSTEXPR_CXX20 bool all_the_algorithms()
-{
- T a[10] = {};
- T b[10] = {};
- T *first = a;
- T *mid = a+5;
- T *last = a+10;
- T *first2 = b;
- T *mid2 = b+5;
- T *last2 = b+10;
- T value = 0;
- int count = 1;
-
- int copies = 0;
- (void)std::adjacent_find(first, last, Equal<T>(&copies)); assert(copies == 0);
+TEST_CONSTEXPR_CXX20 bool all_the_algorithms() {
+ T a[10] = {};
+ T b[10] = {};
+ T* first = a;
+ T* mid = a + 5;
+ T* last = a + 10;
+ T* first2 = b;
+ T* mid2 = b + 5;
+ T* last2 = b + 10;
+ T value = 0;
+ int count = 1;
+
+ int copies = 0;
+ (void)std::adjacent_find(first, last, Equal<T>(&copies));
+ assert(copies == 0);
#if TEST_STD_VER >= 11
- (void)std::all_of(first, last, UnaryTrue<T>(&copies)); assert(copies == 0);
- (void)std::any_of(first, last, UnaryTrue<T>(&copies)); assert(copies == 0);
+ (void)std::all_of(first, last, UnaryTrue<T>(&copies));
+ assert(copies == 0);
+ (void)std::any_of(first, last, UnaryTrue<T>(&copies));
+ assert(copies == 0);
#endif
- (void)std::binary_search(first, last, value, Less<T>(&copies)); assert(copies == 0);
+ (void)std::binary_search(first, last, value, Less<T>(&copies));
+ assert(copies == 0);
#if TEST_STD_VER > 17
- (void)std::clamp(value, value, value, Less<T>(&copies)); assert(copies == 0);
+ (void)std::clamp(value, value, value, Less<T>(&copies));
+ assert(copies == 0);
#endif
- (void)std::count_if(first, last, UnaryTrue<T>(&copies)); assert(copies == 0);
- (void)std::copy_if(first, last, first2, UnaryTrue<T>(&copies)); assert(copies == 0);
- (void)std::equal(first, last, first2, Equal<T>(&copies)); assert(copies == 0);
+ (void)std::count_if(first, last, UnaryTrue<T>(&copies));
+ assert(copies == 0);
+ (void)std::copy_if(first, last, first2, UnaryTrue<T>(&copies));
+ assert(copies == 0);
+ (void)std::equal(first, last, first2, Equal<T>(&copies));
+ assert(copies == 0);
#if TEST_STD_VER > 11
- (void)std::equal(first, last, first2, last2, Equal<T>(&copies)); assert(copies == 0);
+ (void)std::equal(first, last, first2, last2, Equal<T>(&copies));
+ assert(copies == 0);
#endif
- (void)std::equal_range(first, last, value, Less<T>(&copies)); assert(copies == 0);
- (void)std::find_end(first, last, first2, mid2, Equal<T>(&copies)); assert(copies == 0);
- (void)std::find_first_of(first, last, first2, last2, Equal<T>(&copies)); assert(copies == 0);
- (void)std::find_if(first, last, UnaryTrue<T>(&copies)); assert(copies == 0);
- (void)std::find_if_not(first, last, UnaryTrue<T>(&copies)); assert(copies == 0);
- (void)std::for_each(first, last, UnaryVoid<T>(&copies)); assert(copies == 1); copies = 0;
+ (void)std::equal_range(first, last, value, Less<T>(&copies));
+ assert(copies == 0);
+ (void)std::find_end(first, last, first2, mid2, Equal<T>(&copies));
+ assert(copies == 0);
+ (void)std::find_first_of(first, last, first2, last2, Equal<T>(&copies));
+ assert(copies == 0);
+ (void)std::find_if(first, last, UnaryTrue<T>(&copies));
+ assert(copies == 0);
+ (void)std::find_if_not(first, last, UnaryTrue<T>(&copies));
+ assert(copies == 0);
+ (void)std::for_each(first, last, UnaryVoid<T>(&copies));
+ assert(copies == 1);
+ copies = 0;
#if TEST_STD_VER > 14
- (void)std::for_each_n(first, count, UnaryVoid<T>(&copies)); assert(copies == 0);
+ (void)std::for_each_n(first, count, UnaryVoid<T>(&copies));
+ assert(copies == 0);
#endif
- (void)std::generate(first, last, NullaryValue<T>(&copies)); assert(copies == 0);
- (void)std::generate_n(first, count, NullaryValue<T>(&copies)); assert(copies == 0);
- (void)std::includes(first, last, first2, last2, Less<T>(&copies)); assert(copies == 0);
- (void)std::is_heap(first, last, Less<T>(&copies)); assert(copies == 0);
- (void)std::is_heap_until(first, last, Less<T>(&copies)); assert(copies == 0);
- (void)std::is_partitioned(first, last, UnaryTrue<T>(&copies)); assert(copies == 0);
- (void)std::is_permutation(first, last, first2, Equal<T>(&copies)); assert(copies == 0);
+ (void)std::generate(first, last, NullaryValue<T>(&copies));
+ assert(copies == 0);
+ (void)std::generate_n(first, count, NullaryValue<T>(&copies));
+ assert(copies == 0);
+ (void)std::includes(first, last, first2, last2, Less<T>(&copies));
+ assert(copies == 0);
+ (void)std::is_heap(first, last, Less<T>(&copies));
+ assert(copies == 0);
+ (void)std::is_heap_until(first, last, Less<T>(&copies));
+ assert(copies == 0);
+ (void)std::is_partitioned(first, last, UnaryTrue<T>(&copies));
+ assert(copies == 0);
+ (void)std::is_permutation(first, last, first2, Equal<T>(&copies));
+ assert(copies == 0);
#if TEST_STD_VER > 11
- (void)std::is_permutation(first, last, first2, last2, Equal<T>(&copies)); assert(copies == 0);
+ (void)std::is_permutation(first, last, first2, last2, Equal<T>(&copies));
+ assert(copies == 0);
#endif
- (void)std::is_sorted(first, last, Less<T>(&copies)); assert(copies == 0);
- (void)std::is_sorted_until(first, last, Less<T>(&copies)); assert(copies == 0);
- if (!TEST_IS_CONSTANT_EVALUATED) { (void)std::inplace_merge(first, mid, last, Less<T>(&copies)); assert(copies == 0); }
- (void)std::lexicographical_compare(first, last, first2, last2, Less<T>(&copies)); assert(copies == 0);
+ (void)std::is_sorted(first, last, Less<T>(&copies));
+ assert(copies == 0);
+ (void)std::is_sorted_until(first, last, Less<T>(&copies));
+ assert(copies == 0);
+ if (!TEST_IS_CONSTANT_EVALUATED) {
+ (void)std::inplace_merge(first, mid, last, Less<T>(&copies));
+ assert(copies == 0);
+ }
+ (void)std::lexicographical_compare(first, last, first2, last2, Less<T>(&copies));
+ assert(copies == 0);
#if TEST_STD_VER > 17
- (void)std::lexicographical_compare_three_way(first, last, first2, last2, ThreeWay<T>(&copies)); assert(copies == 0);
+ (void)std::lexicographical_compare_three_way(first, last, first2, last2, ThreeWay<T>(&copies));
+ assert(copies == 0);
#endif
- (void)std::lower_bound(first, last, value, Less<T>(&copies)); assert(copies == 0);
- (void)std::make_heap(first, last, Less<T>(&copies)); assert(copies == 0);
- (void)std::max(value, value, Less<T>(&copies)); assert(copies == 0);
+ (void)std::lower_bound(first, last, value, Less<T>(&copies));
+ assert(copies == 0);
+ (void)std::make_heap(first, last, Less<T>(&copies));
+ assert(copies == 0);
+ (void)std::max(value, value, Less<T>(&copies));
+ assert(copies == 0);
#if TEST_STD_VER >= 11
- (void)std::max({ value, value }, Less<T>(&copies)); assert(copies == 0);
+ (void)std::max({value, value}, Less<T>(&copies));
+ assert(copies == 0);
#endif
- (void)std::max_element(first, last, L...
[truncated]
|
db2a070
to
d8642b2
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you add a release note?
d8642b2
to
cfc3cce
Compare
cfc3cce
to
b1d5b7e
Compare
b1d5b7e
to
32d8bf4
Compare
Looks like this PR is associated w/ a build issue: #137046 |
…r_each to C++11 (llvm#134960)" This reverts commit e9280a1.
…r_each to C++11 (llvm#134960)" This reverts commit e9280a1.
…o C++11 (llvm#134960) Previously, the segmented iterator optimization for `std::for_each` was restricted to C++23 and later due to its dependency on `__movable_box`, which is not available in earlier standards. This patch eliminates that restriction, enabling consistent optimizations starting from C++11. By backporting this enhancement, we improve performance across older standards and create opportunities to extend similar optimizations to other algorithms by forwarding their calls to `std::for_each`.
…o C++11 (llvm#134960) Previously, the segmented iterator optimization for `std::for_each` was restricted to C++23 and later due to its dependency on `__movable_box`, which is not available in earlier standards. This patch eliminates that restriction, enabling consistent optimizations starting from C++11. By backporting this enhancement, we improve performance across older standards and create opportunities to extend similar optimizations to other algorithms by forwarding their calls to `std::for_each`.
…o C++11 (llvm#134960) Previously, the segmented iterator optimization for `std::for_each` was restricted to C++23 and later due to its dependency on `__movable_box`, which is not available in earlier standards. This patch eliminates that restriction, enabling consistent optimizations starting from C++11. By backporting this enhancement, we improve performance across older standards and create opportunities to extend similar optimizations to other algorithms by forwarding their calls to `std::for_each`.
This PR caused the tests failure in lldbFailed tests:
Above tests passed on commit repro steps:
Test output
|
@shafik @zyn-li |
@winner245 Thank you for submitting this fix! I will follow up on my side with @dmpots. Will definitely share more if we have more findings regarding this issue! |
Previously, the segmented iterator optimization for
std::for_each
was restricted to C++23 and later due to its dependency on__movable_box
, which is not available in earlier standards. This patch eliminates that restriction, enabling consistent optimizations starting from C++11.By backporting this enhancement, we improve performance across older standards and create opportunities to extend similar optimizations to other algorithms by forwarding their calls to
std::for_each
.