Add StringRef::{rfind, rsplit}

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@82087 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Daniel Dunbar 2009-09-16 22:38:48 +00:00
parent 358f1ef765
commit e65512809a
4 changed files with 150 additions and 42 deletions

View File

@ -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));
}
/// @}
};

View File

@ -27,6 +27,7 @@ add_llvm_library(LLVMSupport
StringExtras.cpp
StringMap.cpp
StringPool.cpp
StringRef.cpp
SystemUtils.cpp
TargetRegistry.cpp
Timer.cpp

13
lib/Support/StringRef.cpp Normal file
View File

@ -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;

View File

@ -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_EQ("lo", Str.substr(3));
EXPECT_EQ("", Str.substr(100));
EXPECT_EQ("hello", Str.substr(0, 100));
EXPECT_EQ("o", Str.substr(4, 10));
}
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) == "");
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));
}
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("")));
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