From 945c481a57a21ae25c40ae9a58469c652c88e2ce Mon Sep 17 00:00:00 2001 From: Henry Wong Date: Fri, 8 Jun 2018 12:42:12 +0000 Subject: [PATCH] [ADT] Add `StringRef::rsplit(StringRef Separator)`. Summary: Add `StringRef::rsplit(StringRef Separator)` to achieve the function of getting the tail substring according to the separator. A typical usage is to get `data` in `std::basic_string::data`. Reviewers: mehdi_amini, zturner, beanz, xbolva00, vsk Reviewed By: zturner, xbolva00, vsk Subscribers: vsk, xbolva00, llvm-commits, MTC Differential Revision: https://reviews.llvm.org/D47406 llvm-svn: 334283 --- llvm/include/llvm/ADT/StringRef.h | 28 ++++++++++++++++++++-------- llvm/unittests/ADT/StringRefTest.cpp | 11 +++++++++++ 2 files changed, 31 insertions(+), 8 deletions(-) diff --git a/llvm/include/llvm/ADT/StringRef.h b/llvm/include/llvm/ADT/StringRef.h index 2704ab00b104..a5ba5b59b5a3 100644 --- a/llvm/include/llvm/ADT/StringRef.h +++ b/llvm/include/llvm/ADT/StringRef.h @@ -725,10 +725,7 @@ namespace llvm { /// \returns The split substrings. LLVM_NODISCARD std::pair split(char Separator) const { - size_t Idx = find(Separator); - if (Idx == npos) - return std::make_pair(*this, StringRef()); - return std::make_pair(slice(0, Idx), slice(Idx+1, npos)); + return split(StringRef(&Separator, 1)); } /// Split into two substrings around the first occurrence of a separator @@ -749,6 +746,24 @@ namespace llvm { return std::make_pair(slice(0, Idx), slice(Idx + Separator.size(), npos)); } + /// Split into two substrings around the last occurrence of a separator + /// string. + /// + /// If \p Separator is in the string, then the result is a pair (LHS, RHS) + /// such that (*this == LHS + Separator + RHS) is true and RHS is + /// minimal. If \p Separator is not in the string, then the result is a + /// pair (LHS, RHS) where (*this == LHS) and (RHS == ""). + /// + /// \param Separator - The string to split on. + /// \return - The split substrings. + LLVM_NODISCARD + std::pair rsplit(StringRef Separator) const { + size_t Idx = rfind(Separator); + if (Idx == npos) + return std::make_pair(*this, StringRef()); + return std::make_pair(slice(0, Idx), slice(Idx + Separator.size(), npos)); + } + /// Split into substrings around the occurrences of a separator string. /// /// Each substring is stored in \p A. If \p MaxSplit is >= 0, at most @@ -796,10 +811,7 @@ namespace llvm { /// \return - The split substrings. LLVM_NODISCARD std::pair rsplit(char Separator) const { - size_t Idx = rfind(Separator); - if (Idx == npos) - return std::make_pair(*this, StringRef()); - return std::make_pair(slice(0, Idx), slice(Idx+1, npos)); + return rsplit(StringRef(&Separator, 1)); } /// Return string with consecutive \p Char characters starting from the diff --git a/llvm/unittests/ADT/StringRefTest.cpp b/llvm/unittests/ADT/StringRefTest.cpp index 8c4099e6e810..4087d6c99a93 100644 --- a/llvm/unittests/ADT/StringRefTest.cpp +++ b/llvm/unittests/ADT/StringRefTest.cpp @@ -181,6 +181,17 @@ TEST(StringRefTest, Split) { Str.rsplit('l')); EXPECT_EQ(std::make_pair(StringRef("hell"), StringRef("")), Str.rsplit('o')); + + EXPECT_EQ(std::make_pair(StringRef("he"), StringRef("o")), + Str.rsplit("ll")); + EXPECT_EQ(std::make_pair(StringRef(""), StringRef("ello")), + Str.rsplit("h")); + EXPECT_EQ(std::make_pair(StringRef("hell"), StringRef("")), + Str.rsplit("o")); + EXPECT_EQ(std::make_pair(StringRef("hello"), StringRef("")), + Str.rsplit("::")); + EXPECT_EQ(std::make_pair(StringRef("hel"), StringRef("o")), + Str.rsplit("l")); } TEST(StringRefTest, Split2) {