Skip to content

Commit af7ab57

Browse files
committed
[ADT] Use adl_begin/end in hasNItems*
This is to make sure that ADT helpers consistently use argument dependent lookup when dealing with input ranges. This was a part of #87936 but reverted due to buildbot failures.
1 parent 5c3b059 commit af7ab57

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; }
@@ -961,6 +971,13 @@ TEST(STLExtrasTest, hasNItems) {
961971
EXPECT_TRUE(hasNItems(V3.begin(), V3.end(), 3, [](int x) { return x < 10; }));
962972
EXPECT_TRUE(hasNItems(V3.begin(), V3.end(), 0, [](int x) { return x > 10; }));
963973
EXPECT_TRUE(hasNItems(V3.begin(), V3.end(), 2, [](int x) { return x < 5; }));
974+
975+
// Make sure that we use the `begin`/`end` functions from `some_namespace`,
976+
// using ADL.
977+
some_namespace::List L;
978+
L.data = {0, 1, 2};
979+
EXPECT_FALSE(hasNItems(L, 2));
980+
EXPECT_TRUE(hasNItems(L, 3));
964981
}
965982

966983
TEST(STLExtras, hasNItemsOrMore) {
@@ -983,6 +1000,13 @@ TEST(STLExtras, hasNItemsOrMore) {
9831000
hasNItemsOrMore(V3.begin(), V3.end(), 3, [](int x) { return x > 10; }));
9841001
EXPECT_TRUE(
9851002
hasNItemsOrMore(V3.begin(), V3.end(), 2, [](int x) { return x < 5; }));
1003+
1004+
// Make sure that we use the `begin`/`end` functions from `some_namespace`,
1005+
// using ADL.
1006+
some_namespace::List L;
1007+
L.data = {0, 1, 2};
1008+
EXPECT_TRUE(hasNItemsOrMore(L, 1));
1009+
EXPECT_FALSE(hasNItems(L, 4));
9861010
}
9871011

9881012
TEST(STLExtras, hasNItemsOrLess) {
@@ -1016,6 +1040,13 @@ TEST(STLExtras, hasNItemsOrLess) {
10161040
hasNItemsOrLess(V3.begin(), V3.end(), 5, [](int x) { return x < 5; }));
10171041
EXPECT_FALSE(
10181042
hasNItemsOrLess(V3.begin(), V3.end(), 2, [](int x) { return x < 10; }));
1043+
1044+
// Make sure that we use the `begin`/`end` functions from `some_namespace`,
1045+
// using ADL.
1046+
some_namespace::List L;
1047+
L.data = {0, 1, 2};
1048+
EXPECT_FALSE(hasNItemsOrLess(L, 1));
1049+
EXPECT_TRUE(hasNItemsOrLess(L, 4));
10191050
}
10201051

10211052
TEST(STLExtras, MoveRange) {

0 commit comments

Comments
 (0)