<div dir="ltr"><br><br><div class="gmail_quote"><div dir="ltr">On Mon, Nov 28, 2016 at 10:19 AM Zachary Turner <<a href="mailto:zturner@google.com">zturner@google.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr" class="gmail_msg">Having a single type for cost and mutable would be great, if we could make it work.  Seems like a huge change across the codebase, but probably worth it if myself or someone gets some cycles to do it.</div></blockquote><div><br></div><div>Yep - big, but fairly mechanical change. If you/anyone else wants to do this, I'd suggest floating it on llvm-dev first, just so everyone's aware of the ArrayRef<T> -> ArrayRef<const T> change that would fall out of this.</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr" class="gmail_msg"><div class="gmail_msg">And good point about having drop_front call slice.  I can make it parallel the interface of ArrayRef for now, until we figure out what to do about constness.<br></div></div></blockquote><div><br></div><div>Yep yep</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr" class="gmail_msg"><div class="gmail_msg"></div></div><br class="gmail_msg"><div class="gmail_quote gmail_msg"><div dir="ltr" class="gmail_msg">On Mon, Nov 28, 2016 at 10:16 AM David Blaikie <<a href="mailto:dblaikie@gmail.com" class="gmail_msg" target="_blank">dblaikie@gmail.com</a>> wrote:<br class="gmail_msg"></div><blockquote class="gmail_quote gmail_msg" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr" class="gmail_msg"><div class="gmail_quote gmail_msg"><div dir="ltr" class="gmail_msg">On Tue, Nov 22, 2016 at 3:32 PM Zachary Turner via llvm-commits <<a href="mailto:llvm-commits@lists.llvm.org" class="gmail_msg" target="_blank">llvm-commits@lists.llvm.org</a>> wrote:<br class="gmail_msg"></div><blockquote class="gmail_quote gmail_msg" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: zturner<br class="gmail_msg">
Date: Tue Nov 22 17:22:19 2016<br class="gmail_msg">
New Revision: 287722<br class="gmail_msg">
<br class="gmail_msg">
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=287722&view=rev" rel="noreferrer" class="gmail_msg" target="_blank">http://llvm.org/viewvc/llvm-project?rev=287722&view=rev</a><br class="gmail_msg">
Log:<br class="gmail_msg">
Add some searching functions for ArrayRef<T>.<br class="gmail_msg">
<br class="gmail_msg">
Differential Revision: <a href="https://reviews.llvm.org/D26999" rel="noreferrer" class="gmail_msg" target="_blank">https://reviews.llvm.org/D26999</a><br class="gmail_msg">
<br class="gmail_msg">
Modified:<br class="gmail_msg">
    llvm/trunk/include/llvm/ADT/ArrayRef.h<br class="gmail_msg">
    llvm/trunk/include/llvm/ADT/STLExtras.h<br class="gmail_msg">
    llvm/trunk/unittests/ADT/ArrayRefTest.cpp<br class="gmail_msg">
<br class="gmail_msg">
Modified: llvm/trunk/include/llvm/ADT/ArrayRef.h<br class="gmail_msg">
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/ArrayRef.h?rev=287722&r1=287721&r2=287722&view=diff" rel="noreferrer" class="gmail_msg" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/ArrayRef.h?rev=287722&r1=287721&r2=287722&view=diff</a><br class="gmail_msg">
==============================================================================<br class="gmail_msg">
--- llvm/trunk/include/llvm/ADT/ArrayRef.h (original)<br class="gmail_msg">
+++ llvm/trunk/include/llvm/ADT/ArrayRef.h Tue Nov 22 17:22:19 2016<br class="gmail_msg">
@@ -12,6 +12,7 @@<br class="gmail_msg">
<br class="gmail_msg">
 #include "llvm/ADT/Hashing.h"<br class="gmail_msg">
 #include "llvm/ADT/None.h"<br class="gmail_msg">
+#include "llvm/ADT/STLExtras.h"<br class="gmail_msg">
 #include "llvm/ADT/SmallVector.h"<br class="gmail_msg">
 #include <array><br class="gmail_msg">
 #include <vector><br class="gmail_msg">
@@ -165,12 +166,6 @@ namespace llvm {<br class="gmail_msg">
       return std::equal(begin(), end(), RHS.begin());<br class="gmail_msg">
     }<br class="gmail_msg">
<br class="gmail_msg">
-    /// slice(n) - Chop off the first N elements of the array.<br class="gmail_msg">
-    ArrayRef<T> slice(size_t N) const {<br class="gmail_msg">
-      assert(N <= size() && "Invalid specifier");<br class="gmail_msg">
-      return ArrayRef<T>(data()+N, size()-N);<br class="gmail_msg"></blockquote><div class="gmail_msg"><br class="gmail_msg"></div></div></div><div dir="ltr" class="gmail_msg"><div class="gmail_quote gmail_msg"><div class="gmail_msg">This might be easier written as ArrayRef(begin() + N, end()) - similar suggestion in MutableArrayRef. (worth adding a CRTP base to implement some of these common functions in both? - alternatively I'll float the suggestion I made when Chris originally committed MutableArrayRef: Maybe we just fix ArrayRef<T> -> ArrayRef<const T> and ArrayRef<T> is MutableArrayRef<T> and there's no need for two types, etc)<br class="gmail_msg"><br class="gmail_msg">(note you don't need to specify <T> when referencing ArrayRef<T> from within the class itself - applies across this change)</div></div></div><div dir="ltr" class="gmail_msg"><div class="gmail_quote gmail_msg"><div class="gmail_msg"> </div><blockquote class="gmail_quote gmail_msg" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
-    }<br class="gmail_msg">
-<br class="gmail_msg">
     /// slice(n, m) - Chop off the first N elements of the array, and keep M<br class="gmail_msg">
     /// elements in the array.<br class="gmail_msg">
     ArrayRef<T> slice(size_t N, size_t M) const {<br class="gmail_msg">
@@ -178,6 +173,9 @@ namespace llvm {<br class="gmail_msg">
       return ArrayRef<T>(data()+N, M);<br class="gmail_msg">
     }<br class="gmail_msg">
<br class="gmail_msg">
+    /// slice(n) - Chop off the first N elements of the array.<br class="gmail_msg"></blockquote><div class="gmail_msg"><br class="gmail_msg"></div></div></div><div dir="ltr" class="gmail_msg"><div class="gmail_quote gmail_msg"><div class="gmail_msg">This is an alias for drop_front below, right? Should one call the other?</div></div></div><div dir="ltr" class="gmail_msg"><div class="gmail_quote gmail_msg"><div class="gmail_msg"> </div><blockquote class="gmail_quote gmail_msg" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+    ArrayRef<T> slice(size_t N) const { return slice(N, size() - N); }<br class="gmail_msg">
+<br class="gmail_msg">
     /// \brief Drop the first \p N elements of the array.<br class="gmail_msg">
     ArrayRef<T> drop_front(size_t N = 1) const {<br class="gmail_msg">
       assert(size() >= N && "Dropping more elements than exist");<br class="gmail_msg">
@@ -190,6 +188,18 @@ namespace llvm {<br class="gmail_msg">
       return slice(0, size() - N);<br class="gmail_msg">
     }<br class="gmail_msg">
<br class="gmail_msg">
+    /// \brief Return a copy of *this with the first N elements satisfying the<br class="gmail_msg">
+    /// given predicate removed.<br class="gmail_msg">
+    template <class PredicateT> ArrayRef<T> drop_while(PredicateT Pred) const {<br class="gmail_msg">
+      return ArrayRef<T>(find_if_not(*this, Pred), end());<br class="gmail_msg">
+    }<br class="gmail_msg">
+<br class="gmail_msg">
+    /// \brief Return a copy of *this with the first N elements not satisfying<br class="gmail_msg">
+    /// the given predicate removed.<br class="gmail_msg">
+    template <class PredicateT> ArrayRef<T> drop_until(PredicateT Pred) const {<br class="gmail_msg">
+      return ArrayRef<T>(find_if(*this, Pred), end());<br class="gmail_msg">
+    }<br class="gmail_msg">
+<br class="gmail_msg">
     /// \brief Return a copy of *this with only the first \p N elements.<br class="gmail_msg">
     ArrayRef<T> take_front(size_t N = 1) const {<br class="gmail_msg">
       if (N >= size())<br class="gmail_msg">
@@ -204,6 +214,18 @@ namespace llvm {<br class="gmail_msg">
       return drop_front(size() - N);<br class="gmail_msg">
     }<br class="gmail_msg">
<br class="gmail_msg">
+    /// \brief Return the first N elements of this Array that satisfy the given<br class="gmail_msg">
+    /// predicate.<br class="gmail_msg">
+    template <class PredicateT> ArrayRef<T> take_while(PredicateT Pred) const {<br class="gmail_msg">
+      return ArrayRef<T>(begin(), find_if_not(*this, Pred));<br class="gmail_msg">
+    }<br class="gmail_msg">
+<br class="gmail_msg">
+    /// \brief Return the first N elements of this Array that don't satisfy the<br class="gmail_msg">
+    /// given predicate.<br class="gmail_msg">
+    template <class PredicateT> ArrayRef<T> take_until(PredicateT Pred) const {<br class="gmail_msg">
+      return ArrayRef<T>(begin(), find_if(*this, Pred));<br class="gmail_msg">
+    }<br class="gmail_msg">
+<br class="gmail_msg">
     /// @}<br class="gmail_msg">
     /// @name Operator Overloads<br class="gmail_msg">
     /// @{<br class="gmail_msg">
@@ -317,17 +339,16 @@ namespace llvm {<br class="gmail_msg">
       return data()[this->size()-1];<br class="gmail_msg">
     }<br class="gmail_msg">
<br class="gmail_msg">
-    /// slice(n) - Chop off the first N elements of the array.<br class="gmail_msg">
-    MutableArrayRef<T> slice(size_t N) const {<br class="gmail_msg">
-      assert(N <= this->size() && "Invalid specifier");<br class="gmail_msg">
-      return MutableArrayRef<T>(data()+N, this->size()-N);<br class="gmail_msg">
-    }<br class="gmail_msg">
-<br class="gmail_msg">
     /// slice(n, m) - Chop off the first N elements of the array, and keep M<br class="gmail_msg">
     /// elements in the array.<br class="gmail_msg">
     MutableArrayRef<T> slice(size_t N, size_t M) const {<br class="gmail_msg">
-      assert(N+M <= this->size() && "Invalid specifier");<br class="gmail_msg">
-      return MutableArrayRef<T>(data()+N, M);<br class="gmail_msg">
+      assert(N + M <= this->size() && "Invalid specifier");<br class="gmail_msg">
+      return MutableArrayRef<T>(this->data() + N, M);<br class="gmail_msg">
+    }<br class="gmail_msg">
+<br class="gmail_msg">
+    /// slice(n) - Chop off the first N elements of the array.<br class="gmail_msg">
+    MutableArrayRef<T> slice(size_t N) const {<br class="gmail_msg">
+      return slice(N, this->size() - N);<br class="gmail_msg">
     }<br class="gmail_msg">
<br class="gmail_msg">
     /// \brief Drop the first \p N elements of the array.<br class="gmail_msg">
@@ -341,6 +362,20 @@ namespace llvm {<br class="gmail_msg">
       return slice(0, this->size() - N);<br class="gmail_msg">
     }<br class="gmail_msg">
<br class="gmail_msg">
+    /// \brief Return a copy of *this with the first N elements satisfying the<br class="gmail_msg">
+    /// given predicate removed.<br class="gmail_msg">
+    template <class PredicateT><br class="gmail_msg">
+    MutableArrayRef<T> drop_while(PredicateT Pred) const {<br class="gmail_msg">
+      return MutableArrayRef<T>(find_if_not(*this, Pred), end());<br class="gmail_msg">
+    }<br class="gmail_msg">
+<br class="gmail_msg">
+    /// \brief Return a copy of *this with the first N elements not satisfying<br class="gmail_msg">
+    /// the given predicate removed.<br class="gmail_msg">
+    template <class PredicateT><br class="gmail_msg">
+    MutableArrayRef<T> drop_until(PredicateT Pred) const {<br class="gmail_msg">
+      return MutableArrayRef<T>(find_if(*this, Pred), end());<br class="gmail_msg">
+    }<br class="gmail_msg">
+<br class="gmail_msg">
     /// \brief Return a copy of *this with only the first \p N elements.<br class="gmail_msg">
     MutableArrayRef<T> take_front(size_t N = 1) const {<br class="gmail_msg">
       if (N >= this->size())<br class="gmail_msg">
@@ -355,6 +390,20 @@ namespace llvm {<br class="gmail_msg">
       return drop_front(this->size() - N);<br class="gmail_msg">
     }<br class="gmail_msg">
<br class="gmail_msg">
+    /// \brief Return the first N elements of this Array that satisfy the given<br class="gmail_msg">
+    /// predicate.<br class="gmail_msg">
+    template <class PredicateT><br class="gmail_msg">
+    MutableArrayRef<T> take_while(PredicateT Pred) const {<br class="gmail_msg">
+      return MutableArrayRef<T>(begin(), find_if_not(*this, Pred));<br class="gmail_msg">
+    }<br class="gmail_msg">
+<br class="gmail_msg">
+    /// \brief Return the first N elements of this Array that don't satisfy the<br class="gmail_msg">
+    /// given predicate.<br class="gmail_msg">
+    template <class PredicateT><br class="gmail_msg">
+    MutableArrayRef<T> take_until(PredicateT Pred) const {<br class="gmail_msg">
+      return MutableArrayRef<T>(begin(), find_if(*this, Pred));<br class="gmail_msg">
+    }<br class="gmail_msg">
+<br class="gmail_msg">
     /// @}<br class="gmail_msg">
     /// @name Operator Overloads<br class="gmail_msg">
     /// @{<br class="gmail_msg">
<br class="gmail_msg">
Modified: llvm/trunk/include/llvm/ADT/STLExtras.h<br class="gmail_msg">
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/STLExtras.h?rev=287722&r1=287721&r2=287722&view=diff" rel="noreferrer" class="gmail_msg" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/STLExtras.h?rev=287722&r1=287721&r2=287722&view=diff</a><br class="gmail_msg">
==============================================================================<br class="gmail_msg">
--- llvm/trunk/include/llvm/ADT/STLExtras.h (original)<br class="gmail_msg">
+++ llvm/trunk/include/llvm/ADT/STLExtras.h Tue Nov 22 17:22:19 2016<br class="gmail_msg">
@@ -622,6 +622,11 @@ auto find_if(R &&Range, const T &Pred) -<br class="gmail_msg">
   return std::find_if(Range.begin(), Range.end(), Pred);<br class="gmail_msg">
 }<br class="gmail_msg">
<br class="gmail_msg">
+template <typename R, class PredicateT><br class="gmail_msg">
+auto find_if_not(R &&Range, PredicateT Pred) -> decltype(Range.begin()) {<br class="gmail_msg">
+  return std::find_if_not(Range.begin(), Range.end(), Pred);<br class="gmail_msg">
+}<br class="gmail_msg">
+<br class="gmail_msg">
 /// Provide wrappers to std::remove_if which take ranges instead of having to<br class="gmail_msg">
 /// pass begin/end explicitly.<br class="gmail_msg">
 template<typename R, class UnaryPredicate><br class="gmail_msg">
<br class="gmail_msg">
Modified: llvm/trunk/unittests/ADT/ArrayRefTest.cpp<br class="gmail_msg">
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/ADT/ArrayRefTest.cpp?rev=287722&r1=287721&r2=287722&view=diff" rel="noreferrer" class="gmail_msg" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/ADT/ArrayRefTest.cpp?rev=287722&r1=287721&r2=287722&view=diff</a><br class="gmail_msg">
==============================================================================<br class="gmail_msg">
--- llvm/trunk/unittests/ADT/ArrayRefTest.cpp (original)<br class="gmail_msg">
+++ llvm/trunk/unittests/ADT/ArrayRefTest.cpp Tue Nov 22 17:22:19 2016<br class="gmail_msg">
@@ -102,6 +102,28 @@ TEST(ArrayRefTest, DropFront) {<br class="gmail_msg">
   EXPECT_EQ(1U, AR3.drop_front(AR3.size() - 1).size());<br class="gmail_msg">
 }<br class="gmail_msg">
<br class="gmail_msg">
+TEST(ArrayRefTest, DropWhile) {<br class="gmail_msg">
+  static const int TheNumbers[] = {1, 3, 5, 8, 10, 11};<br class="gmail_msg">
+  ArrayRef<int> AR1(TheNumbers);<br class="gmail_msg">
+  ArrayRef<int> Expected = AR1.drop_front(3);<br class="gmail_msg">
+  EXPECT_EQ(Expected, AR1.drop_while([](const int &N) { return N % 2 == 1; }));<br class="gmail_msg">
+<br class="gmail_msg">
+  EXPECT_EQ(AR1, AR1.drop_while([](const int &N) { return N < 0; }));<br class="gmail_msg">
+  EXPECT_EQ(ArrayRef<int>(),<br class="gmail_msg">
+            AR1.drop_while([](const int &N) { return N > 0; }));<br class="gmail_msg">
+}<br class="gmail_msg">
+<br class="gmail_msg">
+TEST(ArrayRefTest, DropUntil) {<br class="gmail_msg">
+  static const int TheNumbers[] = {1, 3, 5, 8, 10, 11};<br class="gmail_msg">
+  ArrayRef<int> AR1(TheNumbers);<br class="gmail_msg">
+  ArrayRef<int> Expected = AR1.drop_front(3);<br class="gmail_msg">
+  EXPECT_EQ(Expected, AR1.drop_until([](const int &N) { return N % 2 == 0; }));<br class="gmail_msg">
+<br class="gmail_msg">
+  EXPECT_EQ(ArrayRef<int>(),<br class="gmail_msg">
+            AR1.drop_until([](const int &N) { return N < 0; }));<br class="gmail_msg">
+  EXPECT_EQ(AR1, AR1.drop_until([](const int &N) { return N > 0; }));<br class="gmail_msg">
+}<br class="gmail_msg">
+<br class="gmail_msg">
 TEST(ArrayRefTest, TakeBack) {<br class="gmail_msg">
   static const int TheNumbers[] = {4, 8, 15, 16, 23, 42};<br class="gmail_msg">
   ArrayRef<int> AR1(TheNumbers);<br class="gmail_msg">
@@ -116,6 +138,28 @@ TEST(ArrayRefTest, TakeFront) {<br class="gmail_msg">
   EXPECT_TRUE(AR1.take_front(2).equals(AR2));<br class="gmail_msg">
 }<br class="gmail_msg">
<br class="gmail_msg">
+TEST(ArrayRefTest, TakeWhile) {<br class="gmail_msg">
+  static const int TheNumbers[] = {1, 3, 5, 8, 10, 11};<br class="gmail_msg">
+  ArrayRef<int> AR1(TheNumbers);<br class="gmail_msg">
+  ArrayRef<int> Expected = AR1.take_front(3);<br class="gmail_msg">
+  EXPECT_EQ(Expected, AR1.take_while([](const int &N) { return N % 2 == 1; }));<br class="gmail_msg">
+<br class="gmail_msg">
+  EXPECT_EQ(ArrayRef<int>(),<br class="gmail_msg">
+            AR1.take_while([](const int &N) { return N < 0; }));<br class="gmail_msg">
+  EXPECT_EQ(AR1, AR1.take_while([](const int &N) { return N > 0; }));<br class="gmail_msg">
+}<br class="gmail_msg">
+<br class="gmail_msg">
+TEST(ArrayRefTest, TakeUntil) {<br class="gmail_msg">
+  static const int TheNumbers[] = {1, 3, 5, 8, 10, 11};<br class="gmail_msg">
+  ArrayRef<int> AR1(TheNumbers);<br class="gmail_msg">
+  ArrayRef<int> Expected = AR1.take_front(3);<br class="gmail_msg">
+  EXPECT_EQ(Expected, AR1.take_until([](const int &N) { return N % 2 == 0; }));<br class="gmail_msg">
+<br class="gmail_msg">
+  EXPECT_EQ(AR1, AR1.take_until([](const int &N) { return N < 0; }));<br class="gmail_msg">
+  EXPECT_EQ(ArrayRef<int>(),<br class="gmail_msg">
+            AR1.take_until([](const int &N) { return N > 0; }));<br class="gmail_msg">
+}<br class="gmail_msg">
+<br class="gmail_msg">
 TEST(ArrayRefTest, Equals) {<br class="gmail_msg">
   static const int A1[] = {1, 2, 3, 4, 5, 6, 7, 8};<br class="gmail_msg">
   ArrayRef<int> AR1(A1);<br class="gmail_msg">
<br class="gmail_msg">
<br class="gmail_msg">
_______________________________________________<br class="gmail_msg">
llvm-commits mailing list<br class="gmail_msg">
<a href="mailto:llvm-commits@lists.llvm.org" class="gmail_msg" target="_blank">llvm-commits@lists.llvm.org</a><br class="gmail_msg">
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits" rel="noreferrer" class="gmail_msg" target="_blank">http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits</a><br class="gmail_msg">
</blockquote></div></div></blockquote></div>
</blockquote></div></div>