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 @@ -13,7 +13,7 @@ Search,partition_point,Christopher Di Bella,`D105794 `_,Under review Search,lower_bound,Nikolas Klauser,`D121964 `_,✅ Search,upper_bound,Nikolas Klauser,`D121964 `_,✅ -Search,equal_range,Christopher Di Bella,n/a,Not started +Search,equal_range,Hui Xie,`D129796 `,✅ Search,binary_search,Nikolas Klauser,`D121964 `_,✅ Search,min,Nikolas Klauser,`D119589 `_,✅ Search,max,Nikolas Klauser,`D122002 `_,✅ diff --git a/libcxx/include/__algorithm/equal_range.h b/libcxx/include/__algorithm/equal_range.h --- a/libcxx/include/__algorithm/equal_range.h +++ b/libcxx/include/__algorithm/equal_range.h @@ -17,6 +17,7 @@ #include <__algorithm/upper_bound.h> #include <__config> #include <__functional/identity.h> +#include <__functional/invoke.h> #include <__iterator/advance.h> #include <__iterator/distance.h> #include <__iterator/iterator_traits.h> @@ -28,59 +29,42 @@ _LIBCPP_BEGIN_NAMESPACE_STD -template -_LIBCPP_CONSTEXPR_AFTER_CXX17 pair<_ForwardIterator, _ForwardIterator> -__equal_range(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value, _Compare __comp) -{ - typedef typename iterator_traits<_ForwardIterator>::difference_type difference_type; - difference_type __len = _VSTD::distance(__first, __last); - while (__len != 0) - { - difference_type __l2 = _VSTD::__half_positive(__len); - _ForwardIterator __m = __first; - _VSTD::advance(__m, __l2); - if (__comp(*__m, __value)) - { - __first = ++__m; - __len -= __l2 + 1; - } - else if (__comp(__value, *__m)) - { - __last = __m; - __len = __l2; - } - else - { - auto __proj = std::__identity(); - _ForwardIterator __mp1 = __m; - return pair<_ForwardIterator, _ForwardIterator> - ( - _VSTD::__lower_bound_impl<_ClassicAlgPolicy>(__first, __m, __value, __comp, __proj), - _VSTD::__upper_bound<_Compare>(++__mp1, __last, __value, __comp) - ); - } +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 pair<_Iter, _Iter> +__equal_range(_Iter __first, _Sent __last, const _Tp& __value, _Compare&& __comp, _Proj&& __proj) { + auto __len = _IterOps<_AlgPolicy>::distance(__first, __last); + _Iter __end = _IterOps<_AlgPolicy>::next(__first, __last); + while (__len != 0) { + auto __half_len = std::__half_positive(__len); + _Iter __mid = _IterOps<_AlgPolicy>::next(__first, __half_len); + if (std::__invoke(__comp, std::__invoke(__proj, *__mid), __value)) { + __first = ++__mid; + __len -= __half_len + 1; + } else if (std::__invoke(__comp, __value, std::__invoke(__proj, *__mid))) { + __end = __mid; + __len = __half_len; + } else { + _Iter __mp1 = __mid; + return pair<_Iter, _Iter>( + std::__lower_bound_impl<_AlgPolicy>(__first, __mid, __value, __comp, __proj), + std::__upper_bound<_AlgPolicy, _Compare>(++__mp1, __end, __value, __comp, __proj)); } - return pair<_ForwardIterator, _ForwardIterator>(__first, __first); + } + return pair<_Iter, _Iter>(__first, __first); } template -_LIBCPP_NODISCARD_EXT inline -_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 -pair<_ForwardIterator, _ForwardIterator> -equal_range(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value, _Compare __comp) -{ - typedef typename __comp_ref_type<_Compare>::type _Comp_ref; - return _VSTD::__equal_range<_Comp_ref>(__first, __last, __value, __comp); +_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 pair<_ForwardIterator, _ForwardIterator> +equal_range(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value, _Compare __comp) { + typedef typename __comp_ref_type<_Compare>::type _Comp_ref; + return std::__equal_range<_ClassicAlgPolicy, _Comp_ref>(__first, __last, __value, __comp, std::__identity()); } template -_LIBCPP_NODISCARD_EXT inline -_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 -pair<_ForwardIterator, _ForwardIterator> -equal_range(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) -{ - return _VSTD::equal_range(__first, __last, __value, - __less::value_type, _Tp>()); +_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 pair<_ForwardIterator, _ForwardIterator> +equal_range(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) { + return std::equal_range( + __first, __last, __value, __less::value_type, _Tp>()); } _LIBCPP_END_NAMESPACE_STD diff --git a/libcxx/include/__algorithm/iterator_operations.h b/libcxx/include/__algorithm/iterator_operations.h --- a/libcxx/include/__algorithm/iterator_operations.h +++ b/libcxx/include/__algorithm/iterator_operations.h @@ -84,6 +84,13 @@ return __last; } + template + _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR_AFTER_CXX11 + __uncvref_t<_Iter> next(_Iter&& __it, + typename iterator_traits<__uncvref_t<_Iter> >::difference_type __n = 1){ + return std::next(std::forward<_Iter>(__it), __n); + } + template _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR_AFTER_CXX11 void __advance_to(_Iter& __first, _Iter __last) { __first = __last; diff --git a/libcxx/include/__algorithm/ranges_equal_range.h b/libcxx/include/__algorithm/ranges_equal_range.h --- a/libcxx/include/__algorithm/ranges_equal_range.h +++ b/libcxx/include/__algorithm/ranges_equal_range.h @@ -10,7 +10,7 @@ #define _LIBCPP___ALGORITHM_RANGES_EQUAL_RANGE_H #include <__algorithm/equal_range.h> -#include <__algorithm/make_projected.h> +#include <__algorithm/iterator_operations.h> #include <__config> #include <__functional/identity.h> #include <__functional/invoke.h> @@ -37,27 +37,30 @@ namespace __equal_range { struct __fn { - - template _Sent, class _Tp, class _Proj = identity, - indirect_strict_weak_order> _Comp = ranges::less> - _LIBCPP_HIDE_FROM_ABI constexpr - subrange<_Iter> operator()(_Iter __first, _Sent __last, const _Tp& __value, _Comp __comp = {}, - _Proj __proj = {}) const { - // TODO: implement - (void)__first; (void)__last; (void)__value; (void)__comp; (void)__proj; - return {}; + template < + forward_iterator _Iter, + sentinel_for<_Iter> _Sent, + class _Tp, + class _Proj = identity, + indirect_strict_weak_order> _Comp = ranges::less> + _LIBCPP_HIDE_FROM_ABI constexpr subrange<_Iter> + operator()(_Iter __first, _Sent __last, const _Tp& __value, _Comp __comp = {}, _Proj __proj = {}) const { + auto __ret = std::__equal_range<_RangeAlgPolicy>( + std::move(__first), std::move(__last), __value, __comp, __proj); + return {std::move(__ret.first), std::move(__ret.second)}; } - template , _Proj>> _Comp = ranges::less> - _LIBCPP_HIDE_FROM_ABI constexpr - borrowed_subrange_t<_Range> operator()(_Range&& __range, const _Tp& __value, _Comp __comp = {}, - _Proj __proj = {}) const { - // TODO: implement - (void)__range; (void)__value; (void)__comp; (void)__proj; - return {}; + template < + forward_range _Range, + class _Tp, + class _Proj = identity, + indirect_strict_weak_order, _Proj>> _Comp = ranges::less> + _LIBCPP_HIDE_FROM_ABI constexpr borrowed_subrange_t<_Range> + operator()(_Range&& __range, const _Tp& __value, _Comp __comp = {}, _Proj __proj = {}) const { + auto __ret = std::__equal_range<_RangeAlgPolicy>( + ranges::begin(__range), ranges::end(__range), __value, __comp, __proj); + return {std::move(__ret.first), std::move(__ret.second)}; } - }; } // namespace __equal_range diff --git a/libcxx/include/__algorithm/upper_bound.h b/libcxx/include/__algorithm/upper_bound.h --- a/libcxx/include/__algorithm/upper_bound.h +++ b/libcxx/include/__algorithm/upper_bound.h @@ -11,7 +11,9 @@ #include <__algorithm/comp.h> #include <__algorithm/half_positive.h> +#include <__algorithm/iterator_operations.h> #include <__config> +#include <__functional/invoke.h> #include <__iterator/advance.h> #include <__iterator/distance.h> #include <__iterator/iterator_traits.h> @@ -22,45 +24,34 @@ _LIBCPP_BEGIN_NAMESPACE_STD -template -_LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator -__upper_bound(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value, _Compare __comp) -{ - typedef typename iterator_traits<_ForwardIterator>::difference_type difference_type; - difference_type __len = _VSTD::distance(__first, __last); - while (__len != 0) - { - difference_type __l2 = _VSTD::__half_positive(__len); - _ForwardIterator __m = __first; - _VSTD::advance(__m, __l2); - if (__comp(__value, *__m)) - __len = __l2; - else - { - __first = ++__m; - __len -= __l2 + 1; - } +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 _Iter +__upper_bound(_Iter __first, _Sent __last, const _Tp& __value, _Compare&& __comp, _Proj&& __proj) { + auto __len = _IterOps<_AlgPolicy>::distance(__first, __last); + while (__len != 0) { + auto __half_len = std::__half_positive(__len); + auto __mid = _IterOps<_AlgPolicy>::next(__first, __half_len); + if (std::__invoke(__comp, __value, std::__invoke(__proj, *__mid))) + __len = __half_len; + else { + __first = ++__mid; + __len -= __half_len + 1; } - return __first; + } + return __first; } template -_LIBCPP_NODISCARD_EXT inline -_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 -_ForwardIterator -upper_bound(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value, _Compare __comp) -{ - return _VSTD::__upper_bound<_Compare&>(__first, __last, __value, __comp); +_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator +upper_bound(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value, _Compare __comp) { + return std::__upper_bound<_ClassicAlgPolicy, _Compare&>(__first, __last, __value, __comp); } template -_LIBCPP_NODISCARD_EXT inline -_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 -_ForwardIterator -upper_bound(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) -{ - return _VSTD::upper_bound(__first, __last, __value, - __less<_Tp, typename iterator_traits<_ForwardIterator>::value_type>()); +_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator +upper_bound(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) { + return _VSTD::upper_bound( + __first, __last, __value, __less<_Tp, typename iterator_traits<_ForwardIterator>::value_type>()); } _LIBCPP_END_NAMESPACE_STD diff --git a/libcxx/include/algorithm b/libcxx/include/algorithm --- a/libcxx/include/algorithm +++ b/libcxx/include/algorithm @@ -711,6 +711,17 @@ borrowed_iterator_t, O> set_symmetric_difference(R1&& r1, R2&& r2, O result, Comp comp = {}, Proj1 proj1 = {}, Proj2 proj2 = {}); // since C++20 + + template S, class T, class Proj = identity, + indirect_strict_weak_order> Comp = ranges::less> + constexpr subrange + equal_range(I first, S last, const T& value, Comp comp = {}, Proj proj = {}); // since C++20 + + template, Proj>> Comp = + ranges::less> + constexpr borrowed_subrange_t + equal_range(R&& r, const T& value, Comp comp = {}, Proj proj = {}); // since C++20 template using set_union_result = in_in_out_result; // since C++20 @@ -1469,6 +1480,7 @@ #include <__algorithm/ranges_count.h> #include <__algorithm/ranges_count_if.h> #include <__algorithm/ranges_equal.h> +#include <__algorithm/ranges_equal_range.h> #include <__algorithm/ranges_fill.h> #include <__algorithm/ranges_fill_n.h> #include <__algorithm/ranges_find.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 @@ -108,8 +108,8 @@ #endif (void)std::ranges::equal(first, last, first2, last2, Equal(&copies)); assert(copies == 0); (void)std::ranges::equal(a, b, Equal(&copies)); assert(copies == 0); - //(void)std::ranges::equal_range(first, last, value, Less(&copies)); assert(copies == 0); - //(void)std::ranges::equal_range(a, value, Less(&copies)); assert(copies == 0); + (void)std::ranges::equal_range(first, last, value, Less(&copies)); assert(copies == 0); + (void)std::ranges::equal_range(a, value, Less(&copies)); assert(copies == 0); (void)std::ranges::find_end(first, last, first2, mid2, Equal(&copies)); assert(copies == 0); (void)std::ranges::find_end(a, b, Equal(&copies)); assert(copies == 0); (void)std::ranges::find_first_of(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 @@ -92,8 +92,8 @@ #endif (void)std::ranges::equal(first, last, first2, last2, Equal(), Proj(&copies), Proj(&copies)); assert(copies == 0); (void)std::ranges::equal(a, b, Equal(), Proj(&copies), Proj(&copies)); assert(copies == 0); - //(void)std::ranges::equal_range(first, last, value, Less(), Proj(&copies)); assert(copies == 0); - //(void)std::ranges::equal_range(a, value, Less(), Proj(&copies)); assert(copies == 0); + (void)std::ranges::equal_range(first, last, value, Less(), Proj(&copies)); assert(copies == 0); + (void)std::ranges::equal_range(a, value, Less(), Proj(&copies)); assert(copies == 0); (void)std::ranges::find(first, last, value, Proj(&copies)); assert(copies == 0); (void)std::ranges::find(a, value, Proj(&copies)); assert(copies == 0); //(void)std::ranges::find_end(first, last, first2, mid2, Equal(), Proj(&copies), Proj(&copies)); assert(copies == 0); diff --git a/libcxx/test/std/algorithms/alg.sorting/alg.binary.search/equal.range/ranges_equal_range.pass.cpp b/libcxx/test/std/algorithms/alg.sorting/alg.binary.search/equal.range/ranges_equal_range.pass.cpp --- a/libcxx/test/std/algorithms/alg.sorting/alg.binary.search/equal.range/ranges_equal_range.pass.cpp +++ b/libcxx/test/std/algorithms/alg.sorting/alg.binary.search/equal.range/ranges_equal_range.pass.cpp @@ -30,14 +30,195 @@ #include "almost_satisfies_types.h" #include "test_iterators.h" +#include "../../sortable_helpers.h" -// TODO: SFINAE tests. +struct Foo {}; + +template +concept HasEqualRangeIter = + requires(Iter&& iter, Sent&& sent, const T& value, Comp&& comp, Proj&& proj) { + std::ranges::equal_range(std::forward(iter), std::forward(sent), value, comp, proj); + }; + +static_assert(HasEqualRangeIter); + +// !forward_iterator +static_assert(!HasEqualRangeIter, sentinel_wrapper>, int>); + +// !sentinel_for +static_assert(!HasEqualRangeIter); + +// !indirect_strict_weak_order> +static_assert(!HasEqualRangeIter); + +template +concept HasEqualRangeRange = + requires(R&& r, const T& value, Comp&& comp, Proj&& proj) { + std::ranges::equal_range(std::forward(r), value, comp, proj); + }; + +template +using R = UncheckedRange; + +static_assert(HasEqualRangeRange, int>); + +// !forward_range +static_assert(!HasEqualRangeRange>, int>); + +// !indirect_strict_weak_order, Proj>> +static_assert(!HasEqualRangeRange, Foo>); + +template +constexpr void testEqualRangeImpl(std::array& in, int value, std::ranges::subrange expected) { + using Sent = sentinel_wrapper; + + // iterator overload + { + std::same_as> decltype(auto) result = + std::ranges::equal_range(InIter{in.data()}, Sent{InIter{in.data() + in.size()}}, value); + + assert(base(result.begin()) == expected.begin()); + assert(base(result.end()) == expected.end()); + } + + // range overload + { + std::ranges::subrange r{InIter{in.data()}, Sent{InIter{in.data() + in.size()}}}; + std::same_as> decltype(auto) result = std::ranges::equal_range(r, value); + + assert(base(result.begin()) == expected.begin()); + assert(base(result.end()) == expected.end()); + } +} + +template +constexpr void testImpl() { + // no match and the searched value is in the middle + { + std::array in{0, 1, 5, 6, 9, 10}; + int value = 7; + std::ranges::subrange expected{in.data() + 4, in.data() + 4}; + testEqualRangeImpl(in, value, expected); + } + + // value smaller than all the elements + { + std::array in{0, 1, 5, 6, 9, 10}; + int value = -1; + std::ranges::subrange expected{in.data(), in.data()}; + testEqualRangeImpl(in, value, expected); + } + + // value bigger than all the elements + { + std::array in{0, 1, 5, 6, 9, 10}; + int value = 20; + std::ranges::subrange expected{in.data() + in.size(), in.data() + in.size()}; + testEqualRangeImpl(in, value, expected); + } + + // exact one match + { + std::array in{0, 1, 5, 6, 9, 10}; + int value = 5; + std::ranges::subrange expected{in.data() + 2, in.data() + 3}; + testEqualRangeImpl(in, value, expected); + } + + // multiple matches + { + std::array in{0, 1, 5, 6, 6, 6, 9, 10}; + int value = 6; + std::ranges::subrange expected{in.data() + 3, in.data() + 6}; + testEqualRangeImpl(in, value, expected); + } + + // all matches + { + std::array in{6, 6, 6, 6, 6}; + int value = 6; + std::ranges::subrange expected{in.data(), in.data() + in.size()}; + testEqualRangeImpl(in, value, expected); + } + + // empty range + { + std::array in{}; + int value = 6; + std::ranges::subrange expected{in.data(), in.data()}; + testEqualRangeImpl(in, value, expected); + } + + // partially sorted + { + std::array in{3, 1, 5, 2, 6, 6, 10, 7, 8}; + int value = 6; + std::ranges::subrange expected{in.data() + 4, in.data() + 6}; + testEqualRangeImpl(in, value, expected); + } + + // check that ranges::dangling is returned for non-borrowed_range + { + std::array in{0, 1, 5, 6, 6, 6, 9, 10}; + int value = 6; + [[maybe_unused]] std::same_as decltype(auto) result = + std::ranges::equal_range(NonBorrowedRange{in.data(), in.size()}, value); + } +} constexpr bool test() { - // TODO: main tests. - // TODO: A custom comparator works. - // TODO: A custom projection works. + testImpl>(); + testImpl>(); + testImpl>(); + testImpl>(); + + struct Data { + int data; + }; + + // Test custom comparator + { + std::array in{{{2}, {1}, {3}, {3}, {3}, {10}, {9}, {5}, {5}, {7}}}; + Data value{3}; + // iterator overload + { + auto result = std::ranges::equal_range(in.begin(), in.end(), value, [](const Data& x, const Data& y) { + return x.data < y.data; + }); + + assert(result.begin() == in.begin() + 2); + assert(result.end() == in.begin() + 5); + } + + // range overload + { + auto result = std::ranges::equal_range(in, value, [](const Data& x, const Data& y) { return x.data < y.data; }); + + assert(result.begin() == in.begin() + 2); + assert(result.end() == in.begin() + 5); + } + } + + // Test custom projection + { + std::array in{{{2}, {1}, {3}, {3}, {3}, {10}, {9}, {5}, {5}, {7}}}; + int value = 3; + // iterator overload + { + auto result = std::ranges::equal_range(in.begin(), in.end(), value, {}, [](const Data& d) { return d.data; }); + + assert(result.begin() == in.begin() + 2); + assert(result.end() == in.begin() + 5); + } + + // range overload + { + auto result = std::ranges::equal_range(in, value, {}, [](const Data& d) { return d.data; }); + assert(result.begin() == in.begin() + 2); + assert(result.end() == in.begin() + 5); + } + } return true; } diff --git a/libcxx/test/std/algorithms/ranges_robust_against_nonbool_predicates.compile.pass.cpp b/libcxx/test/std/algorithms/ranges_robust_against_nonbool_predicates.compile.pass.cpp --- a/libcxx/test/std/algorithms/ranges_robust_against_nonbool_predicates.compile.pass.cpp +++ b/libcxx/test/std/algorithms/ranges_robust_against_nonbool_predicates.compile.pass.cpp @@ -102,7 +102,7 @@ //in_pred(std::ranges::partition_point, unary_pred); in_val_pred(std::ranges::lower_bound, in, x, binary_pred); in_val_pred(std::ranges::upper_bound, in, x, binary_pred); - //in_val_pred(std::ranges::equal_range, in, x, binary_pred); + in_val_pred(std::ranges::equal_range, in, x, binary_pred); in_val_pred(std::ranges::binary_search, in, x, binary_pred); // min diff --git a/libcxx/test/std/algorithms/ranges_robust_against_omitting_invoke.compile.pass.cpp b/libcxx/test/std/algorithms/ranges_robust_against_omitting_invoke.compile.pass.cpp --- a/libcxx/test/std/algorithms/ranges_robust_against_omitting_invoke.compile.pass.cpp +++ b/libcxx/test/std/algorithms/ranges_robust_against_omitting_invoke.compile.pass.cpp @@ -115,7 +115,7 @@ //in_pred(std::ranges::partition_point, in, &Foo::unary_pred, &Bar::val); in_val_pred(std::ranges::lower_bound, in, x, &Foo::binary_pred, &Bar::val); in_val_pred(std::ranges::upper_bound, in, x, &Foo::binary_pred, &Bar::val); - //in_val_pred(std::ranges::equal_range, in, x, &Foo::binary_pred, &Bar::val); + in_val_pred(std::ranges::equal_range, in, x, &Foo::binary_pred, &Bar::val); in_val_pred(std::ranges::binary_search, in, x, &Foo::binary_pred, &Bar::val); // min 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 @@ -74,7 +74,7 @@ static_assert(test(std::ranges::count_if, a, odd)); //static_assert(test(std::ranges::ends_with, a, a)); static_assert(test(std::ranges::equal, a, a)); -//static_assert(test(std::ranges::equal_range, a, 42)); +static_assert(test(std::ranges::equal_range, a, 42)); static_assert(test(std::ranges::fill, a, 42)); static_assert(test(std::ranges::fill_n, a, 10, 42)); static_assert(test(std::ranges::find, a, 42));