Skip to content

Commit e427f06

Browse files
authored
[ADT] Use adl_begin in make_first_range and make_second_range (#130521)
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 9ef7287 commit e427f06

File tree

2 files changed

+20
-3
lines changed

2 files changed

+20
-3
lines changed

llvm/include/llvm/ADT/STLExtras.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1434,7 +1434,7 @@ template <typename EltTy, typename FirstTy> class first_or_second_type {
14341434

14351435
/// Given a container of pairs, return a range over the first elements.
14361436
template <typename ContainerTy> auto make_first_range(ContainerTy &&c) {
1437-
using EltTy = decltype((*std::begin(c)));
1437+
using EltTy = decltype(*adl_begin(c));
14381438
return llvm::map_range(std::forward<ContainerTy>(c),
14391439
[](EltTy elt) -> typename detail::first_or_second_type<
14401440
EltTy, decltype((elt.first))>::type {
@@ -1444,7 +1444,7 @@ template <typename ContainerTy> auto make_first_range(ContainerTy &&c) {
14441444

14451445
/// Given a container of pairs, return a range over the second elements.
14461446
template <typename ContainerTy> auto make_second_range(ContainerTy &&c) {
1447-
using EltTy = decltype((*std::begin(c)));
1447+
using EltTy = decltype(*adl_begin(c));
14481448
return llvm::map_range(
14491449
std::forward<ContainerTy>(c),
14501450
[](EltTy elt) ->

llvm/unittests/ADT/STLExtrasTest.cpp

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -428,9 +428,17 @@ struct List {
428428
std::list<int>::const_iterator begin(const List &list) {
429429
return list.data.begin();
430430
}
431-
432431
std::list<int>::const_iterator end(const List &list) { return list.data.end(); }
433432

433+
struct Pairs {
434+
std::vector<std::pair<std::string, int>> data;
435+
using const_iterator =
436+
std::vector<std::pair<std::string, int>>::const_iterator;
437+
};
438+
439+
Pairs::const_iterator begin(const Pairs &p) { return p.data.begin(); }
440+
Pairs::const_iterator end(const Pairs &p) { return p.data.end(); }
441+
434442
struct requires_move {};
435443
int *begin(requires_move &&) { return nullptr; }
436444
int *end(requires_move &&) { return nullptr; }
@@ -524,6 +532,15 @@ TEST(STLExtrasTest, ConcatRangeADL) {
524532
EXPECT_THAT(concat<const int>(S0, S1), ElementsAre(1, 2, 3, 4));
525533
}
526534

535+
TEST(STLExtrasTest, MakeFirstSecondRangeADL) {
536+
// Make sure that we use the `begin`/`end` functions from `some_namespace`,
537+
// using ADL.
538+
some_namespace::Pairs Pairs;
539+
Pairs.data = {{"foo", 1}, {"bar", 2}};
540+
EXPECT_THAT(make_first_range(Pairs), ElementsAre("foo", "bar"));
541+
EXPECT_THAT(make_second_range(Pairs), ElementsAre(1, 2));
542+
}
543+
527544
template <typename T> struct Iterator {
528545
int i = 0;
529546
T operator*() const { return i; }

0 commit comments

Comments
 (0)