summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakub Kuderski <jakub@nod-labs.com>2025-03-10 17:54:04 -0400
committerGitHub <noreply@github.com>2025-03-10 17:54:04 -0400
commitc88352d2e92fb28abc39f9a393bdb2f1d6729a4e (patch)
tree0af3724500a708b38b3c260699c13a2a6ce87223
parent92c8dd6fc940318d03c0689fdd008914e105f055 (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.h17
-rw-r--r--llvm/unittests/ADT/STLExtrasTest.cpp10
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));