Skip to content

Commit c88352d

Browse files
authored
[ADT] Use adl_begin/end in replace. (#130523)
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 92c8dd6 commit c88352d

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
@@ -2124,29 +2124,32 @@ void append_values(Container &C, Args &&...Values) {
21242124

21252125
/// Given a sequence container Cont, replace the range [ContIt, ContEnd) with
21262126
/// the range [ValIt, ValEnd) (which is not from the same container).
2127-
template<typename Container, typename RandomAccessIterator>
2127+
template <typename Container, typename RandomAccessIterator>
21282128
void replace(Container &Cont, typename Container::iterator ContIt,
21292129
typename Container::iterator ContEnd, RandomAccessIterator ValIt,
21302130
RandomAccessIterator ValEnd) {
21312131
while (true) {
21322132
if (ValIt == ValEnd) {
21332133
Cont.erase(ContIt, ContEnd);
21342134
return;
2135-
} else if (ContIt == ContEnd) {
2135+
}
2136+
if (ContIt == ContEnd) {
21362137
Cont.insert(ContIt, ValIt, ValEnd);
21372138
return;
21382139
}
2139-
*ContIt++ = *ValIt++;
2140+
*ContIt = *ValIt;
2141+
++ContIt;
2142+
++ValIt;
21402143
}
21412144
}
21422145

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

21522155
/// 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
@@ -864,6 +864,16 @@ TEST(STLExtrasTest, EarlyIncrementTestCustomPointerIterator) {
864864
EXPECT_EQ(EIR.end(), I);
865865
}
866866

867+
TEST(STLExtrasTest, ReplaceADL) {
868+
// Make sure that we use the `begin`/`end` functions from `some_namespace`,
869+
// using ADL.
870+
std::vector<int> Cont = {0, 1, 2, 3, 4, 5};
871+
some_namespace::some_struct S;
872+
S.data = {42, 43, 44};
873+
replace(Cont, Cont.begin() + 2, Cont.begin() + 5, S);
874+
EXPECT_THAT(Cont, ElementsAre(0, 1, 42, 43, 44, 5));
875+
}
876+
867877
TEST(STLExtrasTest, AllEqual) {
868878
std::vector<int> V;
869879
EXPECT_TRUE(all_equal(V));

0 commit comments

Comments
 (0)