Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions llvm/include/llvm/ADT/STLExtras.h
Original file line number Diff line number Diff line change
Expand Up @@ -2562,19 +2562,19 @@ bool hasNItemsOrLess(

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

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

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

/// Returns a raw pointer that represents the same address as the argument.
Expand Down
31 changes: 31 additions & 0 deletions llvm/unittests/ADT/STLExtrasTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -421,6 +421,16 @@ void swap(some_struct &lhs, some_struct &rhs) {
rhs.swap_val = "rhs";
}

struct List {
std::list<int> data;
};

std::list<int>::const_iterator begin(const List &list) {
return list.data.begin();
}

std::list<int>::const_iterator end(const List &list) { return list.data.end(); }

struct requires_move {};
int *begin(requires_move &&) { return nullptr; }
int *end(requires_move &&) { return nullptr; }
Expand Down Expand Up @@ -961,6 +971,13 @@ TEST(STLExtrasTest, hasNItems) {
EXPECT_TRUE(hasNItems(V3.begin(), V3.end(), 3, [](int x) { return x < 10; }));
EXPECT_TRUE(hasNItems(V3.begin(), V3.end(), 0, [](int x) { return x > 10; }));
EXPECT_TRUE(hasNItems(V3.begin(), V3.end(), 2, [](int x) { return x < 5; }));

// Make sure that we use the `begin`/`end` functions from `some_namespace`,
// using ADL.
some_namespace::List L;
L.data = {0, 1, 2};
EXPECT_FALSE(hasNItems(L, 2));
EXPECT_TRUE(hasNItems(L, 3));
}

TEST(STLExtras, hasNItemsOrMore) {
Expand All @@ -983,6 +1000,13 @@ TEST(STLExtras, hasNItemsOrMore) {
hasNItemsOrMore(V3.begin(), V3.end(), 3, [](int x) { return x > 10; }));
EXPECT_TRUE(
hasNItemsOrMore(V3.begin(), V3.end(), 2, [](int x) { return x < 5; }));

// Make sure that we use the `begin`/`end` functions from `some_namespace`,
// using ADL.
some_namespace::List L;
L.data = {0, 1, 2};
EXPECT_TRUE(hasNItemsOrMore(L, 1));
EXPECT_FALSE(hasNItems(L, 4));
}

TEST(STLExtras, hasNItemsOrLess) {
Expand Down Expand Up @@ -1016,6 +1040,13 @@ TEST(STLExtras, hasNItemsOrLess) {
hasNItemsOrLess(V3.begin(), V3.end(), 5, [](int x) { return x < 5; }));
EXPECT_FALSE(
hasNItemsOrLess(V3.begin(), V3.end(), 2, [](int x) { return x < 10; }));

// Make sure that we use the `begin`/`end` functions from `some_namespace`,
// using ADL.
some_namespace::List L;
L.data = {0, 1, 2};
EXPECT_FALSE(hasNItemsOrLess(L, 1));
EXPECT_TRUE(hasNItemsOrLess(L, 4));
}

TEST(STLExtras, MoveRange) {
Expand Down