Skip to content

Commit cd7b444

Browse files
committed
[libc++][ranges] Add implicit conversion to bool test for ranges::find{, if, if_not}
Reviewed By: ldionne, var-const, #libc Spies: libcxx-commits Differential Revision: https://reviews.llvm.org/D122011
1 parent 3031fa8 commit cd7b444

File tree

4 files changed

+106
-0
lines changed

4 files changed

+106
-0
lines changed

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

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

2727
#include "almost_satisfies_types.h"
28+
#include "boolean_testable.h"
2829
#include "test_iterators.h"
2930

3031
struct NotEqualityComparable {};
@@ -247,6 +248,20 @@ constexpr bool test() {
247248
}
248249
}
249250

251+
{
252+
// check that the implicit conversion to bool works
253+
{
254+
StrictComparable<int> a[] = {1, 2, 3, 4};
255+
auto ret = std::ranges::find(a, a + 4, StrictComparable<int>{2});
256+
assert(ret == a + 1);
257+
}
258+
{
259+
StrictComparable<int> a[] = {1, 2, 3, 4};
260+
auto ret = std::ranges::find(a, StrictComparable<int>{2});
261+
assert(ret == a + 1);
262+
}
263+
}
264+
250265
return true;
251266
}
252267

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

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

2727
#include "almost_satisfies_types.h"
28+
#include "boolean_testable.h"
2829
#include "test_iterators.h"
2930

3031
struct Predicate {
@@ -224,6 +225,20 @@ constexpr bool test() {
224225
}
225226
}
226227

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

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

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

2727
#include "almost_satisfies_types.h"
28+
#include "boolean_testable.h"
2829
#include "test_iterators.h"
2930

3031
struct Predicate {
@@ -218,6 +219,20 @@ constexpr bool test() {
218219
}
219220
}
220221

222+
{
223+
// check that the implicit conversion to bool works
224+
{
225+
int a[] = {1, 2, 3, 4};
226+
auto ret = std::ranges::find_if_not(a, a + 4, [](const int& i) { return BooleanTestable{i != 3}; });
227+
assert(ret == a + 2);
228+
}
229+
{
230+
int a[] = {1, 2, 3, 4};
231+
auto ret = std::ranges::find_if_not(a, [](const int& b) { return BooleanTestable{b != 3}; });
232+
assert(ret == a + 2);
233+
}
234+
}
235+
221236
return true;
222237
}
223238

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#ifndef LIBCXX_TEST_SUPPORT_BOOLEAN_TESTABLE_H
10+
#define LIBCXX_TEST_SUPPORT_BOOLEAN_TESTABLE_H
11+
12+
#if TEST_STD_VER > 17
13+
14+
class BooleanTestable {
15+
public:
16+
constexpr operator bool() const {
17+
return value_;
18+
}
19+
20+
friend constexpr BooleanTestable operator==(const BooleanTestable& lhs, const BooleanTestable& rhs) {
21+
return lhs.value_ == rhs.value_;
22+
}
23+
24+
friend constexpr BooleanTestable operator!=(const BooleanTestable& lhs, const BooleanTestable& rhs) {
25+
return !(lhs == rhs);
26+
}
27+
28+
constexpr BooleanTestable operator!() {
29+
return BooleanTestable{!value_};
30+
}
31+
32+
// this class should behave like a bool, so the constructor shouldn't be explicit
33+
constexpr BooleanTestable(bool value) : value_{value} {}
34+
constexpr BooleanTestable(const BooleanTestable&) = delete;
35+
constexpr BooleanTestable(BooleanTestable&&) = delete;
36+
37+
private:
38+
bool value_;
39+
};
40+
41+
template <class T>
42+
class StrictComparable {
43+
public:
44+
// this shouldn't be explicit to make it easier to initlaize inside arrays (which it almost always is)
45+
constexpr StrictComparable(T value) : value_{value} {}
46+
47+
friend constexpr BooleanTestable operator==(const StrictComparable& lhs, const StrictComparable& rhs) {
48+
return (lhs.value_ == rhs.value_);
49+
}
50+
51+
friend constexpr BooleanTestable operator!=(const StrictComparable& lhs, const StrictComparable& rhs) {
52+
return !(lhs == rhs);
53+
}
54+
55+
private:
56+
T value_;
57+
};
58+
59+
#endif // TEST_STD_VER > 17
60+
61+
#endif // LIBCXX_TEST_SUPPORT_BOOLEAN_TESTABLE_H

0 commit comments

Comments
 (0)