Skip to content

Commit 8338fbe

Browse files
authored
[ADT] Use adl_begin/end in hasNItems* (llvm#130524)
This is to make sure that ADT helpers consistently use argument dependent lookup when dealing with input ranges. This was a part of llvm#87936 but reverted due to buildbot failures.
1 parent 666540c commit 8338fbe

File tree

2 files changed

+34
-3
lines changed

2 files changed

+34
-3
lines changed

llvm/include/llvm/ADT/STLExtras.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2562,19 +2562,19 @@ bool hasNItemsOrLess(
25622562

25632563
/// Returns true if the given container has exactly N items
25642564
template <typename ContainerTy> bool hasNItems(ContainerTy &&C, unsigned N) {
2565-
return hasNItems(std::begin(C), std::end(C), N);
2565+
return hasNItems(adl_begin(C), adl_end(C), N);
25662566
}
25672567

25682568
/// Returns true if the given container has N or more items
25692569
template <typename ContainerTy>
25702570
bool hasNItemsOrMore(ContainerTy &&C, unsigned N) {
2571-
return hasNItemsOrMore(std::begin(C), std::end(C), N);
2571+
return hasNItemsOrMore(adl_begin(C), adl_end(C), N);
25722572
}
25732573

25742574
/// Returns true if the given container has N or less items
25752575
template <typename ContainerTy>
25762576
bool hasNItemsOrLess(ContainerTy &&C, unsigned N) {
2577-
return hasNItemsOrLess(std::begin(C), std::end(C), N);
2577+
return hasNItemsOrLess(adl_begin(C), adl_end(C), N);
25782578
}
25792579

25802580
/// Returns a raw pointer that represents the same address as the argument.

llvm/unittests/ADT/STLExtrasTest.cpp

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -421,6 +421,16 @@ void swap(some_struct &lhs, some_struct &rhs) {
421421
rhs.swap_val = "rhs";
422422
}
423423

424+
struct List {
425+
std::list<int> data;
426+
};
427+
428+
std::list<int>::const_iterator begin(const List &list) {
429+
return list.data.begin();
430+
}
431+
432+
std::list<int>::const_iterator end(const List &list) { return list.data.end(); }
433+
424434
struct requires_move {};
425435
int *begin(requires_move &&) { return nullptr; }
426436
int *end(requires_move &&) { return nullptr; }
@@ -981,6 +991,13 @@ TEST(STLExtrasTest, hasNItems) {
981991
EXPECT_TRUE(hasNItems(V3.begin(), V3.end(), 3, [](int x) { return x < 10; }));
982992
EXPECT_TRUE(hasNItems(V3.begin(), V3.end(), 0, [](int x) { return x > 10; }));
983993
EXPECT_TRUE(hasNItems(V3.begin(), V3.end(), 2, [](int x) { return x < 5; }));
994+
995+
// Make sure that we use the `begin`/`end` functions from `some_namespace`,
996+
// using ADL.
997+
some_namespace::List L;
998+
L.data = {0, 1, 2};
999+
EXPECT_FALSE(hasNItems(L, 2));
1000+
EXPECT_TRUE(hasNItems(L, 3));
9841001
}
9851002

9861003
TEST(STLExtras, hasNItemsOrMore) {
@@ -1003,6 +1020,13 @@ TEST(STLExtras, hasNItemsOrMore) {
10031020
hasNItemsOrMore(V3.begin(), V3.end(), 3, [](int x) { return x > 10; }));
10041021
EXPECT_TRUE(
10051022
hasNItemsOrMore(V3.begin(), V3.end(), 2, [](int x) { return x < 5; }));
1023+
1024+
// Make sure that we use the `begin`/`end` functions from `some_namespace`,
1025+
// using ADL.
1026+
some_namespace::List L;
1027+
L.data = {0, 1, 2};
1028+
EXPECT_TRUE(hasNItemsOrMore(L, 1));
1029+
EXPECT_FALSE(hasNItems(L, 4));
10061030
}
10071031

10081032
TEST(STLExtras, hasNItemsOrLess) {
@@ -1036,6 +1060,13 @@ TEST(STLExtras, hasNItemsOrLess) {
10361060
hasNItemsOrLess(V3.begin(), V3.end(), 5, [](int x) { return x < 5; }));
10371061
EXPECT_FALSE(
10381062
hasNItemsOrLess(V3.begin(), V3.end(), 2, [](int x) { return x < 10; }));
1063+
1064+
// Make sure that we use the `begin`/`end` functions from `some_namespace`,
1065+
// using ADL.
1066+
some_namespace::List L;
1067+
L.data = {0, 1, 2};
1068+
EXPECT_FALSE(hasNItemsOrLess(L, 1));
1069+
EXPECT_TRUE(hasNItemsOrLess(L, 4));
10391070
}
10401071

10411072
TEST(STLExtras, MoveRange) {

0 commit comments

Comments
 (0)