Skip to content

Commit 16e5737

Browse files
committed
[ADT] Use adl_begin/end in replace.
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. Also clean up the implementation to adhere to the llvm coding standards.
1 parent 2e7a509 commit 16e5737

File tree

2 files changed

+20
-7
lines changed

2 files changed

+20
-7
lines changed

llvm/include/llvm/ADT/STLExtras.h

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2127,29 +2127,32 @@ void append_values(Container &C, Args &&...Values) {
21272127

21282128
/// Given a sequence container Cont, replace the range [ContIt, ContEnd) with
21292129
/// the range [ValIt, ValEnd) (which is not from the same container).
2130-
template<typename Container, typename RandomAccessIterator>
2130+
template <typename Container, typename RandomAccessIterator>
21312131
void replace(Container &Cont, typename Container::iterator ContIt,
21322132
typename Container::iterator ContEnd, RandomAccessIterator ValIt,
21332133
RandomAccessIterator ValEnd) {
21342134
while (true) {
21352135
if (ValIt == ValEnd) {
21362136
Cont.erase(ContIt, ContEnd);
21372137
return;
2138-
} else if (ContIt == ContEnd) {
2138+
}
2139+
if (ContIt == ContEnd) {
21392140
Cont.insert(ContIt, ValIt, ValEnd);
21402141
return;
21412142
}
2142-
*ContIt++ = *ValIt++;
2143+
*ContIt = *ValIt;
2144+
++ContIt;
2145+
++ValIt;
21432146
}
21442147
}
21452148

21462149
/// Given a sequence container Cont, replace the range [ContIt, ContEnd) with
21472150
/// the range R.
2148-
template<typename Container, typename Range = std::initializer_list<
2149-
typename Container::value_type>>
2151+
template <typename Container, typename Range = std::initializer_list<
2152+
typename Container::value_type>>
21502153
void replace(Container &Cont, typename Container::iterator ContIt,
2151-
typename Container::iterator ContEnd, Range R) {
2152-
replace(Cont, ContIt, ContEnd, R.begin(), R.end());
2154+
typename Container::iterator ContEnd, Range &&R) {
2155+
replace(Cont, ContIt, ContEnd, adl_begin(R), adl_end(R));
21532156
}
21542157

21552158
/// An STL-style algorithm similar to std::for_each that applies a second

llvm/unittests/ADT/STLExtrasTest.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -854,6 +854,16 @@ TEST(STLExtrasTest, EarlyIncrementTestCustomPointerIterator) {
854854
EXPECT_EQ(EIR.end(), I);
855855
}
856856

857+
TEST(STLExtrasTest, ReplaceADL) {
858+
// Make sure that we use the `begin`/`end` functions from `some_namespace`,
859+
// using ADL.
860+
std::vector<int> Cont = {0, 1, 2, 3, 4, 5};
861+
some_namespace::some_struct S;
862+
S.data = {42, 43, 44};
863+
replace(Cont, Cont.begin() + 2, Cont.begin() + 5, S);
864+
EXPECT_THAT(Cont, ElementsAre(0, 1, 42, 43, 44, 5));
865+
}
866+
857867
TEST(STLExtrasTest, AllEqual) {
858868
std::vector<int> V;
859869
EXPECT_TRUE(all_equal(V));

0 commit comments

Comments
 (0)