[llvm] [ADT] Relax iterator constraints on all_equal (PR #106400)

via llvm-commits llvm-commits at lists.llvm.org
Wed Aug 28 09:46:10 PDT 2024


https://github.com/aws-taylor updated https://github.com/llvm/llvm-project/pull/106400

>From 2089ddd2b7759e5470487a2b6e78378f50ac63b9 Mon Sep 17 00:00:00 2001
From: aws-taylor <57725958+aws-taylor at users.noreply.github.com>
Date: Wed, 28 Aug 2024 07:48:08 -0700
Subject: [PATCH 1/4] Relax iterator constraints on all_equal

The previous `all_equal` implementation contained `Begin + 1`, which implicitly requires `Begin` to model the random_access_iterator concept due to the usage of the `+` operator. By swapping this out with `std::next`, this method can be used with weaker iterator concepts, such as forward_iterator.
---
 llvm/include/llvm/ADT/STLExtras.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/llvm/include/llvm/ADT/STLExtras.h b/llvm/include/llvm/ADT/STLExtras.h
index b2df0cd650ad7b..e11d6cac7685e4 100644
--- a/llvm/include/llvm/ADT/STLExtras.h
+++ b/llvm/include/llvm/ADT/STLExtras.h
@@ -2062,7 +2062,7 @@ bool equal(L &&LRange, R &&RRange, BinaryPredicate P) {
 template <typename R> bool all_equal(R &&Range) {
   auto Begin = adl_begin(Range);
   auto End = adl_end(Range);
-  return Begin == End || std::equal(Begin + 1, End, Begin);
+  return Begin == End || std::equal(std::next(Begin), End, Begin);
 }
 
 /// Returns true if all Values in the initializer lists are equal or the list

>From 9520c3c86a47d58d8d3de44bbca27571f3dad807 Mon Sep 17 00:00:00 2001
From: aws-taylor <57725958+aws-taylor at users.noreply.github.com>
Date: Wed, 28 Aug 2024 09:34:15 -0700
Subject: [PATCH 2/4] Add test for all_equal() to verify correctness on
 non-random-access containers

---
 llvm/unittests/ADT/STLExtrasTest.cpp | 21 +++++++++++++++++++++
 1 file changed, 21 insertions(+)

diff --git a/llvm/unittests/ADT/STLExtrasTest.cpp b/llvm/unittests/ADT/STLExtrasTest.cpp
index b7dc15bf60af51..63cf0cadfbc57d 100644
--- a/llvm/unittests/ADT/STLExtrasTest.cpp
+++ b/llvm/unittests/ADT/STLExtrasTest.cpp
@@ -15,6 +15,7 @@
 #include <climits>
 #include <cstddef>
 #include <initializer_list>
+#include <iterator>
 #include <list>
 #include <tuple>
 #include <type_traits>
@@ -831,6 +832,26 @@ TEST(STLExtrasTest, AllEqual) {
   EXPECT_FALSE(all_equal(V));
 }
 
+// Test to verify that all_equal works with a container that does not 
+// model the random access iterator concept.
+TEST(STLExtrasTest, AllEqualNonRandomAccess) {
+  std::list<int> V;
+  static_assert(!std::is_convertible<std::iterator_traits<decltype(V)::iterator>::iterator_category,
+                                     std::random_access_iterator_tag >::value);
+  
+  EXPECT_TRUE(all_equal(V));
+
+  V.push_back(1);
+  EXPECT_TRUE(all_equal(V));
+
+  V.push_back(1);
+  V.push_back(1);
+  EXPECT_TRUE(all_equal(V));
+
+  V.push_back(2);
+  EXPECT_FALSE(all_equal(V));
+}
+                                
 TEST(STLExtrasTest, AllEqualInitializerList) {
   EXPECT_TRUE(all_equal({1}));
   EXPECT_TRUE(all_equal({1, 1}));

>From a2a6e56f71be8fb29ed28ca7584cb3419a0756e5 Mon Sep 17 00:00:00 2001
From: aws-taylor <57725958+aws-taylor at users.noreply.github.com>
Date: Wed, 28 Aug 2024 09:39:32 -0700
Subject: [PATCH 3/4] Update llvm/unittests/ADT/STLExtrasTest.cpp

Co-authored-by: Jakub Kuderski <kubakuderski at gmail.com>
---
 llvm/unittests/ADT/STLExtrasTest.cpp | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/llvm/unittests/ADT/STLExtrasTest.cpp b/llvm/unittests/ADT/STLExtrasTest.cpp
index 63cf0cadfbc57d..9842d8af32ff6c 100644
--- a/llvm/unittests/ADT/STLExtrasTest.cpp
+++ b/llvm/unittests/ADT/STLExtrasTest.cpp
@@ -836,8 +836,8 @@ TEST(STLExtrasTest, AllEqual) {
 // model the random access iterator concept.
 TEST(STLExtrasTest, AllEqualNonRandomAccess) {
   std::list<int> V;
-  static_assert(!std::is_convertible<std::iterator_traits<decltype(V)::iterator>::iterator_category,
-                                     std::random_access_iterator_tag >::value);
+  static_assert(!std::is_convertible_v<std::iterator_traits<decltype(V)::iterator>::iterator_category,
+                                     std::random_access_iterator_tag >);
   
   EXPECT_TRUE(all_equal(V));
 

>From 57e5f518cc18c4e1f811a0bd2204c4923e41d40f Mon Sep 17 00:00:00 2001
From: aws-taylor <57725958+aws-taylor at users.noreply.github.com>
Date: Wed, 28 Aug 2024 09:46:01 -0700
Subject: [PATCH 4/4] Fix formatting

---
 llvm/unittests/ADT/STLExtrasTest.cpp | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/llvm/unittests/ADT/STLExtrasTest.cpp b/llvm/unittests/ADT/STLExtrasTest.cpp
index 9842d8af32ff6c..a312d0ea4490b6 100644
--- a/llvm/unittests/ADT/STLExtrasTest.cpp
+++ b/llvm/unittests/ADT/STLExtrasTest.cpp
@@ -832,12 +832,13 @@ TEST(STLExtrasTest, AllEqual) {
   EXPECT_FALSE(all_equal(V));
 }
 
-// Test to verify that all_equal works with a container that does not 
+// Test to verify that all_equal works with a container that does not
 // model the random access iterator concept.
 TEST(STLExtrasTest, AllEqualNonRandomAccess) {
   std::list<int> V;
-  static_assert(!std::is_convertible_v<std::iterator_traits<decltype(V)::iterator>::iterator_category,
-                                     std::random_access_iterator_tag >);
+  static_assert(!std::is_convertible_v<
+                std::iterator_traits<decltype(V)::iterator>::iterator_category,
+                std::random_access_iterator_tag>);
   
   EXPECT_TRUE(all_equal(V));
 
@@ -851,7 +852,7 @@ TEST(STLExtrasTest, AllEqualNonRandomAccess) {
   V.push_back(2);
   EXPECT_FALSE(all_equal(V));
 }
-                                
+
 TEST(STLExtrasTest, AllEqualInitializerList) {
   EXPECT_TRUE(all_equal({1}));
   EXPECT_TRUE(all_equal({1, 1}));



More information about the llvm-commits mailing list