diff --git a/llvm/include/llvm/ADT/STLExtras.h b/llvm/include/llvm/ADT/STLExtras.h index fe1d010574e31..4219c6b41eac4 100644 --- a/llvm/include/llvm/ADT/STLExtras.h +++ b/llvm/include/llvm/ADT/STLExtras.h @@ -2127,7 +2127,7 @@ void append_values(Container &C, Args &&...Values) { /// Given a sequence container Cont, replace the range [ContIt, ContEnd) with /// the range [ValIt, ValEnd) (which is not from the same container). -template +template void replace(Container &Cont, typename Container::iterator ContIt, typename Container::iterator ContEnd, RandomAccessIterator ValIt, RandomAccessIterator ValEnd) { @@ -2135,21 +2135,24 @@ void replace(Container &Cont, typename Container::iterator ContIt, if (ValIt == ValEnd) { Cont.erase(ContIt, ContEnd); return; - } else if (ContIt == ContEnd) { + } + if (ContIt == ContEnd) { Cont.insert(ContIt, ValIt, ValEnd); return; } - *ContIt++ = *ValIt++; + *ContIt = *ValIt; + ++ContIt; + ++ValIt; } } /// Given a sequence container Cont, replace the range [ContIt, ContEnd) with /// the range R. -template> +template > void replace(Container &Cont, typename Container::iterator ContIt, - typename Container::iterator ContEnd, Range R) { - replace(Cont, ContIt, ContEnd, R.begin(), R.end()); + typename Container::iterator ContEnd, Range &&R) { + replace(Cont, ContIt, ContEnd, adl_begin(R), adl_end(R)); } /// An STL-style algorithm similar to std::for_each that applies a second diff --git a/llvm/unittests/ADT/STLExtrasTest.cpp b/llvm/unittests/ADT/STLExtrasTest.cpp index e107cb570641b..3a34b6673ef2d 100644 --- a/llvm/unittests/ADT/STLExtrasTest.cpp +++ b/llvm/unittests/ADT/STLExtrasTest.cpp @@ -854,6 +854,16 @@ TEST(STLExtrasTest, EarlyIncrementTestCustomPointerIterator) { EXPECT_EQ(EIR.end(), I); } +TEST(STLExtrasTest, ReplaceADL) { + // Make sure that we use the `begin`/`end` functions from `some_namespace`, + // using ADL. + std::vector Cont = {0, 1, 2, 3, 4, 5}; + some_namespace::some_struct S; + S.data = {42, 43, 44}; + replace(Cont, Cont.begin() + 2, Cont.begin() + 5, S); + EXPECT_THAT(Cont, ElementsAre(0, 1, 42, 43, 44, 5)); +} + TEST(STLExtrasTest, AllEqual) { std::vector V; EXPECT_TRUE(all_equal(V));