diff --git a/libcxx/docs/Status/RangesAlgorithms.csv b/libcxx/docs/Status/RangesAlgorithms.csv --- a/libcxx/docs/Status/RangesAlgorithms.csv +++ b/libcxx/docs/Status/RangesAlgorithms.csv @@ -30,8 +30,8 @@ Read-only,is_sorted,Nikolas Klauser,`D125608 `_,✅ Read-only,is_sorted_until,Nikolas Klauser,`D125608 `_,✅ Read-only,includes,Hui Xie,`D130116 `,✅ -Read-only,is_heap,Nikolas Klauser,n/a,Not started -Read-only,is_heap_until,Nikolas Klauser,n/a,Not started +Read-only,is_heap,Konstantin Varlamov,`D130547 `_,✅ +Read-only,is_heap_until,Konstantin Varlamov,`D130547 `_,✅ Read-only,clamp,Nikolas Klauser,`D126193 `_,Under review Read-only,is_permutation,Nikolas Klauser,`D127194 `_,Under review Read-only,for_each,Nikolas Klauser,`D124332 `_,✅ diff --git a/libcxx/include/__algorithm/is_heap.h b/libcxx/include/__algorithm/is_heap.h --- a/libcxx/include/__algorithm/is_heap.h +++ b/libcxx/include/__algorithm/is_heap.h @@ -28,7 +28,7 @@ is_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) { typedef typename __comp_ref_type<_Compare>::type _Comp_ref; - return _VSTD::__is_heap_until<_Comp_ref>(__first, __last, __comp) == __last; + return std::__is_heap_until(__first, __last, static_cast<_Comp_ref>(__comp)) == __last; } template diff --git a/libcxx/include/__algorithm/is_heap_until.h b/libcxx/include/__algorithm/is_heap_until.h --- a/libcxx/include/__algorithm/is_heap_until.h +++ b/libcxx/include/__algorithm/is_heap_until.h @@ -22,7 +22,7 @@ template _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 _RandomAccessIterator -__is_heap_until(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) +__is_heap_until(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare&& __comp) { typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type; difference_type __len = __last - __first; @@ -52,7 +52,7 @@ is_heap_until(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) { typedef typename __comp_ref_type<_Compare>::type _Comp_ref; - return _VSTD::__is_heap_until<_Comp_ref>(__first, __last, __comp); + return std::__is_heap_until(__first, __last, static_cast<_Comp_ref>(__comp)); } template diff --git a/libcxx/include/__algorithm/ranges_is_heap.h b/libcxx/include/__algorithm/ranges_is_heap.h --- a/libcxx/include/__algorithm/ranges_is_heap.h +++ b/libcxx/include/__algorithm/ranges_is_heap.h @@ -9,18 +9,17 @@ #ifndef _LIBCPP___ALGORITHM_RANGES_IS_HEAP_H #define _LIBCPP___ALGORITHM_RANGES_IS_HEAP_H -#include <__algorithm/is_heap.h> +#include <__algorithm/is_heap_until.h> #include <__algorithm/make_projected.h> #include <__config> #include <__functional/identity.h> -#include <__functional/invoke.h> #include <__functional/ranges_operations.h> #include <__iterator/concepts.h> #include <__iterator/iterator_traits.h> +#include <__iterator/next.h> #include <__iterator/projected.h> #include <__ranges/access.h> #include <__ranges/concepts.h> -#include <__utility/forward.h> #include <__utility/move.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) @@ -36,22 +35,28 @@ struct __fn { + template + _LIBCPP_HIDE_FROM_ABI constexpr + static bool __is_heap_fn_impl(_Iter __first, _Sent __last, _Comp& __comp, _Proj& __proj) { + auto __last_iter = ranges::next(__first, __last); + auto&& __projected_comp = ranges::__make_projected_comp(__comp, __proj); + + auto __result = std::__is_heap_until(std::move(__first), std::move(__last_iter), __projected_comp); + return __result == __last; + } + template _Sent, class _Proj = identity, indirect_strict_weak_order> _Comp = ranges::less> _LIBCPP_HIDE_FROM_ABI constexpr bool operator()(_Iter __first, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) const { - // TODO: implement - (void)__first; (void)__last; (void)__comp; (void)__proj; - return {}; + return __is_heap_fn_impl(std::move(__first), std::move(__last), __comp, __proj); } template , _Proj>> _Comp = ranges::less> _LIBCPP_HIDE_FROM_ABI constexpr bool operator()(_Range&& __range, _Comp __comp = {}, _Proj __proj = {}) const { - // TODO: implement - (void)__range; (void)__comp; (void)__proj; - return {}; + return __is_heap_fn_impl(ranges::begin(__range), ranges::end(__range), __comp, __proj); } }; diff --git a/libcxx/include/__algorithm/ranges_is_heap_until.h b/libcxx/include/__algorithm/ranges_is_heap_until.h --- a/libcxx/include/__algorithm/ranges_is_heap_until.h +++ b/libcxx/include/__algorithm/ranges_is_heap_until.h @@ -13,15 +13,14 @@ #include <__algorithm/make_projected.h> #include <__config> #include <__functional/identity.h> -#include <__functional/invoke.h> #include <__functional/ranges_operations.h> #include <__iterator/concepts.h> #include <__iterator/iterator_traits.h> +#include <__iterator/next.h> #include <__iterator/projected.h> #include <__ranges/access.h> #include <__ranges/concepts.h> #include <__ranges/dangling.h> -#include <__utility/forward.h> #include <__utility/move.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) @@ -37,22 +36,27 @@ struct __fn { + template + _LIBCPP_HIDE_FROM_ABI constexpr + static _Iter __is_heap_until_fn_impl(_Iter __first, _Sent __last, _Comp& __comp, _Proj& __proj) { + auto __last_iter = ranges::next(__first, __last); + auto&& __projected_comp = ranges::__make_projected_comp(__comp, __proj); + + return std::__is_heap_until(std::move(__first), std::move(__last_iter), __projected_comp); + } + template _Sent, class _Proj = identity, indirect_strict_weak_order> _Comp = ranges::less> _LIBCPP_HIDE_FROM_ABI constexpr _Iter operator()(_Iter __first, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) const { - // TODO: implement - (void)__first; (void)__last; (void)__comp; (void)__proj; - return {}; + return __is_heap_until_fn_impl(std::move(__first), std::move(__last), __comp, __proj); } template , _Proj>> _Comp = ranges::less> _LIBCPP_HIDE_FROM_ABI constexpr borrowed_iterator_t<_Range> operator()(_Range&& __range, _Comp __comp = {}, _Proj __proj = {}) const { - // TODO: implement - (void)__range; (void)__comp; (void)__proj; - return {}; + return __is_heap_until_fn_impl(ranges::begin(__range), ranges::end(__range), __comp, __proj); } }; diff --git a/libcxx/include/algorithm b/libcxx/include/algorithm --- a/libcxx/include/algorithm +++ b/libcxx/include/algorithm @@ -331,6 +331,23 @@ constexpr borrowed_iterator_t ranges::sort_heap(R&& r, Comp comp = {}, Proj proj = {}); // since C++20 + template S, class Proj = identity, + indirect_strict_weak_order> Comp = ranges::less> + constexpr bool is_heap(I first, S last, Comp comp = {}, Proj proj = {}); // Since C++20 + + template, Proj>> Comp = ranges::less> + constexpr bool is_heap(R&& r, Comp comp = {}, Proj proj = {}); // Since C++20 + + template S, class Proj = identity, + indirect_strict_weak_order> Comp = ranges::less> + constexpr I is_heap_until(I first, S last, Comp comp = {}, Proj proj = {}); // Since C++20 + + template, Proj>> Comp = ranges::less> + constexpr borrowed_iterator_t + is_heap_until(R&& r, Comp comp = {}, Proj proj = {}); // Since C++20 + template S> requires permutable constexpr I ranges::reverse(I first, S last); // since C++20 @@ -1590,6 +1607,8 @@ #include <__algorithm/ranges_generate.h> #include <__algorithm/ranges_generate_n.h> #include <__algorithm/ranges_includes.h> +#include <__algorithm/ranges_is_heap.h> +#include <__algorithm/ranges_is_heap_until.h> #include <__algorithm/ranges_is_partitioned.h> #include <__algorithm/ranges_is_sorted.h> #include <__algorithm/ranges_is_sorted_until.h> diff --git a/libcxx/test/libcxx/algorithms/ranges_robust_against_copying_comparators.pass.cpp b/libcxx/test/libcxx/algorithms/ranges_robust_against_copying_comparators.pass.cpp --- a/libcxx/test/libcxx/algorithms/ranges_robust_against_copying_comparators.pass.cpp +++ b/libcxx/test/libcxx/algorithms/ranges_robust_against_copying_comparators.pass.cpp @@ -126,10 +126,10 @@ //(void)std::ranges::generate_n(first, count, NullaryValue(&copies)); assert(copies == 0); (void)std::ranges::includes(first, last, first2, last2, Less(&copies)); assert(copies == 0); (void)std::ranges::includes(a, b, Less(&copies)); assert(copies == 0); - //(void)std::ranges::is_heap(first, last, Less(&copies)); assert(copies == 0); - //(void)std::ranges::is_heap(a, Less(&copies)); assert(copies == 0); - //(void)std::ranges::is_heap_until(first, last, Less(&copies)); assert(copies == 0); - //(void)std::ranges::is_heap_until(a, Less(&copies)); assert(copies == 0); + (void)std::ranges::is_heap(first, last, Less(&copies)); assert(copies == 0); + (void)std::ranges::is_heap(a, Less(&copies)); assert(copies == 0); + (void)std::ranges::is_heap_until(first, last, Less(&copies)); assert(copies == 0); + (void)std::ranges::is_heap_until(a, Less(&copies)); assert(copies == 0); (void)std::ranges::is_partitioned(first, last, UnaryTrue(&copies)); assert(copies == 0); (void)std::ranges::is_partitioned(a, UnaryTrue(&copies)); assert(copies == 0); //(void)std::ranges::is_permutation(first, last, first2, last2, Equal(&copies)); assert(copies == 0); diff --git a/libcxx/test/libcxx/algorithms/ranges_robust_against_copying_projections.pass.cpp b/libcxx/test/libcxx/algorithms/ranges_robust_against_copying_projections.pass.cpp --- a/libcxx/test/libcxx/algorithms/ranges_robust_against_copying_projections.pass.cpp +++ b/libcxx/test/libcxx/algorithms/ranges_robust_against_copying_projections.pass.cpp @@ -109,10 +109,10 @@ (void)std::ranges::for_each_n(first, count, UnaryVoid(), Proj(&copies)); assert(copies == 0); (void)std::ranges::includes(first, last, first2, last2, Less(), Proj(&copies), Proj(&copies)); assert(copies == 0); (void)std::ranges::includes(a, b, Less(), Proj(&copies), Proj(&copies)); assert(copies == 0); - //(void)std::ranges::is_heap(first, last, Less(), Proj(&copies)); assert(copies == 0); - //(void)std::ranges::is_heap(a, Less(), Proj(&copies)); assert(copies == 0); - //(void)std::ranges::is_heap_until(first, last, Less(), Proj(&copies)); assert(copies == 0); - //(void)std::ranges::is_heap_until(a, Less(), Proj(&copies)); assert(copies == 0); + (void)std::ranges::is_heap(first, last, Less(), Proj(&copies)); assert(copies == 0); + (void)std::ranges::is_heap(a, Less(), Proj(&copies)); assert(copies == 0); + (void)std::ranges::is_heap_until(first, last, Less(), Proj(&copies)); assert(copies == 0); + (void)std::ranges::is_heap_until(a, Less(), Proj(&copies)); assert(copies == 0); (void)std::ranges::is_partitioned(first, last, UnaryTrue(), Proj(&copies)); assert(copies == 0); (void)std::ranges::is_partitioned(a, UnaryTrue(), Proj(&copies)); assert(copies == 0); //(void)std::ranges::is_permutation(first, last, first2, last2, Equal(), Proj(&copies), Proj(&copies)); assert(copies == 0); diff --git a/libcxx/test/std/algorithms/alg.sorting/alg.heap.operations/is.heap/ranges_is_heap.pass.cpp b/libcxx/test/std/algorithms/alg.sorting/alg.heap.operations/is.heap/ranges_is_heap.pass.cpp --- a/libcxx/test/std/algorithms/alg.sorting/alg.heap.operations/is.heap/ranges_is_heap.pass.cpp +++ b/libcxx/test/std/algorithms/alg.sorting/alg.heap.operations/is.heap/ranges_is_heap.pass.cpp @@ -12,28 +12,158 @@ // // template S, class Proj = identity, -// indirect_strict_weak_order> Comp = ranges::less> -// constexpr bool is_heap(I first, S last, Comp comp = {}, Proj proj = {}); // Since C++20 +// indirect_strict_weak_order> Comp = ranges::less> +// constexpr bool is_heap(I first, S last, Comp comp = {}, Proj proj = {}); // Since C++20 // -// template, Proj>> Comp = ranges::less> -// constexpr bool is_heap(R&& r, Comp comp = {}, Proj proj = {}); // Since C++20 +// template, Proj>> Comp = ranges::less> +// constexpr bool is_heap(R&& r, Comp comp = {}, Proj proj = {}); // Since C++20 #include #include #include #include #include +#include #include "almost_satisfies_types.h" #include "test_iterators.h" -// TODO: SFINAE tests. +// Test constraints of the (iterator, sentinel) overload. +// ====================================================== + +template +concept HasIsHeapIter = + requires(Iter&& iter, Sent&& sent, Comp&& comp) { + std::ranges::is_heap(std::forward(iter), std::forward(sent), std::forward(comp)); + }; + +static_assert(HasIsHeapIter); + +// !random_access_iterator +static_assert(!HasIsHeapIter); +static_assert(!HasIsHeapIter); + +// !sentinel_for +static_assert(!HasIsHeapIter); +static_assert(!HasIsHeapIter); + +struct NoComparator {}; +// !indirect_strict_weak_order> +static_assert(!HasIsHeapIter); + +// Test constraints of the (range) overload. +// ========================================= + +template +concept HasIsHeapRange = + requires(Range&& range, Comp&& comp) { + std::ranges::is_heap(std::forward(range), std::forward(comp)); + }; + +template +using R = UncheckedRange; + +static_assert(HasIsHeapRange>); + +// !random_access_range +static_assert(!HasIsHeapRange); +static_assert(!HasIsHeapRange); + +// !indirect_strict_weak_order, Proj>> +static_assert(!HasIsHeapRange>); + +template +constexpr void test_one(std::array input, bool expected) { + auto begin = Iter(input.data()); + auto end = Sent(Iter(input.data() + input.size())); + + { // (iterator, sentinel) overload. + std::same_as decltype(auto) result = std::ranges::is_heap(begin, end); + assert(result == expected); + } + + { // (range) overload. + auto range = std::ranges::subrange(begin, end); + std::same_as decltype(auto) result = std::ranges::is_heap(range); + assert(result == expected); + } +} + +template +constexpr void test_iter_sent() { + // Empty sequence. + test_one({}, true); + // 1-element sequence. + test_one(std::array{1}, true); + // 2-element sequence, a heap. + test_one(std::array{2, 1}, true); + // 2-element sequence, not a heap. + test_one(std::array{1, 2}, false); + // Longer sequence, a heap. + test_one(std::array{8, 6, 7, 3, 4, 1, 5, 2}, true); + // Longer sequence, not a heap. + test_one(std::array{8, 6, 7, 3, 4, 1, 2, 5}, false); + // Longer sequence with duplicates, a heap. + test_one(std::array{8, 7, 5, 5, 6, 4, 1, 2, 3, 2}, true); + // Longer sequence with duplicates, not a heap. + test_one(std::array{7, 5, 5, 6, 4, 1, 2, 3, 2, 8}, false); + // All elements are the same. + test_one(std::array{1, 1, 1}, true); +} + +template +constexpr void test_iter() { + test_iter_sent(); + test_iter_sent>(); +} + +constexpr void test_iterators() { + test_iter>(); + test_iter>(); + test_iter(); + test_iter(); +} constexpr bool test() { - // TODO: main tests. - // TODO: A custom comparator works. - // TODO: A custom projection works. + test_iterators(); + + { // A custom comparator works. + std::ranges::less ls; + std::ranges::greater gt; + std::array in = {1, 3, 2, 5, 4, 7, 8, 6}; + + { // (iterator, sentinel) overload. + assert(!std::ranges::is_heap(in.begin(), in.end(), ls)); + assert(std::ranges::is_heap(in.begin(), in.end(), gt)); + } + + { // (range) overload. + assert(!std::ranges::is_heap(in, ls)); + assert(std::ranges::is_heap(in, gt)); + } + } + + { // A custom projection works. + struct A { + int x; + constexpr auto operator<=>(const A&) const = default; + }; + + std::array in = {A{-8}, A{-6}, A{-7}, A{-3}, A{-4}, A{-1}, A{-5}, A{-2}}; + auto negate = [](A a) { return a.x * -1; }; + + { // (iterator, sentinel) overload. + assert(!std::ranges::is_heap(in.begin(), in.end(), {})); + assert(std::ranges::is_heap(in.begin(), in.end(), {}, negate)); + } + + { // (range) overload. + assert(!std::ranges::is_heap(in, {})); + assert(std::ranges::is_heap(in, {}, negate)); + } + } + return true; } diff --git a/libcxx/test/std/algorithms/alg.sorting/alg.heap.operations/is.heap/ranges_is_heap_until.pass.cpp b/libcxx/test/std/algorithms/alg.sorting/alg.heap.operations/is.heap/ranges_is_heap_until.pass.cpp --- a/libcxx/test/std/algorithms/alg.sorting/alg.heap.operations/is.heap/ranges_is_heap_until.pass.cpp +++ b/libcxx/test/std/algorithms/alg.sorting/alg.heap.operations/is.heap/ranges_is_heap_until.pass.cpp @@ -12,13 +12,13 @@ // // template S, class Proj = identity, -// indirect_strict_weak_order> Comp = ranges::less> -// constexpr I is_heap_until(I first, S last, Comp comp = {}, Proj proj = {}); // Since C++20 +// indirect_strict_weak_order> Comp = ranges::less> +// constexpr I is_heap_until(I first, S last, Comp comp = {}, Proj proj = {}); // Since C++20 // -// template, Proj>> Comp = ranges::less> -// constexpr borrowed_iterator_t -// is_heap_until(R&& r, Comp comp = {}, Proj proj = {}); // Since C++20 +// template, Proj>> Comp = ranges::less> +// constexpr borrowed_iterator_t +// is_heap_until(R&& r, Comp comp = {}, Proj proj = {}); // Since C++20 #include #include @@ -29,12 +29,149 @@ #include "almost_satisfies_types.h" #include "test_iterators.h" -// TODO: SFINAE tests. +// Test constraints of the (iterator, sentinel) overload. +// ====================================================== + +template +concept HasIsHeapUntilIter = + requires(Iter&& iter, Sent&& sent, Comp&& comp) { + std::ranges::is_heap_until(std::forward(iter), std::forward(sent), std::forward(comp)); + }; + +static_assert(HasIsHeapUntilIter); + +// !random_access_iterator +static_assert(!HasIsHeapUntilIter); +static_assert(!HasIsHeapUntilIter); + +// !sentinel_for +static_assert(!HasIsHeapUntilIter); +static_assert(!HasIsHeapUntilIter); + +struct NoComparator {}; +// !indirect_strict_weak_order> +static_assert(!HasIsHeapUntilIter); + +// Test constraints of the (range) overload. +// ========================================= + +template +concept HasIsHeapUntilRange = + requires(Range&& range, Comp&& comp) { + std::ranges::is_heap_until(std::forward(range), std::forward(comp)); + }; + +template +using R = UncheckedRange; + +static_assert(HasIsHeapUntilRange>); + +// !random_access_range +static_assert(!HasIsHeapUntilRange); +static_assert(!HasIsHeapUntilRange); + +// !indirect_strict_weak_order, Proj>> +static_assert(!HasIsHeapUntilRange>); + +template +constexpr void test_one(std::array input, size_t until_index) { + auto begin = Iter(input.data()); + auto end = Sent(Iter(input.data() + input.size())); + + { // (iterator, sentinel) overload. + std::same_as decltype(auto) result = std::ranges::is_heap_until(begin, end); + assert(base(result) == input.data() + until_index); + } + + { // (range) overload. + auto range = std::ranges::subrange(begin, end); + std::same_as decltype(auto) result = std::ranges::is_heap_until(range); + assert(base(result) == input.data() + until_index); + } +} + +template +constexpr void test_iter_sent() { + // Empty sequence. + test_one({}, 0); + // 1-element sequence. + test_one(std::array{1}, 1); + // 2-element sequence, a heap. + test_one(std::array{2, 1}, 2); + // 2-element sequence, not a heap. + test_one(std::array{1, 2}, 1); + // Longer sequence, a heap. + test_one(std::array{8, 6, 7, 3, 4, 1, 5, 2}, 8); + // Longer sequence, not a heap. + test_one(std::array{8, 6, 7, 3, 4, 1, 2, 5}, 7); + // Longer sequence with duplicates, a heap. + test_one(std::array{8, 7, 5, 5, 6, 4, 1, 2, 3, 2}, 10); + // Longer sequence with duplicates, not a heap. + test_one(std::array{7, 5, 5, 6, 4, 1, 2, 3, 2, 8}, 3); + // All elements are the same. + test_one(std::array{1, 1, 1}, 3); +} + +template +constexpr void test_iter() { + test_iter_sent(); + test_iter_sent>(); +} + +constexpr void test_iterators() { + test_iter>(); + test_iter>(); + test_iter(); + test_iter(); +} constexpr bool test() { - // TODO: main tests. - // TODO: A custom comparator works. - // TODO: A custom projection works. + test_iterators(); + + { // A custom comparator works. + std::ranges::less ls; + std::ranges::greater gt; + std::array in = {1, 3, 2, 5, 4, 7, 8, 6}; + + { // (iterator, sentinel) overload. + auto result_default_comp = std::ranges::is_heap_until(in.begin(), in.end(), ls); + assert(result_default_comp == in.begin() + 1); + auto result_custom_comp = std::ranges::is_heap_until(in.begin(), in.end(), gt); + assert(result_custom_comp == in.end()); + } + + { // (range) overload. + auto result_default_comp = std::ranges::is_heap_until(in, ls); + assert(result_default_comp == in.begin() + 1); + auto result_custom_comp = std::ranges::is_heap_until(in, gt); + assert(result_custom_comp == in.end()); + } + } + + { // A custom projection works. + struct A { + int x; + constexpr auto operator<=>(const A&) const = default; + }; + + std::array in = {A{-8}, A{-6}, A{-7}, A{-3}, A{-4}, A{-1}, A{-5}, A{-2}}; + auto negate = [](A a) { return a.x * -1; }; + + { // (iterator, sentinel) overload. + auto result_default_comp = std::ranges::is_heap_until(in.begin(), in.end(), {}); + assert(result_default_comp == in.begin() + 1); + auto result_custom_comp = std::ranges::is_heap_until(in.begin(), in.end(), {}, negate); + assert(result_custom_comp == in.end()); + } + + { // (range) overload. + auto result_default_comp = std::ranges::is_heap_until(in, {}); + assert(result_default_comp == in.begin() + 1); + auto result_custom_comp = std::ranges::is_heap_until(in, {}, negate); + assert(result_custom_comp == in.end()); + } + } + return true; } diff --git a/libcxx/test/std/algorithms/ranges_robust_against_dangling.pass.cpp b/libcxx/test/std/algorithms/ranges_robust_against_dangling.pass.cpp --- a/libcxx/test/std/algorithms/ranges_robust_against_dangling.pass.cpp +++ b/libcxx/test/std/algorithms/ranges_robust_against_dangling.pass.cpp @@ -125,7 +125,7 @@ dangling_1st(std::ranges::search_n, in, count, x); dangling_1st(std::ranges::find_end, in, in2); dangling_1st(std::ranges::is_sorted_until, in); - //dangling_1st(std::ranges::is_heap_until, in); + dangling_1st(std::ranges::is_heap_until, in); dangling_1st>(std::ranges::for_each, in, unary_pred); dangling_1st>(std::ranges::copy, in, out); // TODO: uncomment `copy_backward` once https://reviews.llvm.org/D128864 lands. diff --git a/libcxx/test/std/algorithms/ranges_robust_against_nonbool_predicates.pass.cpp b/libcxx/test/std/algorithms/ranges_robust_against_nonbool_predicates.pass.cpp --- a/libcxx/test/std/algorithms/ranges_robust_against_nonbool_predicates.pass.cpp +++ b/libcxx/test/std/algorithms/ranges_robust_against_nonbool_predicates.pass.cpp @@ -107,8 +107,8 @@ test(std::ranges::is_sorted, in, binary_pred); test(std::ranges::is_sorted_until, in, binary_pred); test(std::ranges::includes, in, in2, binary_pred); - //test(std::ranges::is_heap, in, binary_pred); - //test(std::ranges::is_heap_until, in, binary_pred); + test(std::ranges::is_heap, in, binary_pred); + test(std::ranges::is_heap_until, in, binary_pred); //std::ranges::clamp(2, 1, 3, binary_pred); //test(std::ranges::is_permutation, in, in2, binary_pred); test(std::ranges::copy_if, in, out, unary_pred); diff --git a/libcxx/test/std/algorithms/ranges_robust_against_omitting_invoke.pass.cpp b/libcxx/test/std/algorithms/ranges_robust_against_omitting_invoke.pass.cpp --- a/libcxx/test/std/algorithms/ranges_robust_against_omitting_invoke.pass.cpp +++ b/libcxx/test/std/algorithms/ranges_robust_against_omitting_invoke.pass.cpp @@ -114,8 +114,8 @@ test(std::ranges::is_sorted, in, &Foo::binary_pred, &Bar::val); test(std::ranges::is_sorted_until, in, &Foo::binary_pred, &Bar::val); test(std::ranges::includes, in, in2, &Foo::binary_pred, &Bar::val, &Bar::val); - //test(std::ranges::is_heap, in, &Foo::binary_pred, &Bar::val); - //test(std::ranges::is_heap_until, in, &Foo::binary_pred, &Bar::val); + test(std::ranges::is_heap, in, &Foo::binary_pred, &Bar::val); + test(std::ranges::is_heap_until, in, &Foo::binary_pred, &Bar::val); //std::ranges::clamp(b, a, c, &Foo::binary_pred); //test(std::ranges::is_permutation, in, in2, &Foo::binary_pred, &Bar::val, &Bar::val); test(std::ranges::for_each, in, &Foo::unary_pred, &Bar::val); diff --git a/libcxx/test/std/algorithms/ranges_robust_against_proxy_iterators.pass.cpp b/libcxx/test/std/algorithms/ranges_robust_against_proxy_iterators.pass.cpp --- a/libcxx/test/std/algorithms/ranges_robust_against_proxy_iterators.pass.cpp +++ b/libcxx/test/std/algorithms/ranges_robust_against_proxy_iterators.pass.cpp @@ -101,8 +101,8 @@ test(std::ranges::is_sorted, in); test(std::ranges::is_sorted_until, in); test(std::ranges::includes, in, in2); - //test(std::ranges::is_heap, in); - //test(std::ranges::is_heap_until, in); + test(std::ranges::is_heap, in); + test(std::ranges::is_heap_until, in); //test(std::ranges::is_permutation, in, in2); test(std::ranges::for_each, in, std::identity{}); std::ranges::for_each_n(in.begin(), count, std::identity{}); diff --git a/libcxx/test/std/library/description/conventions/customization.point.object/niebloid.compile.pass.cpp b/libcxx/test/std/library/description/conventions/customization.point.object/niebloid.compile.pass.cpp --- a/libcxx/test/std/library/description/conventions/customization.point.object/niebloid.compile.pass.cpp +++ b/libcxx/test/std/library/description/conventions/customization.point.object/niebloid.compile.pass.cpp @@ -88,8 +88,8 @@ static_assert(test(std::ranges::generate_n, a, 10, gen)); static_assert(test(std::ranges::includes, a, a)); //static_assert(test(std::ranges::inplace_merge, a, a+5)); -//static_assert(test(std::ranges::is_heap, a)); -//static_assert(test(std::ranges::is_heap_until, a)); +static_assert(test(std::ranges::is_heap, a)); +static_assert(test(std::ranges::is_heap_until, a)); static_assert(test(std::ranges::is_partitioned, a, odd)); //static_assert(test(std::ranges::is_permutation, a, a)); static_assert(test(std::ranges::is_sorted, a));