diff --git a/libcxx/include/__algorithm/ranges_binary_search.h b/libcxx/include/__algorithm/ranges_binary_search.h index b43de468ddabd..d89597e1be31c 100644 --- a/libcxx/include/__algorithm/ranges_binary_search.h +++ b/libcxx/include/__algorithm/ranges_binary_search.h @@ -36,7 +36,7 @@ struct __fn { _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr bool operator()(_Iter __first, _Sent __last, const _Type& __value, _Comp __comp = {}, _Proj __proj = {}) const { auto __ret = std::__lower_bound_impl<_RangeAlgPolicy>(__first, __last, __value, __comp, __proj); - return __ret != __last && !std::invoke(__comp, __value, std::invoke(__proj, *__first)); + return __ret != __last && !std::invoke(__comp, __value, std::invoke(__proj, *__ret)); } template (__first, __last, __value, __comp, __proj); - return __ret != __last && !std::invoke(__comp, __value, std::invoke(__proj, *__first)); + return __ret != __last && !std::invoke(__comp, __value, std::invoke(__proj, *__ret)); } }; } // namespace __binary_search diff --git a/libcxx/test/std/algorithms/alg.sorting/alg.binary.search/binary.search/ranges.binary_search.pass.cpp b/libcxx/test/std/algorithms/alg.sorting/alg.binary.search/binary.search/ranges.binary_search.pass.cpp index a1abdaff28b4c..cbeb7eb6fab53 100644 --- a/libcxx/test/std/algorithms/alg.sorting/alg.binary.search/binary.search/ranges.binary_search.pass.cpp +++ b/libcxx/test/std/algorithms/alg.sorting/alg.binary.search/binary.search/ranges.binary_search.pass.cpp @@ -131,6 +131,13 @@ constexpr void test_iterators() { auto range = std::ranges::subrange(It(a), Sent(It(a + 5))); assert(std::ranges::binary_search(range, 1)); } + + { // check that false is returned when the element doesn't exist, but an element with a greater value is in the range + int a[] = {1, 2, 4}; + assert(!std::ranges::binary_search(It(a), Sent(It(a + 3)), 3)); + auto range = std::ranges::subrange(It(a), Sent(It(a + 3))); + assert(!std::ranges::binary_search(range, 3)); + } } constexpr bool test() { diff --git a/libcxx/test/std/algorithms/alg.sorting/alg.binary.search/lower.bound/ranges.lower_bound.pass.cpp b/libcxx/test/std/algorithms/alg.sorting/alg.binary.search/lower.bound/ranges.lower_bound.pass.cpp index e7af57bd0156f..cffce51334440 100644 --- a/libcxx/test/std/algorithms/alg.sorting/alg.binary.search/lower.bound/ranges.lower_bound.pass.cpp +++ b/libcxx/test/std/algorithms/alg.sorting/alg.binary.search/lower.bound/ranges.lower_bound.pass.cpp @@ -194,6 +194,22 @@ constexpr void test_iterators() { assert(base(ret) == a); } } + + { // check that the middle of a range is returned when there are smaller and larger elements + { + int a[] = {1, 2, 3, 4, 6, 7, 8}; + auto ret = std::ranges::lower_bound(It(a), It(a + 7), 5); + assert(base(ret) == a + 4); + assert(*ret == 6); + } + { + int a[] = {1, 2, 3, 4, 6, 7, 8}; + auto range = std::ranges::subrange(It(a), It(a + 7)); + auto ret = std::ranges::lower_bound(range, 5); + assert(base(ret) == a + 4); + assert(*ret == 6); + } + } } constexpr bool test() { diff --git a/libcxx/test/std/algorithms/alg.sorting/alg.binary.search/upper.bound/ranges.upper_bound.pass.cpp b/libcxx/test/std/algorithms/alg.sorting/alg.binary.search/upper.bound/ranges.upper_bound.pass.cpp index 762fd7808389c..cab7831c2b59b 100644 --- a/libcxx/test/std/algorithms/alg.sorting/alg.binary.search/upper.bound/ranges.upper_bound.pass.cpp +++ b/libcxx/test/std/algorithms/alg.sorting/alg.binary.search/upper.bound/ranges.upper_bound.pass.cpp @@ -193,6 +193,22 @@ constexpr void test_iterators() { assert(base(ret) == a + 1); } } + + { // check that the middle of a range is returned when there are smaller and larger elements + { + int a[] = {1, 2, 3, 4, 6, 7, 8}; + auto ret = std::ranges::upper_bound(It(a), It(a + 7), 5); + assert(base(ret) == a + 4); + assert(*ret == 6); + } + { + int a[] = {1, 2, 3, 4, 6, 7, 8}; + auto range = std::ranges::subrange(It(a), It(a + 7)); + auto ret = std::ranges::upper_bound(range, 5); + assert(base(ret) == a + 4); + assert(*ret == 6); + } + } } constexpr bool test() {