Skip to content

Commit 0139378

Browse files
committed
[ADT] Use adl_begin in make_first_range and make_second_range
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. This PR is stacked on top of llvm#130508.
1 parent 022fa8a commit 0139378

File tree

2 files changed

+20
-2
lines changed

2 files changed

+20
-2
lines changed

llvm/include/llvm/ADT/STLExtras.h

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

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

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

llvm/unittests/ADT/STLExtrasTest.cpp

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

424+
struct Pairs {
425+
std::vector<std::pair<std::string, int>> data;
426+
using const_iterator =
427+
std::vector<std::pair<std::string, int>>::const_iterator;
428+
};
429+
430+
Pairs::const_iterator begin(const Pairs &p) { return p.data.begin(); }
431+
Pairs::const_iterator end(const Pairs &p) { return p.data.end(); }
432+
424433
struct requires_move {};
425434
int *begin(requires_move &&) { return nullptr; }
426435
int *end(requires_move &&) { return nullptr; }
@@ -504,6 +513,15 @@ TEST(STLExtrasTest, ConcatRange) {
504513
EXPECT_EQ(Expected, Test);
505514
}
506515

516+
TEST(STLExtrasTest, MakeFirstSecondRangeADL) {
517+
// Make sure that we use the `begin`/`end` functions from `some_namespace`,
518+
// using ADL.
519+
some_namespace::Pairs Pairs;
520+
Pairs.data = {{"foo", 1}, {"bar", 2}};
521+
EXPECT_THAT(make_first_range(Pairs), ElementsAre("foo", "bar"));
522+
EXPECT_THAT(make_second_range(Pairs), ElementsAre(1, 2));
523+
}
524+
507525
template <typename T> struct Iterator {
508526
int i = 0;
509527
T operator*() const { return i; }

0 commit comments

Comments
 (0)