[llvm-commits] [llvm] r148881 - in /llvm/trunk: include/llvm/ADT/SmallString.h unittests/ADT/SmallStringTest.cpp

Talin viridia at gmail.com
Tue Jan 24 15:43:59 PST 2012


Author: talin
Date: Tue Jan 24 17:43:59 2012
New Revision: 148881

URL: http://llvm.org/viewvc/llvm-project?rev=148881&view=rev
Log:
Additional methods for SmallString.


Modified:
    llvm/trunk/include/llvm/ADT/SmallString.h
    llvm/trunk/unittests/ADT/SmallStringTest.cpp

Modified: llvm/trunk/include/llvm/ADT/SmallString.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/SmallString.h?rev=148881&r1=148880&r2=148881&view=diff
==============================================================================
--- llvm/trunk/include/llvm/ADT/SmallString.h (original)
+++ llvm/trunk/include/llvm/ADT/SmallString.h Tue Jan 24 17:43:59 2012
@@ -24,21 +24,244 @@
 template<unsigned InternalLen>
 class SmallString : public SmallVector<char, InternalLen> {
 public:
-  // Default ctor - Initialize to empty.
+  /// Default ctor - Initialize to empty.
   SmallString() {}
 
-  // Initialize from a StringRef.
+  /// Initialize from a StringRef.
   SmallString(StringRef S) : SmallVector<char, InternalLen>(S.begin(), S.end()) {}
 
-  // Initialize with a range.
+  /// Initialize with a range.
   template<typename ItTy>
   SmallString(ItTy S, ItTy E) : SmallVector<char, InternalLen>(S, E) {}
 
-  // Copy ctor.
+  /// Copy ctor.
   SmallString(const SmallString &RHS) : SmallVector<char, InternalLen>(RHS) {}
 
+  // Note that in order to add new overloads for append & assign, we have to
+  // duplicate the inherited versions so as not to inadvertently hide them.
+
+  /// @}
+  /// @name String Assignment
+  /// @{
+
+  /// Assign from a repeated element
+  void assign(unsigned NumElts, char Elt) {
+    this->SmallVectorImpl<char>::assign(NumElts, Elt);
+  }
+
+  /// Assign from an iterator pair
+  template<typename in_iter>
+  void assign(in_iter S, in_iter E) {
+    this->clear();
+    SmallVectorImpl<char>::append(S, E);
+  }
+
+  /// Assign from a StringRef
+  void assign(StringRef RHS) {
+    this->clear();
+    SmallVectorImpl<char>::append(RHS.begin(), RHS.end());
+  }
+
+  /// Assign from a SmallVector
+  void assign(const SmallVectorImpl<char> &RHS) {
+    this->clear();
+    SmallVectorImpl<char>::append(RHS.begin(), RHS.end());
+  }
+
+  /// @}
+  /// @name String Concatenation
+  /// @{
+
+  /// Append from an iterator pair
+  template<typename in_iter>
+  void append(in_iter S, in_iter E) {
+    SmallVectorImpl<char>::append(S, E);
+  }
+
+  /// Append from a StringRef
+  void append(StringRef RHS) {
+    SmallVectorImpl<char>::append(RHS.begin(), RHS.end());
+  }
+
+  /// Append from a SmallVector
+  void append(const SmallVectorImpl<char> &RHS) {
+    SmallVectorImpl<char>::append(RHS.begin(), RHS.end());
+  }
+
+  /// @}
+  /// @name String Comparison
+  /// @{
+
+  /// equals - Check for string equality, this is more efficient than
+  /// compare() when the relative ordering of inequal strings isn't needed.
+  bool equals(StringRef RHS) const {
+    return str().equals(RHS);
+  }
+
+  /// equals_lower - Check for string equality, ignoring case.
+  bool equals_lower(StringRef RHS) const {
+    return str().equals_lower(RHS);
+  }
+
+  /// compare - Compare two strings; the result is -1, 0, or 1 if this string
+  /// is lexicographically less than, equal to, or greater than the \arg RHS.
+  int compare(StringRef RHS) const {
+    return str().compare(RHS);
+  }
+
+  /// compare_lower - Compare two strings, ignoring case.
+  int compare_lower(StringRef RHS) const {
+    return str().compare_lower(RHS);
+  }
+
+  /// compare_numeric - Compare two strings, treating sequences of digits as
+  /// numbers.
+  int compare_numeric(StringRef RHS) const {
+    return str().compare_numeric(RHS);
+  }
+
+  /// @}
+  /// @name String Predicates
+  /// @{
+
+  /// startswith - Check if this string starts with the given \arg Prefix.
+  bool startswith(StringRef Prefix) const {
+    return str().startswith(Prefix);
+  }
+
+  /// endswith - Check if this string ends with the given \arg Suffix.
+  bool endswith(StringRef Suffix) const {
+    return str().endswith(Suffix);
+  }
+
+  /// @}
+  /// @name String Searching
+  /// @{
+
+  /// find - Search for the first character \arg C in the string.
+  ///
+  /// \return - The index of the first occurrence of \arg C, or npos if not
+  /// found.
+  size_t find(char C, size_t From = 0) const {
+    return str().find(C, From);
+  }
+
+  /// find - Search for the first string \arg Str in the string.
+  ///
+  /// \return - The index of the first occurrence of \arg Str, or npos if not
+  /// found.
+  size_t find(StringRef Str, size_t From = 0) const {
+    return str().find(Str, From);
+  }
+
+  /// rfind - Search for the last character \arg C in the string.
+  ///
+  /// \return - The index of the last occurrence of \arg C, or npos if not
+  /// found.
+  size_t rfind(char C, size_t From = StringRef::npos) const {
+    return str().rfind(C, From);
+  }
+
+  /// rfind - Search for the last string \arg Str in the string.
+  ///
+  /// \return - The index of the last occurrence of \arg Str, or npos if not
+  /// found.
+  size_t rfind(StringRef Str) const {
+    return str().rfind(Str);
+  }
+
+  /// find_first_of - Find the first character in the string that is \arg C,
+  /// or npos if not found. Same as find.
+  size_t find_first_of(char C, size_t From = 0) const {
+    return str().find_first_of(C, From);
+  }
+
+  /// find_first_of - Find the first character in the string that is in \arg
+  /// Chars, or npos if not found.
+  ///
+  /// Note: O(size() + Chars.size())
+  size_t find_first_of(StringRef Chars, size_t From = 0) const {
+    return str().find_first_of(Chars, From);
+  }
+
+  /// find_first_not_of - Find the first character in the string that is not
+  /// \arg C or npos if not found.
+  size_t find_first_not_of(char C, size_t From = 0) const {
+    return str().find_first_not_of(C, From);
+  }
+
+  /// find_first_not_of - Find the first character in the string that is not
+  /// in the string \arg Chars, or npos if not found.
+  ///
+  /// Note: O(size() + Chars.size())
+  size_t find_first_not_of(StringRef Chars, size_t From = 0) const {
+    return str().find_first_not_of(Chars, From);
+  }
+
+  /// find_last_of - Find the last character in the string that is \arg C, or
+  /// npos if not found.
+  size_t find_last_of(char C, size_t From = StringRef::npos) const {
+    return str().find_last_of(C, From);
+  }
+
+  /// find_last_of - Find the last character in the string that is in \arg C,
+  /// or npos if not found.
+  ///
+  /// Note: O(size() + Chars.size())
+  size_t find_last_of(
+      StringRef Chars, size_t From = StringRef::npos) const {
+    return str().find_last_of(Chars, From);
+  }
+
+  /// @}
+  /// @name Helpful Algorithms
+  /// @{
+
+  /// count - Return the number of occurrences of \arg C in the string.
+  size_t count(char C) const {
+    return str().count(C);
+  }
+
+  /// count - Return the number of non-overlapped occurrences of \arg Str in
+  /// the string.
+  size_t count(StringRef Str) const {
+    return str().count(Str);
+  }
+
+  /// @}
+  /// @name Substring Operations
+  /// @{
+
+  /// substr - Return a reference to the substring from [Start, Start + N).
+  ///
+  /// \param Start - The index of the starting character in the substring; if
+  /// the index is npos or greater than the length of the string then the
+  /// empty substring will be returned.
+  ///
+  /// \param N - The number of characters to included in the substring. If N
+  /// exceeds the number of characters remaining in the string, the string
+  /// suffix (starting with \arg Start) will be returned.
+  StringRef substr(size_t Start, size_t N = StringRef::npos) const {
+    return str().substr(Start, N);
+  }
+
+  /// slice - Return a reference to the substring from [Start, End).
+  ///
+  /// \param Start - The index of the starting character in the substring; if
+  /// the index is npos or greater than the length of the string then the
+  /// empty substring will be returned.
+  ///
+  /// \param End - The index following the last character to include in the
+  /// substring. If this is npos, or less than \arg Start, or exceeds the
+  /// number of characters remaining in the string, the string suffix
+  /// (starting with \arg Start) will be returned.
+  StringRef slice(size_t Start, size_t End) const {
+    return str().slice(Start, End);
+  }
 
   // Extra methods.
+
+  /// Explicit conversion to StringRef
   StringRef str() const { return StringRef(this->begin(), this->size()); }
 
   // TODO: Make this const, if it's safe...
@@ -48,7 +271,7 @@
     return this->data();
   }
 
-  // Implicit conversion to StringRef.
+  /// Implicit conversion to StringRef.
   operator StringRef() const { return str(); }
 
   // Extra operators.

Modified: llvm/trunk/unittests/ADT/SmallStringTest.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/ADT/SmallStringTest.cpp?rev=148881&r1=148880&r2=148881&view=diff
==============================================================================
--- llvm/trunk/unittests/ADT/SmallStringTest.cpp (original)
+++ llvm/trunk/unittests/ADT/SmallStringTest.cpp Tue Jan 24 17:43:59 2012
@@ -44,5 +44,153 @@
   EXPECT_TRUE(theString.rbegin() == theString.rend());
 }
 
+TEST_F(SmallStringTest, AssignRepeated) {
+  theString.assign(3, 'a');
+  EXPECT_EQ(3u, theString.size());
+  EXPECT_STREQ("aaa", theString.c_str());
 }
 
+TEST_F(SmallStringTest, AssignIterPair) {
+  StringRef abc = "abc";
+  theString.assign(abc.begin(), abc.end());
+  EXPECT_EQ(3u, theString.size());
+  EXPECT_STREQ("abc", theString.c_str());
+}
+
+TEST_F(SmallStringTest, AssignStringRef) {
+  StringRef abc = "abc";
+  theString.assign(abc);
+  EXPECT_EQ(3u, theString.size());
+  EXPECT_STREQ("abc", theString.c_str());
+}
+
+TEST_F(SmallStringTest, AssignSmallVector) {
+  StringRef abc = "abc";
+  SmallVector<char, 10> abcVec(abc.begin(), abc.end());
+  theString.assign(abcVec);
+  EXPECT_EQ(3u, theString.size());
+  EXPECT_STREQ("abc", theString.c_str());
+}
+
+TEST_F(SmallStringTest, AppendIterPair) {
+  StringRef abc = "abc";
+  theString.append(abc.begin(), abc.end());
+  theString.append(abc.begin(), abc.end());
+  EXPECT_EQ(6u, theString.size());
+  EXPECT_STREQ("abcabc", theString.c_str());
+}
+
+TEST_F(SmallStringTest, AppendStringRef) {
+  StringRef abc = "abc";
+  theString.append(abc);
+  theString.append(abc);
+  EXPECT_EQ(6u, theString.size());
+  EXPECT_STREQ("abcabc", theString.c_str());
+}
+
+TEST_F(SmallStringTest, AppendSmallVector) {
+  StringRef abc = "abc";
+  SmallVector<char, 10> abcVec(abc.begin(), abc.end());
+  theString.append(abcVec);
+  theString.append(abcVec);
+  EXPECT_EQ(6u, theString.size());
+  EXPECT_STREQ("abcabc", theString.c_str());
+}
+
+TEST_F(SmallStringTest, Substr) {
+  theString = "hello";
+  EXPECT_EQ("lo", theString.substr(3));
+  EXPECT_EQ("", theString.substr(100));
+  EXPECT_EQ("hello", theString.substr(0, 100));
+  EXPECT_EQ("o", theString.substr(4, 10));
+}
+
+TEST_F(SmallStringTest, Slice) {
+  theString = "hello";
+  EXPECT_EQ("l", theString.slice(2, 3));
+  EXPECT_EQ("ell", theString.slice(1, 4));
+  EXPECT_EQ("llo", theString.slice(2, 100));
+  EXPECT_EQ("", theString.slice(2, 1));
+  EXPECT_EQ("", theString.slice(10, 20));
+}
+
+TEST_F(SmallStringTest, Find) {
+  theString = "hello";
+  EXPECT_EQ(2U, theString.find('l'));
+  EXPECT_EQ(StringRef::npos, theString.find('z'));
+  EXPECT_EQ(StringRef::npos, theString.find("helloworld"));
+  EXPECT_EQ(0U, theString.find("hello"));
+  EXPECT_EQ(1U, theString.find("ello"));
+  EXPECT_EQ(StringRef::npos, theString.find("zz"));
+  EXPECT_EQ(2U, theString.find("ll", 2));
+  EXPECT_EQ(StringRef::npos, theString.find("ll", 3));
+  EXPECT_EQ(0U, theString.find(""));
+
+  EXPECT_EQ(3U, theString.rfind('l'));
+  EXPECT_EQ(StringRef::npos, theString.rfind('z'));
+  EXPECT_EQ(StringRef::npos, theString.rfind("helloworld"));
+  EXPECT_EQ(0U, theString.rfind("hello"));
+  EXPECT_EQ(1U, theString.rfind("ello"));
+  EXPECT_EQ(StringRef::npos, theString.rfind("zz"));
+
+  EXPECT_EQ(2U, theString.find_first_of('l'));
+  EXPECT_EQ(1U, theString.find_first_of("el"));
+  EXPECT_EQ(StringRef::npos, theString.find_first_of("xyz"));
+
+  EXPECT_EQ(1U, theString.find_first_not_of('h'));
+  EXPECT_EQ(4U, theString.find_first_not_of("hel"));
+  EXPECT_EQ(StringRef::npos, theString.find_first_not_of("hello"));
+
+  theString = "hellx xello hell ello world foo bar hello";
+  EXPECT_EQ(36U, theString.find("hello"));
+  EXPECT_EQ(28U, theString.find("foo"));
+  EXPECT_EQ(12U, theString.find("hell", 2));
+  EXPECT_EQ(0U, theString.find(""));
+}
+
+TEST_F(SmallStringTest, Count) {
+  theString = "hello";
+  EXPECT_EQ(2U, theString.count('l'));
+  EXPECT_EQ(1U, theString.count('o'));
+  EXPECT_EQ(0U, theString.count('z'));
+  EXPECT_EQ(0U, theString.count("helloworld"));
+  EXPECT_EQ(1U, theString.count("hello"));
+  EXPECT_EQ(1U, theString.count("ello"));
+  EXPECT_EQ(0U, theString.count("zz"));
+}
+
+TEST(StringRefTest, Comparisons) {
+  EXPECT_EQ(-1, SmallString<10>("aab").compare("aad"));
+  EXPECT_EQ( 0, SmallString<10>("aab").compare("aab"));
+  EXPECT_EQ( 1, SmallString<10>("aab").compare("aaa"));
+  EXPECT_EQ(-1, SmallString<10>("aab").compare("aabb"));
+  EXPECT_EQ( 1, SmallString<10>("aab").compare("aa"));
+  EXPECT_EQ( 1, SmallString<10>("\xFF").compare("\1"));
+
+  EXPECT_EQ(-1, SmallString<10>("AaB").compare_lower("aAd"));
+  EXPECT_EQ( 0, SmallString<10>("AaB").compare_lower("aab"));
+  EXPECT_EQ( 1, SmallString<10>("AaB").compare_lower("AAA"));
+  EXPECT_EQ(-1, SmallString<10>("AaB").compare_lower("aaBb"));
+  EXPECT_EQ( 1, SmallString<10>("AaB").compare_lower("aA"));
+  EXPECT_EQ( 1, SmallString<10>("\xFF").compare_lower("\1"));
+
+  EXPECT_EQ(-1, SmallString<10>("aab").compare_numeric("aad"));
+  EXPECT_EQ( 0, SmallString<10>("aab").compare_numeric("aab"));
+  EXPECT_EQ( 1, SmallString<10>("aab").compare_numeric("aaa"));
+  EXPECT_EQ(-1, SmallString<10>("aab").compare_numeric("aabb"));
+  EXPECT_EQ( 1, SmallString<10>("aab").compare_numeric("aa"));
+  EXPECT_EQ(-1, SmallString<10>("1").compare_numeric("10"));
+  EXPECT_EQ( 0, SmallString<10>("10").compare_numeric("10"));
+  EXPECT_EQ( 0, SmallString<10>("10a").compare_numeric("10a"));
+  EXPECT_EQ( 1, SmallString<10>("2").compare_numeric("1"));
+  EXPECT_EQ( 0, SmallString<10>("llvm_v1i64_ty").compare_numeric("llvm_v1i64_ty"));
+  EXPECT_EQ( 1, SmallString<10>("\xFF").compare_numeric("\1"));
+  EXPECT_EQ( 1, SmallString<10>("V16").compare_numeric("V1_q0"));
+  EXPECT_EQ(-1, SmallString<10>("V1_q0").compare_numeric("V16"));
+  EXPECT_EQ(-1, SmallString<10>("V8_q0").compare_numeric("V16"));
+  EXPECT_EQ( 1, SmallString<10>("V16").compare_numeric("V8_q0"));
+  EXPECT_EQ(-1, SmallString<10>("V1_q0").compare_numeric("V8_q0"));
+  EXPECT_EQ( 1, SmallString<10>("V8_q0").compare_numeric("V1_q0"));
+}
+
+}





More information about the llvm-commits mailing list