diff --git a/libcxx/docs/ReleaseNotes/21.rst b/libcxx/docs/ReleaseNotes/21.rst index 2091a713ea200..a7382c5222d08 100644 --- a/libcxx/docs/ReleaseNotes/21.rst +++ b/libcxx/docs/ReleaseNotes/21.rst @@ -67,6 +67,9 @@ Improvements and New Features - The ``std::stable_sort`` algorithm uses radix sort for floating-point types now, which can improve the performance up to 10x, depending on type of sorted elements and the initial state of the sorted array. +- The segmented iterator optimization for ``std::for_each`` has been backported to C++11. Previously it was only available + in C++23 and later. + Deprecations and Removals ------------------------- diff --git a/libcxx/include/__algorithm/for_each.h b/libcxx/include/__algorithm/for_each.h index e08f583504c01..b6c2c7c056edd 100644 --- a/libcxx/include/__algorithm/for_each.h +++ b/libcxx/include/__algorithm/for_each.h @@ -13,44 +13,40 @@ #include <__algorithm/for_each_segment.h> #include <__config> #include <__iterator/segmented_iterator.h> -#include <__ranges/movable_box.h> -#include <__utility/in_place.h> -#include <__utility/move.h> +#include <__type_traits/enable_if.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) # pragma GCC system_header #endif -_LIBCPP_PUSH_MACROS -#include <__undef_macros> - _LIBCPP_BEGIN_NAMESPACE_STD -template -_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _Function -for_each(_InputIterator __first, _InputIterator __last, _Function __f) { +template +_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 - 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))); +#ifndef _LIBCPP_CXX03_LANG +template ::value, int> = 0> +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void +__for_each(_SegmentedIterator __first, _SegmentedIterator __last, _Function& __func) { + using __local_iterator_t = typename __segmented_iterator_traits<_SegmentedIterator>::__local_iterator; + std::__for_each_segment(__first, __last, [&](__local_iterator_t __lfirst, __local_iterator_t __llast) { + std::__for_each(__lfirst, __llast, __func); }); - return std::move(*__wrapped_func); } -#endif // _LIBCPP_STD_VER >= 23 +#endif // !_LIBCPP_CXX03_LANG -_LIBCPP_END_NAMESPACE_STD +template +_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; +} -_LIBCPP_POP_MACROS +_LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP___ALGORITHM_FOR_EACH_H 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 # include # include # include +# include # include # include # include 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 # include # include +# include # include # include # 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 # include +# include # include # 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 # include # include +# include # include # include # include 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 # include # include +# include # include # include # include 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 # include # include +# include # include # include # include diff --git a/libcxx/include/locale b/libcxx/include/locale index 26495497d660f..fa2620d883598 100644 --- a/libcxx/include/locale +++ b/libcxx/include/locale @@ -3692,6 +3692,7 @@ _LIBCPP_POP_MACROS # include # include # include +# include # include # include # include 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 +# include # 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 # include # include +# include # include # include # include 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 # include # include +# include # include # 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; # include # include # include +# include # include # 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 requires is-vector-bool-reference // Since C++ # if _LIBCPP_HAS_LOCALIZATION # include # endif +# include # include # include # include 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 #include #include +#include +#include #include +#include #include "test_macros.h" template 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 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 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 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 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 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 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 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 -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(&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(&copies)); + assert(copies == 0); #if TEST_STD_VER >= 11 - (void)std::all_of(first, last, UnaryTrue(&copies)); assert(copies == 0); - (void)std::any_of(first, last, UnaryTrue(&copies)); assert(copies == 0); + (void)std::all_of(first, last, UnaryTrue(&copies)); + assert(copies == 0); + (void)std::any_of(first, last, UnaryTrue(&copies)); + assert(copies == 0); #endif - (void)std::binary_search(first, last, value, Less(&copies)); assert(copies == 0); + (void)std::binary_search(first, last, value, Less(&copies)); + assert(copies == 0); #if TEST_STD_VER > 17 - (void)std::clamp(value, value, value, Less(&copies)); assert(copies == 0); + (void)std::clamp(value, value, value, Less(&copies)); + assert(copies == 0); #endif - (void)std::count_if(first, last, UnaryTrue(&copies)); assert(copies == 0); - (void)std::copy_if(first, last, first2, UnaryTrue(&copies)); assert(copies == 0); - (void)std::equal(first, last, first2, Equal(&copies)); assert(copies == 0); + (void)std::count_if(first, last, UnaryTrue(&copies)); + assert(copies == 0); + (void)std::copy_if(first, last, first2, UnaryTrue(&copies)); + assert(copies == 0); + (void)std::equal(first, last, first2, Equal(&copies)); + assert(copies == 0); #if TEST_STD_VER > 11 - (void)std::equal(first, last, first2, last2, Equal(&copies)); assert(copies == 0); + (void)std::equal(first, last, first2, last2, Equal(&copies)); + assert(copies == 0); #endif - (void)std::equal_range(first, last, value, Less(&copies)); assert(copies == 0); - (void)std::find_end(first, last, first2, mid2, Equal(&copies)); assert(copies == 0); - (void)std::find_first_of(first, last, first2, last2, Equal(&copies)); assert(copies == 0); - (void)std::find_if(first, last, UnaryTrue(&copies)); assert(copies == 0); - (void)std::find_if_not(first, last, UnaryTrue(&copies)); assert(copies == 0); - (void)std::for_each(first, last, UnaryVoid(&copies)); assert(copies == 1); copies = 0; + (void)std::equal_range(first, last, value, Less(&copies)); + assert(copies == 0); + (void)std::find_end(first, last, first2, mid2, Equal(&copies)); + assert(copies == 0); + (void)std::find_first_of(first, last, first2, last2, Equal(&copies)); + assert(copies == 0); + (void)std::find_if(first, last, UnaryTrue(&copies)); + assert(copies == 0); + (void)std::find_if_not(first, last, UnaryTrue(&copies)); + assert(copies == 0); + (void)std::for_each(first, last, UnaryVoid(&copies)); + assert(copies == 1); + copies = 0; #if TEST_STD_VER > 14 - (void)std::for_each_n(first, count, UnaryVoid(&copies)); assert(copies == 0); + (void)std::for_each_n(first, count, UnaryVoid(&copies)); + assert(copies == 0); #endif - (void)std::generate(first, last, NullaryValue(&copies)); assert(copies == 0); - (void)std::generate_n(first, count, NullaryValue(&copies)); assert(copies == 0); - (void)std::includes(first, last, first2, last2, Less(&copies)); assert(copies == 0); - (void)std::is_heap(first, last, Less(&copies)); assert(copies == 0); - (void)std::is_heap_until(first, last, Less(&copies)); assert(copies == 0); - (void)std::is_partitioned(first, last, UnaryTrue(&copies)); assert(copies == 0); - (void)std::is_permutation(first, last, first2, Equal(&copies)); assert(copies == 0); + (void)std::generate(first, last, NullaryValue(&copies)); + assert(copies == 0); + (void)std::generate_n(first, count, NullaryValue(&copies)); + assert(copies == 0); + (void)std::includes(first, last, first2, last2, Less(&copies)); + assert(copies == 0); + (void)std::is_heap(first, last, Less(&copies)); + assert(copies == 0); + (void)std::is_heap_until(first, last, Less(&copies)); + assert(copies == 0); + (void)std::is_partitioned(first, last, UnaryTrue(&copies)); + assert(copies == 0); + (void)std::is_permutation(first, last, first2, Equal(&copies)); + assert(copies == 0); #if TEST_STD_VER > 11 - (void)std::is_permutation(first, last, first2, last2, Equal(&copies)); assert(copies == 0); + (void)std::is_permutation(first, last, first2, last2, Equal(&copies)); + assert(copies == 0); #endif - (void)std::is_sorted(first, last, Less(&copies)); assert(copies == 0); - (void)std::is_sorted_until(first, last, Less(&copies)); assert(copies == 0); - if (!TEST_IS_CONSTANT_EVALUATED) { (void)std::inplace_merge(first, mid, last, Less(&copies)); assert(copies == 0); } - (void)std::lexicographical_compare(first, last, first2, last2, Less(&copies)); assert(copies == 0); + (void)std::is_sorted(first, last, Less(&copies)); + assert(copies == 0); + (void)std::is_sorted_until(first, last, Less(&copies)); + assert(copies == 0); + if (!TEST_IS_CONSTANT_EVALUATED) { + (void)std::inplace_merge(first, mid, last, Less(&copies)); + assert(copies == 0); + } + (void)std::lexicographical_compare(first, last, first2, last2, Less(&copies)); + assert(copies == 0); #if TEST_STD_VER > 17 - (void)std::lexicographical_compare_three_way(first, last, first2, last2, ThreeWay(&copies)); assert(copies == 0); + (void)std::lexicographical_compare_three_way(first, last, first2, last2, ThreeWay(&copies)); + assert(copies == 0); #endif - (void)std::lower_bound(first, last, value, Less(&copies)); assert(copies == 0); - (void)std::make_heap(first, last, Less(&copies)); assert(copies == 0); - (void)std::max(value, value, Less(&copies)); assert(copies == 0); + (void)std::lower_bound(first, last, value, Less(&copies)); + assert(copies == 0); + (void)std::make_heap(first, last, Less(&copies)); + assert(copies == 0); + (void)std::max(value, value, Less(&copies)); + assert(copies == 0); #if TEST_STD_VER >= 11 - (void)std::max({ value, value }, Less(&copies)); assert(copies == 0); + (void)std::max({value, value}, Less(&copies)); + assert(copies == 0); #endif - (void)std::max_element(first, last, Less(&copies)); assert(copies == 0); - (void)std::merge(first, mid, mid, last, first2, Less(&copies)); assert(copies == 0); - (void)std::min(value, value, Less(&copies)); assert(copies == 0); + (void)std::max_element(first, last, Less(&copies)); + assert(copies == 0); + (void)std::merge(first, mid, mid, last, first2, Less(&copies)); + assert(copies == 0); + (void)std::min(value, value, Less(&copies)); + assert(copies == 0); #if TEST_STD_VER >= 11 - (void)std::min({ value, value }, Less(&copies)); assert(copies == 0); + (void)std::min({value, value}, Less(&copies)); + assert(copies == 0); #endif - (void)std::min_element(first, last, Less(&copies)); assert(copies == 0); - (void)std::minmax(value, value, Less(&copies)); assert(copies == 0); + (void)std::min_element(first, last, Less(&copies)); + assert(copies == 0); + (void)std::minmax(value, value, Less(&copies)); + assert(copies == 0); #if TEST_STD_VER >= 11 - (void)std::minmax({ value, value }, Less(&copies)); assert(copies == 0); + (void)std::minmax({value, value}, Less(&copies)); + assert(copies == 0); #endif - (void)std::minmax_element(first, last, Less(&copies)); assert(copies == 0); - (void)std::mismatch(first, last, first2, Equal(&copies)); assert(copies == 0); + (void)std::minmax_element(first, last, Less(&copies)); + assert(copies == 0); + (void)std::mismatch(first, last, first2, Equal(&copies)); + assert(copies == 0); #if TEST_STD_VER > 11 - (void)std::mismatch(first, last, first2, last2, Equal(&copies)); assert(copies == 0); + (void)std::mismatch(first, last, first2, last2, Equal(&copies)); + assert(copies == 0); #endif - (void)std::next_permutation(first, last, Less(&copies)); assert(copies == 0); + (void)std::next_permutation(first, last, Less(&copies)); + assert(copies == 0); #if TEST_STD_VER >= 11 - (void)std::none_of(first, last, UnaryTrue(&copies)); assert(copies == 0); + (void)std::none_of(first, last, UnaryTrue(&copies)); + assert(copies == 0); #endif - (void)std::nth_element(first, mid, last, Less(&copies)); assert(copies == 0); - (void)std::partial_sort(first, mid, last, Less(&copies)); assert(copies == 0); - (void)std::partial_sort_copy(first, last, first2, mid2, Less(&copies)); assert(copies == 0); - (void)std::partition(first, last, UnaryTrue(&copies)); assert(copies == 0); - (void)std::partition_copy(first, last, first2, last2, UnaryTrue(&copies)); assert(copies == 0); - (void)std::partition_point(first, last, UnaryTrue(&copies)); assert(copies == 0); - (void)std::pop_heap(first, last, Less(&copies)); assert(copies == 0); - (void)std::prev_permutation(first, last, Less(&copies)); assert(copies == 0); - (void)std::push_heap(first, last, Less(&copies)); assert(copies == 0); - (void)std::remove_copy_if(first, last, first2, UnaryTrue(&copies)); assert(copies == 0); - (void)std::remove_if(first, last, UnaryTrue(&copies)); assert(copies == 0); - (void)std::replace_copy_if(first, last, first2, UnaryTrue(&copies), value); assert(copies == 0); - (void)std::replace_if(first, last, UnaryTrue(&copies), value); assert(copies == 0); - (void)std::search(first, last, first2, mid2, Equal(&copies)); assert(copies == 0); - (void)std::search_n(first, last, count, value, Equal(&copies)); assert(copies == 0); - (void)std::set_difference(first, mid, mid, last, first2, Less(&copies)); assert(copies == 0); - (void)std::set_intersection(first, mid, mid, last, first2, Less(&copies)); assert(copies == 0); - (void)std::set_symmetric_difference(first, mid, mid, last, first2, Less(&copies)); assert(copies == 0); - (void)std::set_union(first, mid, mid, last, first2, Less(&copies)); assert(copies == 0); - (void)std::sort(first, first+3, Less(&copies)); assert(copies == 0); - (void)std::sort(first, first+4, Less(&copies)); assert(copies == 0); - (void)std::sort(first, first+5, Less(&copies)); assert(copies == 0); - (void)std::sort(first, last, Less(&copies)); assert(copies == 0); - (void)std::sort_heap(first, last, Less(&copies)); assert(copies == 0); - if (!TEST_IS_CONSTANT_EVALUATED) { (void)std::stable_partition(first, last, UnaryTrue(&copies)); assert(copies == 0); } - if (!TEST_IS_CONSTANT_EVALUATED) { (void)std::stable_sort(first, last, Less(&copies)); assert(copies == 0); } - (void)std::transform(first, last, first2, UnaryTransform(&copies)); assert(copies == 0); - (void)std::transform(first, mid, mid, first2, BinaryTransform(&copies)); assert(copies == 0); - (void)std::unique(first, last, Equal(&copies)); assert(copies == 0); - (void)std::unique_copy(first, last, first2, Equal(&copies)); assert(copies == 0); - (void)std::upper_bound(first, last, value, Less(&copies)); assert(copies == 0); - - return true; + (void)std::nth_element(first, mid, last, Less(&copies)); + assert(copies == 0); + (void)std::partial_sort(first, mid, last, Less(&copies)); + assert(copies == 0); + (void)std::partial_sort_copy(first, last, first2, mid2, Less(&copies)); + assert(copies == 0); + (void)std::partition(first, last, UnaryTrue(&copies)); + assert(copies == 0); + (void)std::partition_copy(first, last, first2, last2, UnaryTrue(&copies)); + assert(copies == 0); + (void)std::partition_point(first, last, UnaryTrue(&copies)); + assert(copies == 0); + (void)std::pop_heap(first, last, Less(&copies)); + assert(copies == 0); + (void)std::prev_permutation(first, last, Less(&copies)); + assert(copies == 0); + (void)std::push_heap(first, last, Less(&copies)); + assert(copies == 0); + (void)std::remove_copy_if(first, last, first2, UnaryTrue(&copies)); + assert(copies == 0); + (void)std::remove_if(first, last, UnaryTrue(&copies)); + assert(copies == 0); + (void)std::replace_copy_if(first, last, first2, UnaryTrue(&copies), value); + assert(copies == 0); + (void)std::replace_if(first, last, UnaryTrue(&copies), value); + assert(copies == 0); + (void)std::search(first, last, first2, mid2, Equal(&copies)); + assert(copies == 0); + (void)std::search_n(first, last, count, value, Equal(&copies)); + assert(copies == 0); + (void)std::set_difference(first, mid, mid, last, first2, Less(&copies)); + assert(copies == 0); + (void)std::set_intersection(first, mid, mid, last, first2, Less(&copies)); + assert(copies == 0); + (void)std::set_symmetric_difference(first, mid, mid, last, first2, Less(&copies)); + assert(copies == 0); + (void)std::set_union(first, mid, mid, last, first2, Less(&copies)); + assert(copies == 0); + (void)std::sort(first, first + 3, Less(&copies)); + assert(copies == 0); + (void)std::sort(first, first + 4, Less(&copies)); + assert(copies == 0); + (void)std::sort(first, first + 5, Less(&copies)); + assert(copies == 0); + (void)std::sort(first, last, Less(&copies)); + assert(copies == 0); + (void)std::sort_heap(first, last, Less(&copies)); + assert(copies == 0); + if (!TEST_IS_CONSTANT_EVALUATED) { + (void)std::stable_partition(first, last, UnaryTrue(&copies)); + assert(copies == 0); + } + if (!TEST_IS_CONSTANT_EVALUATED) { + (void)std::stable_sort(first, last, Less(&copies)); + assert(copies == 0); + } + (void)std::transform(first, last, first2, UnaryTransform(&copies)); + assert(copies == 0); + (void)std::transform(first, mid, mid, first2, BinaryTransform(&copies)); + assert(copies == 0); + (void)std::unique(first, last, Equal(&copies)); + assert(copies == 0); + (void)std::unique_copy(first, last, first2, Equal(&copies)); + assert(copies == 0); + (void)std::upper_bound(first, last, value, Less(&copies)); + assert(copies == 0); + + return true; +} + +bool test_segmented_iterator() { + int copies = 0; + std::deque dq(10); + (void)std::for_each(dq.begin(), dq.end(), UnaryVoid(&copies)); + assert(copies == 1); + copies = 0; + +#if TEST_STD_VER >= 20 + std::vector> vecs(3, std::vector(10)); + auto v = std::views::join(vecs); + (void)std::for_each(v.begin(), v.end(), UnaryVoid(&copies)); + assert(copies == 1); + copies = 0; +#endif + + return true; } -int main(int, char**) -{ - all_the_algorithms(); - all_the_algorithms(); +int main(int, char**) { + all_the_algorithms(); + all_the_algorithms(); + assert(test_segmented_iterator()); #if TEST_STD_VER > 17 - static_assert(all_the_algorithms()); - static_assert(all_the_algorithms()); + static_assert(all_the_algorithms()); + static_assert(all_the_algorithms()); #endif - return 0; + return 0; }