diff options
-rw-r--r-- | llvm/include/llvm/ADT/ArrayRef.h | 32 | ||||
-rw-r--r-- | llvm/include/llvm/ADT/StringRef.h | 22 | ||||
-rw-r--r-- | llvm/unittests/ADT/ArrayRefTest.cpp | 14 | ||||
-rw-r--r-- | llvm/unittests/ADT/StringRefTest.cpp | 43 |
4 files changed, 111 insertions, 0 deletions
diff --git a/llvm/include/llvm/ADT/ArrayRef.h b/llvm/include/llvm/ADT/ArrayRef.h index bfe851485f3..6a6d581eb29 100644 --- a/llvm/include/llvm/ADT/ArrayRef.h +++ b/llvm/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 /// @{ diff --git a/llvm/include/llvm/ADT/StringRef.h b/llvm/include/llvm/ADT/StringRef.h index c753b7f1494..37c214cdff7 100644 --- a/llvm/include/llvm/ADT/StringRef.h +++ b/llvm/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 diff --git a/llvm/unittests/ADT/ArrayRefTest.cpp b/llvm/unittests/ADT/ArrayRefTest.cpp index 132be35eb16..62d36819fde 100644 --- a/llvm/unittests/ADT/ArrayRefTest.cpp +++ b/llvm/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); diff --git a/llvm/unittests/ADT/StringRefTest.cpp b/llvm/unittests/ADT/StringRefTest.cpp index 72018869742..97ddaf6adcc 100644 --- a/llvm/unittests/ADT/StringRefTest.cpp +++ b/llvm/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 |