aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDaniel Dunbar <daniel@zuster.org>2009-09-16 22:38:48 +0000
committerDaniel Dunbar <daniel@zuster.org>2009-09-16 22:38:48 +0000
commite65512809a4144c17538aac4cc59fac6d325a7e4 (patch)
treebe1cc374a08ca577ef4144eb7065872af199c499
parent358f1ef765ba1b385795e03c80fdd4cbd924d010 (diff)
downloadexternal_llvm-e65512809a4144c17538aac4cc59fac6d325a7e4.zip
external_llvm-e65512809a4144c17538aac4cc59fac6d325a7e4.tar.gz
external_llvm-e65512809a4144c17538aac4cc59fac6d325a7e4.tar.bz2
Add StringRef::{rfind, rsplit}
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@82087 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/llvm/ADT/StringRef.h50
-rw-r--r--lib/Support/CMakeLists.txt1
-rw-r--r--lib/Support/StringRef.cpp13
-rw-r--r--unittests/ADT/StringRefTest.cpp132
4 files changed, 152 insertions, 44 deletions
diff --git a/include/llvm/ADT/StringRef.h b/include/llvm/ADT/StringRef.h
index acfc335..74d3eaa 100644
--- a/include/llvm/ADT/StringRef.h
+++ b/include/llvm/ADT/StringRef.h
@@ -147,7 +147,7 @@ namespace llvm {
/// @name String Searching
/// @{
- /// find - Search for the character \arg C in the string.
+ /// find - Search for the first character \arg C in the string.
///
/// \return - The index of the first occurence of \arg C, or npos if not
/// found.
@@ -158,7 +158,7 @@ namespace llvm {
return npos;
}
- /// find - Search for the string \arg Str in the string.
+ /// find - Search for the first string \arg Str in the string.
///
/// \return - The index of the first occurence of \arg Str, or npos if not
/// found.
@@ -172,6 +172,35 @@ namespace llvm {
return npos;
}
+ /// rfind - Search for the last character \arg C in the string.
+ ///
+ /// \return - The index of the last occurence of \arg C, or npos if not
+ /// found.
+ size_t rfind(char C) const {
+ for (size_t i = Length, e = 0; i != e;) {
+ --i;
+ if (Data[i] == C)
+ return i;
+ }
+ return npos;
+ }
+
+ /// rfind - Search for the last string \arg Str in the string.
+ ///
+ /// \return - The index of the last occurence of \arg Str, or npos if not
+ /// found.
+ size_t rfind(const StringRef &Str) const {
+ size_t N = Str.size();
+ if (N > Length)
+ return npos;
+ for (size_t i = Length - N + 1, e = 0; i != e;) {
+ --i;
+ if (substr(i, N).equals(Str))
+ return i;
+ }
+ return npos;
+ }
+
/// count - Return the number of occurrences of \arg C in the string.
size_t count(char C) const {
size_t Count = 0;
@@ -245,6 +274,23 @@ namespace llvm {
return std::make_pair(slice(0, Idx), slice(Idx+1, npos));
}
+ /// rsplit - Split into two substrings around the last occurence of a
+ /// separator character.
+ ///
+ /// If \arg 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 \arg Separator is not in the string, then the result is a
+ /// pair (LHS, RHS) where (*this == LHS) and (RHS == "").
+ ///
+ /// \param Separator - The character to split on.
+ /// \return - The split substrings.
+ std::pair<StringRef, StringRef> 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));
+ }
+
/// @}
};
diff --git a/lib/Support/CMakeLists.txt b/lib/Support/CMakeLists.txt
index 4f02397..cd355ff 100644
--- a/lib/Support/CMakeLists.txt
+++ b/lib/Support/CMakeLists.txt
@@ -27,6 +27,7 @@ add_llvm_library(LLVMSupport
StringExtras.cpp
StringMap.cpp
StringPool.cpp
+ StringRef.cpp
SystemUtils.cpp
TargetRegistry.cpp
Timer.cpp
diff --git a/lib/Support/StringRef.cpp b/lib/Support/StringRef.cpp
new file mode 100644
index 0000000..4751f06
--- /dev/null
+++ b/lib/Support/StringRef.cpp
@@ -0,0 +1,13 @@
+//===-- StringRef.cpp - Lightweight String References ---------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/ADT/StringRef.h"
+using namespace llvm;
+
+const size_t StringRef::npos;
diff --git a/unittests/ADT/StringRefTest.cpp b/unittests/ADT/StringRefTest.cpp
index 320633a..cdc476e 100644
--- a/unittests/ADT/StringRefTest.cpp
+++ b/unittests/ADT/StringRefTest.cpp
@@ -14,18 +14,29 @@ using namespace llvm;
namespace {
+std::ostream &operator<<(std::ostream &OS, const StringRef &S) {
+ OS << S;
+ return OS;
+}
+
+std::ostream &operator<<(std::ostream &OS,
+ const std::pair<StringRef, StringRef> &P) {
+ OS << "(" << P.first << ", " << P.second << ")";
+ return OS;
+}
+
TEST(StringRefTest, Construction) {
- EXPECT_TRUE(StringRef() == "");
- EXPECT_TRUE(StringRef("hello") == "hello");
- EXPECT_TRUE(StringRef("hello world", 5) == "hello");
- EXPECT_TRUE(StringRef(std::string("hello")) == "hello");
+ EXPECT_EQ("", StringRef());
+ EXPECT_EQ("hello", StringRef("hello"));
+ EXPECT_EQ("hello", StringRef("hello world", 5));
+ EXPECT_EQ("hello", StringRef(std::string("hello")));
}
TEST(StringRefTest, Iteration) {
StringRef S("hello");
const char *p = "hello";
for (const char *it = S.begin(), *ie = S.end(); it != ie; ++it, ++p)
- EXPECT_TRUE(*p == *it);
+ EXPECT_EQ(*it, *p);
}
TEST(StringRefTest, StringOps) {
@@ -41,7 +52,7 @@ TEST(StringRefTest, StringOps) {
}
TEST(StringRefTest, Operators) {
- EXPECT_TRUE(StringRef() == "");
+ EXPECT_EQ("", StringRef());
EXPECT_TRUE(StringRef("aab") < StringRef("aad"));
EXPECT_FALSE(StringRef("aab") < StringRef("aab"));
EXPECT_TRUE(StringRef("aab") <= StringRef("aab"));
@@ -50,58 +61,95 @@ TEST(StringRefTest, Operators) {
EXPECT_FALSE(StringRef("aab") > StringRef("aab"));
EXPECT_TRUE(StringRef("aab") >= StringRef("aab"));
EXPECT_FALSE(StringRef("aaa") >= StringRef("aab"));
- EXPECT_TRUE(StringRef("aab") == StringRef("aab"));
+ EXPECT_EQ(StringRef("aab"), StringRef("aab"));
EXPECT_FALSE(StringRef("aab") == StringRef("aac"));
EXPECT_FALSE(StringRef("aab") != StringRef("aab"));
EXPECT_TRUE(StringRef("aab") != StringRef("aac"));
EXPECT_EQ('a', StringRef("aab")[1]);
}
-TEST(StringRefTest, Utilities) {
+TEST(StringRefTest, Substr) {
StringRef Str("hello");
- EXPECT_TRUE(Str.substr(3) == "lo");
- EXPECT_TRUE(Str.substr(100) == "");
- EXPECT_TRUE(Str.substr(0, 100) == "hello");
- EXPECT_TRUE(Str.substr(4, 10) == "o");
-
- EXPECT_TRUE(Str.slice(2, 3) == "l");
- EXPECT_TRUE(Str.slice(1, 4) == "ell");
- EXPECT_TRUE(Str.slice(2, 100) == "llo");
- EXPECT_TRUE(Str.slice(2, 1) == "");
- EXPECT_TRUE(Str.slice(10, 20) == "");
-
- EXPECT_TRUE(Str.split('X') == std::make_pair(StringRef("hello"),
- StringRef("")));
- EXPECT_TRUE(Str.split('e') == std::make_pair(StringRef("h"),
- StringRef("llo")));
- EXPECT_TRUE(Str.split('h') == std::make_pair(StringRef(""),
- StringRef("ello")));
- EXPECT_TRUE(Str.split('o') == std::make_pair(StringRef("hell"),
- StringRef("")));
+ EXPECT_EQ("lo", Str.substr(3));
+ EXPECT_EQ("", Str.substr(100));
+ EXPECT_EQ("hello", Str.substr(0, 100));
+ EXPECT_EQ("o", Str.substr(4, 10));
+}
+
+TEST(StringRefTest, Slice) {
+ StringRef Str("hello");
+ EXPECT_EQ("l", Str.slice(2, 3));
+ EXPECT_EQ("ell", Str.slice(1, 4));
+ EXPECT_EQ("llo", Str.slice(2, 100));
+ EXPECT_EQ("", Str.slice(2, 1));
+ EXPECT_EQ("", Str.slice(10, 20));
+}
+
+TEST(StringRefTest, Split) {
+ StringRef Str("hello");
+ EXPECT_EQ(std::make_pair(StringRef("hello"), StringRef("")),
+ Str.split('X'));
+ EXPECT_EQ(std::make_pair(StringRef("h"), StringRef("llo")),
+ Str.split('e'));
+ EXPECT_EQ(std::make_pair(StringRef(""), StringRef("ello")),
+ Str.split('h'));
+ EXPECT_EQ(std::make_pair(StringRef("he"), StringRef("lo")),
+ Str.split('l'));
+ EXPECT_EQ(std::make_pair(StringRef("hell"), StringRef("")),
+ Str.split('o'));
+
+ EXPECT_EQ(std::make_pair(StringRef("hello"), StringRef("")),
+ Str.rsplit('X'));
+ EXPECT_EQ(std::make_pair(StringRef("h"), StringRef("llo")),
+ Str.rsplit('e'));
+ EXPECT_EQ(std::make_pair(StringRef(""), StringRef("ello")),
+ Str.rsplit('h'));
+ EXPECT_EQ(std::make_pair(StringRef("hel"), StringRef("o")),
+ Str.rsplit('l'));
+ EXPECT_EQ(std::make_pair(StringRef("hell"), StringRef("")),
+ Str.rsplit('o'));
+}
+TEST(StringRefTest, StartsWith) {
+ StringRef Str("hello");
EXPECT_TRUE(Str.startswith("he"));
EXPECT_FALSE(Str.startswith("helloworld"));
EXPECT_FALSE(Str.startswith("hi"));
+}
+TEST(StringRefTest, Find) {
+ StringRef Str("hello");
+ EXPECT_EQ(2U, Str.find('l'));
+ EXPECT_EQ(StringRef::npos, Str.find('z'));
+ EXPECT_EQ(StringRef::npos, Str.find("helloworld"));
+ EXPECT_EQ(0U, Str.find("hello"));
+ EXPECT_EQ(1U, Str.find("ello"));
+ EXPECT_EQ(StringRef::npos, Str.find("zz"));
+
+ EXPECT_EQ(3U, Str.rfind('l'));
+ EXPECT_EQ(StringRef::npos, Str.rfind('z'));
+ EXPECT_EQ(StringRef::npos, Str.rfind("helloworld"));
+ EXPECT_EQ(0U, Str.rfind("hello"));
+ EXPECT_EQ(1U, Str.rfind("ello"));
+ EXPECT_EQ(StringRef::npos, Str.rfind("zz"));
+}
+
+TEST(StringRefTest, Count) {
+ StringRef Str("hello");
+ EXPECT_EQ(2U, Str.count('l'));
+ EXPECT_EQ(1U, Str.count('o'));
+ EXPECT_EQ(0U, Str.count('z'));
+ EXPECT_EQ(0U, Str.count("helloworld"));
+ EXPECT_EQ(1U, Str.count("hello"));
+ EXPECT_EQ(1U, Str.count("ello"));
+ EXPECT_EQ(0U, Str.count("zz"));
+}
+
+TEST(StringRefTest, Misc) {
std::string Storage;
raw_string_ostream OS(Storage);
OS << StringRef("hello");
EXPECT_EQ("hello", OS.str());
-
- EXPECT_TRUE(Str.find('l') == 2);
- EXPECT_TRUE(Str.find('z') == StringRef::npos);
- EXPECT_TRUE(Str.find("helloworld") == StringRef::npos);
- EXPECT_TRUE(Str.find("hello") == 0);
- EXPECT_TRUE(Str.find("ello") == 1);
- EXPECT_TRUE(Str.find("zz") == StringRef::npos);
-
- EXPECT_TRUE(Str.count('l') == 2);
- EXPECT_TRUE(Str.count('o') == 1);
- EXPECT_TRUE(Str.count('z') == 0);
- EXPECT_TRUE(Str.count("helloworld") == 0);
- EXPECT_TRUE(Str.count("hello") == 1);
- EXPECT_TRUE(Str.count("ello") == 1);
- EXPECT_TRUE(Str.count("zz") == 0);
}
} // end anonymous namespace