Index: include/llvm/ADT/ArrayRef.h =================================================================== --- include/llvm/ADT/ArrayRef.h +++ include/llvm/ADT/ArrayRef.h @@ -195,6 +195,22 @@ return slice(0, size() - N); } + /// \brief Keep the first \p N elements of the array. + LLVM_ATTRIBUTE_UNUSED_RESULT + ArrayRef 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 keep_back(size_t N = 1) const { + if (N >= size()) + return *this; + return drop_front(size() - N); + } + /// @} /// @name Operator Overloads /// @{ @@ -321,6 +337,22 @@ return slice(0, this->size() - N); } + /// \brief Drop the first \p N elements of the array. + LLVM_ATTRIBUTE_UNUSED_RESULT + MutableArrayRef keep_front(size_t N = 1) const { + if (N >= this->size()) + return *this; + return drop_back(size() - N); + } + + /// \brief Keep the first \p N elements of the array. + LLVM_ATTRIBUTE_UNUSED_RESULT + MutableArrayRef keep_back(size_t N = 1) const { + if (N >= this->size()) + return *this; + return drop_front(size() - N); + } + /// @} /// @name Operator Overloads /// @{ Index: include/llvm/ADT/StringRef.h =================================================================== --- include/llvm/ADT/StringRef.h +++ include/llvm/ADT/StringRef.h @@ -428,6 +428,28 @@ 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 keep_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 keep_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 Index: unittests/ADT/ArrayRefTest.cpp =================================================================== --- unittests/ADT/ArrayRefTest.cpp +++ unittests/ADT/ArrayRefTest.cpp @@ -82,6 +82,20 @@ EXPECT_EQ(1U, AR3.drop_front(AR3.size() - 1).size()); } +TEST(ArrayRefTest, KeepBack) { + static const int TheNumbers[] = {4, 8, 15, 16, 23, 42}; + ArrayRef AR1(TheNumbers); + ArrayRef 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 AR1(TheNumbers); + ArrayRef 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 AR1(A1); Index: unittests/ADT/StringRefTest.cpp =================================================================== --- unittests/ADT/StringRefTest.cpp +++ unittests/ADT/StringRefTest.cpp @@ -640,5 +640,48 @@ 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, Keep) { + StringRef Test("StringRefTest::Keep"); + + StringRef Kept = Test.keep_front(5); + EXPECT_EQ(Kept, "Strin"); + + Kept = Test.keep_back(5); + EXPECT_EQ(Kept, ":Keep"); + + Kept = Test.keep_front(Test.size()); + EXPECT_EQ(Kept, Test); + + Kept = Test.keep_back(Test.size()); + EXPECT_EQ(Kept, Test); + + Kept = Test.keep_front(0); + EXPECT_TRUE(Kept.empty()); + + Kept = Test.keep_back(0); + EXPECT_TRUE(Kept.empty()); +} } // end anonymous namespace