Skip to content

Commit 6cdd861

Browse files
committed
[libc++] Make sure ranges algorithms and views handle boolean-testable correctly
Before this patch, we would fail to implicitly convert the result of predicates to bool, which means we'd potentially perform a copy or move construction of the boolean-testable, which isn't allowed. The same holds true for comparing iterators against sentinels, which is allowed to return a boolean-testable type. We already had tests aiming to ensure correct handling of these types, but they failed to provide appropriate coverage in several cases due to guaranteed RVO. This patch fixes the tests, adds tests for missing algorithms and views, and fixes the actual problems in the code. Fixes llvm#69074
1 parent e3c2eac commit 6cdd861

35 files changed

+557
-433
lines changed

libcxx/include/__algorithm/make_projected.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ decltype(auto) __make_projected_comp(_Comp& __comp, _Proj1& __proj1, _Proj2& __p
9696
return __comp;
9797

9898
} else {
99-
return [&](auto&& __lhs, auto&& __rhs) {
99+
return [&](auto&& __lhs, auto&& __rhs) -> bool {
100100
return std::invoke(__comp,
101101
std::invoke(__proj1, std::forward<decltype(__lhs)>(__lhs)),
102102
std::invoke(__proj2, std::forward<decltype(__rhs)>(__rhs)));

libcxx/include/__algorithm/ranges_find_if_not.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,14 +39,14 @@ struct __fn {
3939
indirect_unary_predicate<projected<_Ip, _Proj>> _Pred>
4040
_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr _Ip
4141
operator()(_Ip __first, _Sp __last, _Pred __pred, _Proj __proj = {}) const {
42-
auto __pred2 = [&](auto&& __e) { return !std::invoke(__pred, std::forward<decltype(__e)>(__e)); };
42+
auto __pred2 = [&](auto&& __e) -> bool { return !std::invoke(__pred, std::forward<decltype(__e)>(__e)); };
4343
return ranges::__find_if_impl(std::move(__first), std::move(__last), __pred2, __proj);
4444
}
4545

4646
template <input_range _Rp, class _Proj = identity, indirect_unary_predicate<projected<iterator_t<_Rp>, _Proj>> _Pred>
4747
_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr borrowed_iterator_t<_Rp>
4848
operator()(_Rp&& __r, _Pred __pred, _Proj __proj = {}) const {
49-
auto __pred2 = [&](auto&& __e) { return !std::invoke(__pred, std::forward<decltype(__e)>(__e)); };
49+
auto __pred2 = [&](auto&& __e) -> bool { return !std::invoke(__pred, std::forward<decltype(__e)>(__e)); };
5050
return ranges::__find_if_impl(ranges::begin(__r), ranges::end(__r), __pred2, __proj);
5151
}
5252
};

libcxx/include/__algorithm/ranges_max.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ struct __fn {
5656
operator()(initializer_list<_Tp> __il, _Comp __comp = {}, _Proj __proj = {}) const {
5757
_LIBCPP_ASSERT_UNCATEGORIZED(__il.begin() != __il.end(), "initializer_list must contain at least one element");
5858

59-
auto __comp_lhs_rhs_swapped = [&](auto&& __lhs, auto&& __rhs) { return std::invoke(__comp, __rhs, __lhs); };
59+
auto __comp_lhs_rhs_swapped = [&](auto&& __lhs, auto&& __rhs) -> bool { return std::invoke(__comp, __rhs, __lhs); };
6060
return *ranges::__min_element_impl(__il.begin(), __il.end(), __comp_lhs_rhs_swapped, __proj);
6161
}
6262

@@ -72,7 +72,9 @@ struct __fn {
7272
_LIBCPP_ASSERT_UNCATEGORIZED(__first != __last, "range must contain at least one element");
7373

7474
if constexpr (forward_range<_Rp> && !__is_cheap_to_copy<range_value_t<_Rp>>) {
75-
auto __comp_lhs_rhs_swapped = [&](auto&& __lhs, auto&& __rhs) { return std::invoke(__comp, __rhs, __lhs); };
75+
auto __comp_lhs_rhs_swapped = [&](auto&& __lhs, auto&& __rhs) -> bool {
76+
return std::invoke(__comp, __rhs, __lhs);
77+
};
7678
return *ranges::__min_element_impl(std::move(__first), std::move(__last), __comp_lhs_rhs_swapped, __proj);
7779
} else {
7880
range_value_t<_Rp> __result = *__first;

libcxx/include/__algorithm/ranges_max_element.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ struct __fn {
3737
indirect_strict_weak_order<projected<_Ip, _Proj>> _Comp = ranges::less>
3838
_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr _Ip
3939
operator()(_Ip __first, _Sp __last, _Comp __comp = {}, _Proj __proj = {}) const {
40-
auto __comp_lhs_rhs_swapped = [&](auto&& __lhs, auto&& __rhs) { return std::invoke(__comp, __rhs, __lhs); };
40+
auto __comp_lhs_rhs_swapped = [&](auto&& __lhs, auto&& __rhs) -> bool { return std::invoke(__comp, __rhs, __lhs); };
4141
return ranges::__min_element_impl(__first, __last, __comp_lhs_rhs_swapped, __proj);
4242
}
4343

@@ -46,7 +46,7 @@ struct __fn {
4646
indirect_strict_weak_order<projected<iterator_t<_Rp>, _Proj>> _Comp = ranges::less>
4747
_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr borrowed_iterator_t<_Rp>
4848
operator()(_Rp&& __r, _Comp __comp = {}, _Proj __proj = {}) const {
49-
auto __comp_lhs_rhs_swapped = [&](auto&& __lhs, auto&& __rhs) { return std::invoke(__comp, __rhs, __lhs); };
49+
auto __comp_lhs_rhs_swapped = [&](auto&& __lhs, auto&& __rhs) -> bool { return std::invoke(__comp, __rhs, __lhs); };
5050
return ranges::__min_element_impl(ranges::begin(__r), ranges::end(__r), __comp_lhs_rhs_swapped, __proj);
5151
}
5252
};

libcxx/include/__algorithm/ranges_remove.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ struct __fn {
3636
requires indirect_binary_predicate<ranges::equal_to, projected<_Iter, _Proj>, const _Type*>
3737
_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr subrange<_Iter>
3838
operator()(_Iter __first, _Sent __last, const _Type& __value, _Proj __proj = {}) const {
39-
auto __pred = [&](auto&& __other) { return __value == __other; };
39+
auto __pred = [&](auto&& __other) -> bool { return __value == __other; };
4040
return ranges::__remove_if_impl(std::move(__first), std::move(__last), __pred, __proj);
4141
}
4242

@@ -45,7 +45,7 @@ struct __fn {
4545
indirect_binary_predicate<ranges::equal_to, projected<iterator_t<_Range>, _Proj>, const _Type*>
4646
_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr borrowed_subrange_t<_Range>
4747
operator()(_Range&& __range, const _Type& __value, _Proj __proj = {}) const {
48-
auto __pred = [&](auto&& __other) { return __value == __other; };
48+
auto __pred = [&](auto&& __other) -> bool { return __value == __other; };
4949
return ranges::__remove_if_impl(ranges::begin(__range), ranges::end(__range), __pred, __proj);
5050
}
5151
};

libcxx/include/__algorithm/ranges_remove_copy.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ struct __fn {
4747
indirect_binary_predicate<ranges::equal_to, projected<_InIter, _Proj>, const _Type*>
4848
_LIBCPP_HIDE_FROM_ABI constexpr remove_copy_result<_InIter, _OutIter>
4949
operator()(_InIter __first, _Sent __last, _OutIter __result, const _Type& __value, _Proj __proj = {}) const {
50-
auto __pred = [&](auto&& __val) { return __value == __val; };
50+
auto __pred = [&](auto&& __val) -> bool { return __value == __val; };
5151
return ranges::__remove_copy_if_impl(std::move(__first), std::move(__last), std::move(__result), __pred, __proj);
5252
}
5353

@@ -56,7 +56,7 @@ struct __fn {
5656
indirect_binary_predicate<ranges::equal_to, projected<iterator_t<_Range>, _Proj>, const _Type*>
5757
_LIBCPP_HIDE_FROM_ABI constexpr remove_copy_result<borrowed_iterator_t<_Range>, _OutIter>
5858
operator()(_Range&& __range, _OutIter __result, const _Type& __value, _Proj __proj = {}) const {
59-
auto __pred = [&](auto&& __val) { return __value == __val; };
59+
auto __pred = [&](auto&& __val) -> bool { return __value == __val; };
6060
return ranges::__remove_copy_if_impl(
6161
ranges::begin(__range), ranges::end(__range), std::move(__result), __pred, __proj);
6262
}

libcxx/include/__algorithm/ranges_replace.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ struct __fn {
3636
indirect_binary_predicate<ranges::equal_to, projected<_Iter, _Proj>, const _Type1*>
3737
_LIBCPP_HIDE_FROM_ABI constexpr _Iter operator()(
3838
_Iter __first, _Sent __last, const _Type1& __old_value, const _Type2& __new_value, _Proj __proj = {}) const {
39-
auto __pred = [&](const auto& __val) { return __val == __old_value; };
39+
auto __pred = [&](const auto& __val) -> bool { return __val == __old_value; };
4040
return ranges::__replace_if_impl(std::move(__first), std::move(__last), __pred, __new_value, __proj);
4141
}
4242

@@ -45,7 +45,7 @@ struct __fn {
4545
indirect_binary_predicate<ranges::equal_to, projected<iterator_t<_Range>, _Proj>, const _Type1*>
4646
_LIBCPP_HIDE_FROM_ABI constexpr borrowed_iterator_t<_Range>
4747
operator()(_Range&& __range, const _Type1& __old_value, const _Type2& __new_value, _Proj __proj = {}) const {
48-
auto __pred = [&](auto&& __val) { return __val == __old_value; };
48+
auto __pred = [&](auto&& __val) -> bool { return __val == __old_value; };
4949
return ranges::__replace_if_impl(ranges::begin(__range), ranges::end(__range), __pred, __new_value, __proj);
5050
}
5151
};

libcxx/include/__algorithm/ranges_replace_copy.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ struct __fn {
5353
const _OldType& __old_value,
5454
const _NewType& __new_value,
5555
_Proj __proj = {}) const {
56-
auto __pred = [&](const auto& __value) { return __value == __old_value; };
56+
auto __pred = [&](const auto& __value) -> bool { return __value == __old_value; };
5757
return ranges::__replace_copy_if_impl(
5858
std::move(__first), std::move(__last), std::move(__result), __pred, __new_value, __proj);
5959
}
@@ -68,7 +68,7 @@ struct __fn {
6868
_LIBCPP_HIDE_FROM_ABI constexpr replace_copy_result<borrowed_iterator_t<_Range>, _OutIter> operator()(
6969
_Range&& __range, _OutIter __result, const _OldType& __old_value, const _NewType& __new_value, _Proj __proj = {})
7070
const {
71-
auto __pred = [&](const auto& __value) { return __value == __old_value; };
71+
auto __pred = [&](const auto& __value) -> bool { return __value == __old_value; };
7272
return ranges::__replace_copy_if_impl(
7373
ranges::begin(__range), ranges::end(__range), std::move(__result), __pred, __new_value, __proj);
7474
}

libcxx/include/__algorithm/ranges_upper_bound.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ struct __fn {
3939
indirect_strict_weak_order<const _Type*, projected<_Iter, _Proj>> _Comp = ranges::less>
4040
_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr _Iter
4141
operator()(_Iter __first, _Sent __last, const _Type& __value, _Comp __comp = {}, _Proj __proj = {}) const {
42-
auto __comp_lhs_rhs_swapped = [&](const auto& __lhs, const auto& __rhs) {
42+
auto __comp_lhs_rhs_swapped = [&](const auto& __lhs, const auto& __rhs) -> bool {
4343
return !std::invoke(__comp, __rhs, __lhs);
4444
};
4545

@@ -52,7 +52,7 @@ struct __fn {
5252
indirect_strict_weak_order<const _Type*, projected<iterator_t<_Range>, _Proj>> _Comp = ranges::less>
5353
_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr borrowed_iterator_t<_Range>
5454
operator()(_Range&& __r, const _Type& __value, _Comp __comp = {}, _Proj __proj = {}) const {
55-
auto __comp_lhs_rhs_swapped = [&](const auto& __lhs, const auto& __rhs) {
55+
auto __comp_lhs_rhs_swapped = [&](const auto& __lhs, const auto& __rhs) -> bool {
5656
return !std::invoke(__comp, __rhs, __lhs);
5757
};
5858

libcxx/include/__memory/ranges_uninitialized_algorithms.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -196,7 +196,7 @@ struct __fn {
196196
operator()(_InputIterator __ifirst, _Sentinel1 __ilast, _OutputIterator __ofirst, _Sentinel2 __olast) const {
197197
using _ValueType = remove_reference_t<iter_reference_t<_OutputIterator>>;
198198

199-
auto __stop_copying = [&__olast](auto&& __out_iter) { return __out_iter == __olast; };
199+
auto __stop_copying = [&__olast](auto&& __out_iter) -> bool { return __out_iter == __olast; };
200200
auto __result = std::__uninitialized_copy<_ValueType>(
201201
std::move(__ifirst), std::move(__ilast), std::move(__ofirst), __stop_copying);
202202
return {_VSTD::move(__result.first), _VSTD::move(__result.second)};
@@ -233,7 +233,7 @@ struct __fn {
233233
operator()(_InputIterator __ifirst, iter_difference_t<_InputIterator> __n,
234234
_OutputIterator __ofirst, _Sentinel __olast) const {
235235
using _ValueType = remove_reference_t<iter_reference_t<_OutputIterator>>;
236-
auto __stop_copying = [&__olast](auto&& __out_iter) { return __out_iter == __olast; };
236+
auto __stop_copying = [&__olast](auto&& __out_iter) -> bool { return __out_iter == __olast; };
237237
auto __result =
238238
std::__uninitialized_copy_n<_ValueType>(std::move(__ifirst), __n, std::move(__ofirst), __stop_copying);
239239
return {_VSTD::move(__result.first), _VSTD::move(__result.second)};
@@ -263,7 +263,7 @@ struct __fn {
263263
operator()(_InputIterator __ifirst, _Sentinel1 __ilast, _OutputIterator __ofirst, _Sentinel2 __olast) const {
264264
using _ValueType = remove_reference_t<iter_reference_t<_OutputIterator>>;
265265
auto __iter_move = [](auto&& __iter) -> decltype(auto) { return ranges::iter_move(__iter); };
266-
auto __stop_moving = [&__olast](auto&& __out_iter) { return __out_iter == __olast; };
266+
auto __stop_moving = [&__olast](auto&& __out_iter) -> bool { return __out_iter == __olast; };
267267
auto __result = std::__uninitialized_move<_ValueType>(
268268
std::move(__ifirst), std::move(__ilast), std::move(__ofirst), __stop_moving, __iter_move);
269269
return {_VSTD::move(__result.first), _VSTD::move(__result.second)};
@@ -301,7 +301,7 @@ struct __fn {
301301
_OutputIterator __ofirst, _Sentinel __olast) const {
302302
using _ValueType = remove_reference_t<iter_reference_t<_OutputIterator>>;
303303
auto __iter_move = [](auto&& __iter) -> decltype(auto) { return ranges::iter_move(__iter); };
304-
auto __stop_moving = [&__olast](auto&& __out_iter) { return __out_iter == __olast; };
304+
auto __stop_moving = [&__olast](auto&& __out_iter) -> bool { return __out_iter == __olast; };
305305
auto __result = std::__uninitialized_move_n<_ValueType>(
306306
std::move(__ifirst), __n, std::move(__ofirst), __stop_moving, __iter_move);
307307
return {_VSTD::move(__result.first), _VSTD::move(__result.second)};

libcxx/include/__ranges/chunk_by_view.h

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,6 @@
1616
#include <__config>
1717
#include <__functional/bind_back.h>
1818
#include <__functional/invoke.h>
19-
#include <__functional/not_fn.h>
20-
#include <__functional/reference_wrapper.h>
2119
#include <__iterator/concepts.h>
2220
#include <__iterator/default_sentinel.h>
2321
#include <__iterator/iterator_traits.h>
@@ -69,10 +67,11 @@ class chunk_by_view : public view_interface<chunk_by_view<_View, _Pred>> {
6967
_LIBCPP_HIDE_FROM_ABI constexpr iterator_t<_View> __find_next(iterator_t<_View> __current) {
7068
_LIBCPP_ASSERT_UNCATEGORIZED(
7169
__pred_.__has_value(), "Trying to call __find_next() on a chunk_by_view that does not have a valid predicate.");
72-
73-
return ranges::next(ranges::adjacent_find(__current, ranges::end(__base_), std::not_fn(std::ref(*__pred_))),
74-
1,
75-
ranges::end(__base_));
70+
auto __reversed_pred = [this]<class _Tp, class _Up>(_Tp&& __x, _Up&& __y) -> bool {
71+
return !std::invoke(*__pred_, std::forward<_Tp>(__x), std::forward<_Up>(__y));
72+
};
73+
return ranges::next(
74+
ranges::adjacent_find(__current, ranges::end(__base_), __reversed_pred), 1, ranges::end(__base_));
7675
}
7776

7877
_LIBCPP_HIDE_FROM_ABI constexpr iterator_t<_View> __find_prev(iterator_t<_View> __current)
@@ -85,7 +84,7 @@ class chunk_by_view : public view_interface<chunk_by_view<_View, _Pred>> {
8584

8685
auto __first = ranges::begin(__base_);
8786
reverse_view __reversed{subrange{__first, __current}};
88-
auto __reversed_pred = [this]<class _Tp, class _Up>(_Tp&& __x, _Up&& __y) {
87+
auto __reversed_pred = [this]<class _Tp, class _Up>(_Tp&& __x, _Up&& __y) -> bool {
8988
return !std::invoke(*__pred_, std::forward<_Up>(__y), std::forward<_Tp>(__x));
9089
};
9190
return ranges::prev(ranges::adjacent_find(__reversed, __reversed_pred).base(), 1, std::move(__first));

libcxx/test/std/algorithms/alg.modifying.operations/alg.remove/ranges.remove.pass.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@
2525
#include <ranges>
2626

2727
#include "almost_satisfies_types.h"
28-
#include "boolean_testable.h"
2928
#include "test_iterators.h"
3029

3130
template <class Iter, class Sent = sentinel_wrapper<Iter>>

libcxx/test/std/algorithms/alg.modifying.operations/alg.remove/ranges.remove_if.pass.cpp

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@
2525
#include <ranges>
2626

2727
#include "almost_satisfies_types.h"
28-
#include "boolean_testable.h"
2928
#include "test_iterators.h"
3029

3130
struct FalsePredicate {
@@ -197,20 +196,6 @@ constexpr bool test() {
197196
}
198197
}
199198

200-
{
201-
// check that the implicit conversion to bool works
202-
{
203-
int a[] = {1, 2, 3, 4};
204-
auto ret = std::ranges::remove_if(a, a + 4, [](const int& i) { return BooleanTestable{i == 3}; });
205-
assert(ret.begin() == a + 3);
206-
}
207-
{
208-
int a[] = {1, 2, 3, 4};
209-
auto ret = std::ranges::remove_if(a, [](const int& b) { return BooleanTestable{b == 3}; });
210-
assert(ret.begin() == a + 3);
211-
}
212-
}
213-
214199
return true;
215200
}
216201
// clang-format on

libcxx/test/std/algorithms/alg.modifying.operations/alg.replace/ranges.replace.pass.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@
2727
#include <ranges>
2828

2929
#include "almost_satisfies_types.h"
30-
#include "boolean_testable.h"
3130
#include "test_iterators.h"
3231

3332
template <class Iter, class Sent = sentinel_wrapper<Iter>>

libcxx/test/std/algorithms/alg.modifying.operations/alg.replace/ranges.replace_if.pass.cpp

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@
2626
#include <ranges>
2727

2828
#include "almost_satisfies_types.h"
29-
#include "boolean_testable.h"
3029
#include "test_iterators.h"
3130

3231
struct FalsePredicate {
@@ -133,19 +132,6 @@ constexpr bool test() {
133132
}
134133
}
135134

136-
{ // check that the implicit conversion to bool works
137-
{
138-
int a[] = {1, 2, 2, 4};
139-
auto ret = std::ranges::replace_if(std::begin(a), std::end(a), [](int) { return BooleanTestable{false}; }, 2);
140-
assert(ret == std::end(a));
141-
}
142-
{
143-
int a[] = {1, 2, 2, 4};
144-
auto ret = std::ranges::replace_if(a, [](int) { return BooleanTestable{false}; }, 2);
145-
assert(ret == std::end(a));
146-
}
147-
}
148-
149135
{ // check that std::ranges::dangling is returned
150136
[[maybe_unused]] std::same_as<std::ranges::dangling> decltype(auto) ret =
151137
std::ranges::replace_if(std::array {1, 2, 3, 4}, [](int) { return false; }, 1);

libcxx/test/std/algorithms/alg.nonmodifying/alg.adjacent.find/ranges.adjacent_find.pass.cpp

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@
2626
#include <ranges>
2727

2828
#include "almost_satisfies_types.h"
29-
#include "boolean_testable.h"
3029
#include "test_iterators.h"
3130

3231
template <class Iter, class Sent = Iter>
@@ -172,19 +171,6 @@ constexpr bool test() {
172171
}
173172
}
174173

175-
{ // check that the implicit conversion to bool works
176-
{
177-
int a[] = {1, 2, 2, 4};
178-
auto ret = std::ranges::adjacent_find(a, a + 4, [](int i, int j) { return BooleanTestable{i == j}; });
179-
assert(ret == a + 1);
180-
}
181-
{
182-
int a[] = {1, 2, 2, 4};
183-
auto ret = std::ranges::adjacent_find(a, [](int i, int j) { return BooleanTestable{i == j}; });
184-
assert(ret == a + 1);
185-
}
186-
}
187-
188174
return true;
189175
}
190176

libcxx/test/std/algorithms/alg.nonmodifying/alg.find.first.of/ranges.find_first_of.pass.cpp

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@
3030
#include <ranges>
3131

3232
#include "almost_satisfies_types.h"
33-
#include "boolean_testable.h"
3433
#include "test_iterators.h"
3534

3635
template <class Iter1, class Iter2 = int*, class Sent1 = Iter1, class Sent2 = Iter2>
@@ -194,19 +193,6 @@ constexpr bool test() {
194193
}
195194
}
196195

197-
{ // check that the implicit conversion to bool works
198-
StrictComparable<int> a[] = {1, 2, 3, 4};
199-
StrictComparable<int> b[] = {2, 3};
200-
{
201-
auto ret = std::ranges::find_first_of(a, std::end(a), b, std::end(b));
202-
assert(ret == a + 1);
203-
}
204-
{
205-
auto ret = std::ranges::find_first_of(a, b);
206-
assert(ret == a + 1);
207-
}
208-
}
209-
210196
{ // check that the complexity requirements are met
211197
int a[] = {1, 2, 3, 4};
212198
int b[] = {2, 3};

libcxx/test/std/algorithms/alg.nonmodifying/alg.find/ranges.find.pass.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@
2727
#include <vector>
2828

2929
#include "almost_satisfies_types.h"
30-
#include "boolean_testable.h"
3130
#include "test_iterators.h"
3231

3332
struct NotEqualityComparable {};

libcxx/test/std/algorithms/alg.nonmodifying/alg.find/ranges.find_if.pass.cpp

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@
2424
#include <ranges>
2525

2626
#include "almost_satisfies_types.h"
27-
#include "boolean_testable.h"
2827
#include "test_iterators.h"
2928

3029
struct Predicate {
@@ -224,20 +223,6 @@ constexpr bool test() {
224223
}
225224
}
226225

227-
{
228-
// check that the implicit conversion to bool works
229-
{
230-
int a[] = {1, 2, 3, 4};
231-
auto ret = std::ranges::find_if(a, a + 4, [](const int& i) { return BooleanTestable{i == 3}; });
232-
assert(ret == a + 2);
233-
}
234-
{
235-
int a[] = {1, 2, 3, 4};
236-
auto ret = std::ranges::find_if(a, [](const int& b) { return BooleanTestable{b == 3}; });
237-
assert(ret == a + 2);
238-
}
239-
}
240-
241226
return true;
242227
}
243228

0 commit comments

Comments
 (0)