diff options
| author | Jakub Kuderski <jakub@nod-labs.com> | 2025-03-10 17:54:04 -0400 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-03-10 17:54:04 -0400 |
| commit | c88352d2e92fb28abc39f9a393bdb2f1d6729a4e (patch) | |
| tree | 0af3724500a708b38b3c260699c13a2a6ce87223 | |
| parent | 92c8dd6fc940318d03c0689fdd008914e105f055 (diff) | |
[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.
| -rw-r--r-- | llvm/include/llvm/ADT/STLExtras.h | 17 | ||||
| -rw-r--r-- | llvm/unittests/ADT/STLExtrasTest.cpp | 10 |
2 files changed, 20 insertions, 7 deletions
diff --git a/llvm/include/llvm/ADT/STLExtras.h b/llvm/include/llvm/ADT/STLExtras.h index 885b5b037f42..18e73b4a138d 100644 --- a/llvm/include/llvm/ADT/STLExtras.h +++ b/llvm/include/llvm/ADT/STLExtras.h @@ -2124,7 +2124,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<typename Container, typename RandomAccessIterator> +template <typename Container, typename RandomAccessIterator> void replace(Container &Cont, typename Container::iterator ContIt, typename Container::iterator ContEnd, RandomAccessIterator ValIt, RandomAccessIterator ValEnd) { @@ -2132,21 +2132,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<typename Container, typename Range = std::initializer_list< - typename Container::value_type>> +template <typename Container, typename Range = std::initializer_list< + typename Container::value_type>> 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 2b2b4ae9b9e9..ad0149bf99ea 100644 --- a/llvm/unittests/ADT/STLExtrasTest.cpp +++ b/llvm/unittests/ADT/STLExtrasTest.cpp @@ -864,6 +864,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<int> 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<int> V; EXPECT_TRUE(all_equal(V)); |
