Explorar o código

Add StringRef::take_front and StringRef::take_back

Reviewed By: majnemer, rnk
Differential Revision: https://reviews.llvm.org/D23965

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@280114 91177308-0d34-0410-b5e6-96231b3b80d8
Zachary Turner %!s(int64=9) %!d(string=hai) anos
pai
achega
bb0403b31b

+ 32 - 0
include/llvm/ADT/ArrayRef.h

@@ -195,6 +195,22 @@ namespace llvm {
       return slice(0, size() - N);
     }
 
+    /// \brief Keep the first \p N elements of the array.
+    LLVM_ATTRIBUTE_UNUSED_RESULT
+    ArrayRef<T> keep_front(size_t N = 1) const {
+      if (N >= size())
+        return *this;
+      return drop_back(size() - N);
+    }
+
+    /// \brief Keep the last \p N elements of the array.
+    LLVM_ATTRIBUTE_UNUSED_RESULT
+    ArrayRef<T> keep_back(size_t N = 1) const {
+      if (N >= size())
+        return *this;
+      return drop_front(size() - N);
+    }
+
     /// @}
     /// @name Operator Overloads
     /// @{
@@ -321,6 +337,22 @@ namespace llvm {
       return slice(0, this->size() - N);
     }
 
+    /// \brief Drop everything but the first \p N elements of the array.
+    LLVM_ATTRIBUTE_UNUSED_RESULT
+    MutableArrayRef<T> keep_front(size_t N = 1) const {
+      if (N >= this->size())
+        return *this;
+      return drop_back(size() - N);
+    }
+
+    /// \brief Drop everything but the last \p N elements of the array.
+    LLVM_ATTRIBUTE_UNUSED_RESULT
+    MutableArrayRef<T> keep_back(size_t N = 1) const {
+      if (N >= this->size())
+        return *this;
+      return drop_front(size() - N);
+    }
+
     /// @}
     /// @name Operator Overloads
     /// @{

+ 22 - 0
include/llvm/ADT/StringRef.h

@@ -433,6 +433,28 @@ namespace llvm {
       return StringRef(Data + Start, std::min(N, Length - Start));
     }
 
+    /// Return a StringRef equal to 'this' but with only the first \p N
+    /// elements remaining.  If \p N is greater than the length of the
+    /// string, the entire string is returned.
+    LLVM_ATTRIBUTE_ALWAYS_INLINE
+    LLVM_ATTRIBUTE_UNUSED_RESULT
+    StringRef take_front(size_t N = 1) const {
+      if (N >= size())
+        return *this;
+      return drop_back(size() - N);
+    }
+
+    /// Return a StringRef equal to 'this' but with only the first \p N
+    /// elements remaining.  If \p N is greater than the length of the
+    /// string, the entire string is returned.
+    LLVM_ATTRIBUTE_ALWAYS_INLINE
+    LLVM_ATTRIBUTE_UNUSED_RESULT
+    StringRef take_back(size_t N = 1) const {
+      if (N >= size())
+        return *this;
+      return drop_front(size() - N);
+    }
+
     /// Return a StringRef equal to 'this' but with the first \p N elements
     /// dropped.
     LLVM_ATTRIBUTE_ALWAYS_INLINE

+ 14 - 0
unittests/ADT/ArrayRefTest.cpp

@@ -82,6 +82,20 @@ TEST(ArrayRefTest, DropFront) {
   EXPECT_EQ(1U, AR3.drop_front(AR3.size() - 1).size());
 }
 
+TEST(ArrayRefTest, KeepBack) {
+  static const int TheNumbers[] = {4, 8, 15, 16, 23, 42};
+  ArrayRef<int> AR1(TheNumbers);
+  ArrayRef<int> AR2(AR1.end() - 1, 1);
+  EXPECT_TRUE(AR1.keep_back().equals(AR2));
+}
+
+TEST(ArrayRefTest, KeepFront) {
+  static const int TheNumbers[] = {4, 8, 15, 16, 23, 42};
+  ArrayRef<int> AR1(TheNumbers);
+  ArrayRef<int> AR2(AR1.data(), 2);
+  EXPECT_TRUE(AR1.keep_front(2).equals(AR2));
+}
+
 TEST(ArrayRefTest, Equals) {
   static const int A1[] = {1, 2, 3, 4, 5, 6, 7, 8};
   ArrayRef<int> AR1(A1);

+ 43 - 0
unittests/ADT/StringRefTest.cpp

@@ -640,5 +640,48 @@ TEST(StringRefTest, AllocatorCopy) {
   EXPECT_NE(Str2.data(), Str2c.data());
 }
 
+TEST(StringRefTest, Drop) {
+  StringRef Test("StringRefTest::Drop");
+
+  StringRef Dropped = Test.drop_front(5);
+  EXPECT_EQ(Dropped, "gRefTest::Drop");
+
+  Dropped = Test.drop_back(5);
+  EXPECT_EQ(Dropped, "StringRefTest:");
+
+  Dropped = Test.drop_front(0);
+  EXPECT_EQ(Dropped, Test);
+
+  Dropped = Test.drop_back(0);
+  EXPECT_EQ(Dropped, Test);
+
+  Dropped = Test.drop_front(Test.size());
+  EXPECT_TRUE(Dropped.empty());
+
+  Dropped = Test.drop_back(Test.size());
+  EXPECT_TRUE(Dropped.empty());
+}
+
+TEST(StringRefTest, Take) {
+  StringRef Test("StringRefTest::Take");
+
+  StringRef Taken = Test.take_front(5);
+  EXPECT_EQ(Taken, "Strin");
+
+  Taken = Test.take_back(5);
+  EXPECT_EQ(Taken, ":Take");
+
+  Taken = Test.take_front(Test.size());
+  EXPECT_EQ(Taken, Test);
+
+  Taken = Test.take_back(Test.size());
+  EXPECT_EQ(Taken, Test);
+
+  Taken = Test.take_front(0);
+  EXPECT_TRUE(Taken.empty());
+
+  Taken = Test.take_back(0);
+  EXPECT_TRUE(Taken.empty());
+}
 
 } // end anonymous namespace