[llvm] 1527a1b - [ADT] Use `adl_begin`/`end` in `enumerate`

Jakub Kuderski via llvm-commits llvm-commits at lists.llvm.org
Wed Mar 1 08:15:38 PST 2023


Author: Jakub Kuderski
Date: 2023-03-01T11:15:19-05:00
New Revision: 1527a1bf7086a869f581a5c46cdde35d3eea8df8

URL: https://github.com/llvm/llvm-project/commit/1527a1bf7086a869f581a5c46cdde35d3eea8df8
DIFF: https://github.com/llvm/llvm-project/commit/1527a1bf7086a869f581a5c46cdde35d3eea8df8.diff

LOG: [ADT] Use `adl_begin`/`end` in `enumerate`

This allows `enumerate` to work with range types that expose custom
`begin`/`end` functions.

This is a cleanup in preparation for future changes in
https://reviews.llvm.org/D144503.

Reviewed By: zero9178

Differential Revision: https://reviews.llvm.org/D145026

Added: 
    

Modified: 
    llvm/include/llvm/ADT/STLExtras.h
    llvm/unittests/ADT/STLExtrasTest.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/include/llvm/ADT/STLExtras.h b/llvm/include/llvm/ADT/STLExtras.h
index 86d80354c9978..cc437681ec62c 100644
--- a/llvm/include/llvm/ADT/STLExtras.h
+++ b/llvm/include/llvm/ADT/STLExtras.h
@@ -2271,17 +2271,15 @@ template <typename R> class enumerator {
   explicit enumerator(R &&Range) : TheRange(std::forward<R>(Range)) {}
 
   enumerator_iter<R> begin() {
-    return enumerator_iter<R>(0, std::begin(TheRange));
+    return enumerator_iter<R>(0, adl_begin(TheRange));
   }
   enumerator_iter<R> begin() const {
-    return enumerator_iter<R>(0, std::begin(TheRange));
+    return enumerator_iter<R>(0, adl_begin(TheRange));
   }
 
-  enumerator_iter<R> end() {
-    return enumerator_iter<R>(std::end(TheRange));
-  }
+  enumerator_iter<R> end() { return enumerator_iter<R>(adl_end(TheRange)); }
   enumerator_iter<R> end() const {
-    return enumerator_iter<R>(std::end(TheRange));
+    return enumerator_iter<R>(adl_end(TheRange));
   }
 
 private:

diff  --git a/llvm/unittests/ADT/STLExtrasTest.cpp b/llvm/unittests/ADT/STLExtrasTest.cpp
index a1636237b4eeb..fda4577283d2e 100644
--- a/llvm/unittests/ADT/STLExtrasTest.cpp
+++ b/llvm/unittests/ADT/STLExtrasTest.cpp
@@ -260,6 +260,46 @@ TEST(STLExtrasTest, EnumerateLifetimeSemanticsLValue) {
   EXPECT_EQ(1, Destructors);
 }
 
+namespace some_namespace {
+struct some_struct {
+  std::vector<int> data;
+  std::string swap_val;
+};
+
+std::vector<int>::const_iterator begin(const some_struct &s) {
+  return s.data.begin();
+}
+
+std::vector<int>::const_iterator end(const some_struct &s) {
+  return s.data.end();
+}
+
+void swap(some_struct &lhs, some_struct &rhs) {
+  // make swap visible as non-adl swap would even seem to
+  // work with std::swap which defaults to moving
+  lhs.swap_val = "lhs";
+  rhs.swap_val = "rhs";
+}
+
+struct requires_move {};
+int *begin(requires_move &&) { return nullptr; }
+int *end(requires_move &&) { return nullptr; }
+} // namespace some_namespace
+
+TEST(STLExtrasTest, EnumerateCustomBeginEnd) {
+  // Check that `enumerate` uses ADL to find `begin`/`end` iterators
+  // of the enumerated type.
+  some_namespace::some_struct X{};
+  X.data = {1, 2, 3};
+
+  unsigned Iters = 0;
+  for (auto [Idx, Val] : enumerate(X)) {
+    EXPECT_EQ(Val, X.data[Idx]);
+    ++Iters;
+  }
+  EXPECT_EQ(Iters, 3u);
+}
+
 TEST(STLExtrasTest, CountAdaptor) {
   std::vector<int> v;
 
@@ -375,32 +415,6 @@ TEST(STLExtrasTest, AppendRange) {
   EXPECT_THAT(Str, ElementsAre('a', 'b', 'c', '\0', 'd', 'e', 'f', '\0'));
 }
 
-namespace some_namespace {
-struct some_struct {
-  std::vector<int> data;
-  std::string swap_val;
-};
-
-std::vector<int>::const_iterator begin(const some_struct &s) {
-  return s.data.begin();
-}
-
-std::vector<int>::const_iterator end(const some_struct &s) {
-  return s.data.end();
-}
-
-void swap(some_struct &lhs, some_struct &rhs) {
-  // make swap visible as non-adl swap would even seem to
-  // work with std::swap which defaults to moving
-  lhs.swap_val = "lhs";
-  rhs.swap_val = "rhs";
-}
-
-struct requires_move {};
-int *begin(requires_move &&) { return nullptr; }
-int *end(requires_move &&) { return nullptr; }
-} // namespace some_namespace
-
 TEST(STLExtrasTest, ADLTest) {
   some_namespace::some_struct s{{1, 2, 3, 4, 5}, ""};
   some_namespace::some_struct s2{{2, 4, 6, 8, 10}, ""};


        


More information about the llvm-commits mailing list