SmallString.h revision 249423
191592Smarkm//===- llvm/ADT/SmallString.h - 'Normally small' strings --------*- C++ -*-===// 214963Spaul// 314963Spaul// The LLVM Compiler Infrastructure 414963Spaul// 514963Spaul// This file is distributed under the University of Illinois Open Source 614963Spaul// License. See LICENSE.TXT for details. 714963Spaul// 814963Spaul//===----------------------------------------------------------------------===// 914963Spaul// 1014963Spaul// This file defines the SmallString class. 1114963Spaul// 1214963Spaul//===----------------------------------------------------------------------===// 1314963Spaul 1414963Spaul#ifndef LLVM_ADT_SMALLSTRING_H 1514963Spaul#define LLVM_ADT_SMALLSTRING_H 1614963Spaul 1714963Spaul#include "llvm/ADT/SmallVector.h" 1814963Spaul#include "llvm/ADT/StringRef.h" 1914963Spaul 2014963Spaulnamespace llvm { 2114963Spaul 2214963Spaul/// SmallString - A SmallString is just a SmallVector with methods and accessors 2314963Spaul/// that make it work better as a string (e.g. operator+ etc). 2414963Spaultemplate<unsigned InternalLen> 2514963Spaulclass SmallString : public SmallVector<char, InternalLen> { 2614963Spaulpublic: 2714963Spaul /// Default ctor - Initialize to empty. 2814963Spaul SmallString() {} 2914963Spaul 3014963Spaul /// Initialize from a StringRef. 3114963Spaul SmallString(StringRef S) : SmallVector<char, InternalLen>(S.begin(), S.end()) {} 3275730Sasmodai 3375730Sasmodai /// Initialize with a range. 3414963Spaul template<typename ItTy> 3514963Spaul SmallString(ItTy S, ItTy E) : SmallVector<char, InternalLen>(S, E) {} 3614963Spaul 3714963Spaul /// Copy ctor. 3814963Spaul SmallString(const SmallString &RHS) : SmallVector<char, InternalLen>(RHS) {} 3914963Spaul 4014963Spaul // Note that in order to add new overloads for append & assign, we have to 4114963Spaul // duplicate the inherited versions so as not to inadvertently hide them. 4214963Spaul 4314963Spaul /// @} 4414963Spaul /// @name String Assignment 4514963Spaul /// @{ 4614963Spaul 4714963Spaul /// Assign from a repeated element. 4814963Spaul void assign(size_t NumElts, char Elt) { 4914963Spaul this->SmallVectorImpl<char>::assign(NumElts, Elt); 5014963Spaul } 5114963Spaul 5214963Spaul /// Assign from an iterator pair. 5314963Spaul template<typename in_iter> 5414963Spaul void assign(in_iter S, in_iter E) { 5514963Spaul this->clear(); 5614963Spaul SmallVectorImpl<char>::append(S, E); 5714963Spaul } 5814963Spaul 5914963Spaul /// Assign from a StringRef. 6014963Spaul void assign(StringRef RHS) { 6114963Spaul this->clear(); 6214963Spaul SmallVectorImpl<char>::append(RHS.begin(), RHS.end()); 6314963Spaul } 6414963Spaul 6514963Spaul /// Assign from a SmallVector. 6614963Spaul void assign(const SmallVectorImpl<char> &RHS) { 6714963Spaul this->clear(); 6814963Spaul SmallVectorImpl<char>::append(RHS.begin(), RHS.end()); 6914963Spaul } 7014963Spaul 7114963Spaul /// @} 7214963Spaul /// @name String Concatenation 7314963Spaul /// @{ 7414963Spaul 7514963Spaul /// Append from an iterator pair. 7614963Spaul template<typename in_iter> 7714963Spaul void append(in_iter S, in_iter E) { 7814963Spaul SmallVectorImpl<char>::append(S, E); 7914963Spaul } 8014963Spaul 8114963Spaul void append(size_t NumInputs, char Elt) { 8214963Spaul SmallVectorImpl<char>::append(NumInputs, Elt); 8314963Spaul } 8414963Spaul 8514963Spaul 8614963Spaul /// Append from a StringRef. 8714963Spaul void append(StringRef RHS) { 8814963Spaul SmallVectorImpl<char>::append(RHS.begin(), RHS.end()); 8914963Spaul } 9014963Spaul 9114963Spaul /// Append from a SmallVector. 9214963Spaul void append(const SmallVectorImpl<char> &RHS) { 9314963Spaul SmallVectorImpl<char>::append(RHS.begin(), RHS.end()); 9414963Spaul } 9514963Spaul 9614963Spaul /// @} 9714963Spaul /// @name String Comparison 9814963Spaul /// @{ 9914963Spaul 10014963Spaul /// Check for string equality. This is more efficient than compare() when 10114963Spaul /// the relative ordering of inequal strings isn't needed. 10214963Spaul bool equals(StringRef RHS) const { 10314963Spaul return str().equals(RHS); 10414963Spaul } 10514963Spaul 10614963Spaul /// Check for string equality, ignoring case. 10714963Spaul bool equals_lower(StringRef RHS) const { 10814963Spaul return str().equals_lower(RHS); 10914963Spaul } 11014963Spaul 11114963Spaul /// Compare two strings; the result is -1, 0, or 1 if this string is 11214963Spaul /// lexicographically less than, equal to, or greater than the \p RHS. 11314963Spaul int compare(StringRef RHS) const { 11414963Spaul return str().compare(RHS); 11514963Spaul } 11614963Spaul 11714963Spaul /// compare_lower - Compare two strings, ignoring case. 11814963Spaul int compare_lower(StringRef RHS) const { 11914963Spaul return str().compare_lower(RHS); 12014963Spaul } 12114963Spaul 12214963Spaul /// compare_numeric - Compare two strings, treating sequences of digits as 12314963Spaul /// numbers. 12414963Spaul int compare_numeric(StringRef RHS) const { 12514963Spaul return str().compare_numeric(RHS); 12614963Spaul } 12714963Spaul 12814963Spaul /// @} 12914963Spaul /// @name String Predicates 13014963Spaul /// @{ 13114963Spaul 13214963Spaul /// startswith - Check if this string starts with the given \p Prefix. 13314963Spaul bool startswith(StringRef Prefix) const { 13414963Spaul return str().startswith(Prefix); 13514963Spaul } 13614963Spaul 13714963Spaul /// endswith - Check if this string ends with the given \p Suffix. 13814963Spaul bool endswith(StringRef Suffix) const { 13914963Spaul return str().endswith(Suffix); 14014963Spaul } 14114963Spaul 14214963Spaul /// @} 14314963Spaul /// @name String Searching 14414963Spaul /// @{ 14514963Spaul 14614963Spaul /// find - Search for the first character \p C in the string. 14714963Spaul /// 14814963Spaul /// \return - The index of the first occurrence of \p C, or npos if not 14914963Spaul /// found. 15014963Spaul size_t find(char C, size_t From = 0) const { 15114963Spaul return str().find(C, From); 15214963Spaul } 15314963Spaul 15414963Spaul /// Search for the first string \p Str in the string. 15514963Spaul /// 15614963Spaul /// \returns The index of the first occurrence of \p Str, or npos if not 15714963Spaul /// found. 15814963Spaul size_t find(StringRef Str, size_t From = 0) const { 15914963Spaul return str().find(Str, From); 16014963Spaul } 16114963Spaul 16214963Spaul /// Search for the last character \p C in the string. 16314963Spaul /// 16414963Spaul /// \returns The index of the last occurrence of \p C, or npos if not 16514963Spaul /// found. 16614963Spaul size_t rfind(char C, size_t From = StringRef::npos) const { 16714963Spaul return str().rfind(C, From); 16814963Spaul } 16914963Spaul 17014963Spaul /// Search for the last string \p Str in the string. 17114963Spaul /// 17214963Spaul /// \returns The index of the last occurrence of \p Str, or npos if not 17314963Spaul /// found. 17414963Spaul size_t rfind(StringRef Str) const { 17514963Spaul return str().rfind(Str); 17614963Spaul } 17714963Spaul 17814963Spaul /// Find the first character in the string that is \p C, or npos if not 17914963Spaul /// found. Same as find. 18014963Spaul size_t find_first_of(char C, size_t From = 0) const { 18114963Spaul return str().find_first_of(C, From); 18214963Spaul } 18314963Spaul 18414963Spaul /// Find the first character in the string that is in \p Chars, or npos if 18514963Spaul /// not found. 18614963Spaul /// 18714963Spaul /// Complexity: O(size() + Chars.size()) 18814963Spaul size_t find_first_of(StringRef Chars, size_t From = 0) const { 18914963Spaul return str().find_first_of(Chars, From); 19014963Spaul } 19114963Spaul 19214963Spaul /// Find the first character in the string that is not \p C or npos if not 19314963Spaul /// found. 19414963Spaul size_t find_first_not_of(char C, size_t From = 0) const { 19514963Spaul return str().find_first_not_of(C, From); 19614963Spaul } 19714963Spaul 19814963Spaul /// Find the first character in the string that is not in the string 19914963Spaul /// \p Chars, or npos if not found. 20014963Spaul /// 20114963Spaul /// Complexity: O(size() + Chars.size()) 20214963Spaul size_t find_first_not_of(StringRef Chars, size_t From = 0) const { 20314963Spaul return str().find_first_not_of(Chars, From); 20414963Spaul } 20514963Spaul 20614963Spaul /// Find the last character in the string that is \p C, or npos if not 20714963Spaul /// found. 20814963Spaul size_t find_last_of(char C, size_t From = StringRef::npos) const { 20914963Spaul return str().find_last_of(C, From); 21014963Spaul } 21114963Spaul 21214963Spaul /// Find the last character in the string that is in \p C, or npos if not 21314963Spaul /// found. 21414963Spaul /// 21514963Spaul /// Complexity: O(size() + Chars.size()) 21614963Spaul size_t find_last_of( 21714963Spaul StringRef Chars, size_t From = StringRef::npos) const { 21814963Spaul return str().find_last_of(Chars, From); 21914963Spaul } 22014963Spaul 22114963Spaul /// @} 22214963Spaul /// @name Helpful Algorithms 22314963Spaul /// @{ 22414963Spaul 22514963Spaul /// Return the number of occurrences of \p C in the string. 22614963Spaul size_t count(char C) const { 22714963Spaul return str().count(C); 22814963Spaul } 22914963Spaul 23014963Spaul /// Return the number of non-overlapped occurrences of \p Str in the 23114963Spaul /// string. 23214963Spaul size_t count(StringRef Str) const { 23314963Spaul return str().count(Str); 23414963Spaul } 23514963Spaul 23614963Spaul /// @} 23714963Spaul /// @name Substring Operations 23814963Spaul /// @{ 23914963Spaul 24014963Spaul /// Return a reference to the substring from [Start, Start + N). 24114963Spaul /// 24214963Spaul /// \param Start The index of the starting character in the substring; if 24314963Spaul /// the index is npos or greater than the length of the string then the 24414963Spaul /// empty substring will be returned. 24514963Spaul /// 24614963Spaul /// \param N The number of characters to included in the substring. If \p N 24714963Spaul /// exceeds the number of characters remaining in the string, the string 24814963Spaul /// suffix (starting with \p Start) will be returned. 24914963Spaul StringRef substr(size_t Start, size_t N = StringRef::npos) const { 25014963Spaul return str().substr(Start, N); 25114963Spaul } 25214963Spaul 25314963Spaul /// Return a reference to the substring from [Start, End). 25414963Spaul /// 255 /// \param Start The index of the starting character in the substring; if 256 /// the index is npos or greater than the length of the string then the 257 /// empty substring will be returned. 258 /// 259 /// \param End The index following the last character to include in the 260 /// substring. If this is npos, or less than \p Start, or exceeds the 261 /// number of characters remaining in the string, the string suffix 262 /// (starting with \p Start) will be returned. 263 StringRef slice(size_t Start, size_t End) const { 264 return str().slice(Start, End); 265 } 266 267 // Extra methods. 268 269 /// Explicit conversion to StringRef. 270 StringRef str() const { return StringRef(this->begin(), this->size()); } 271 272 // TODO: Make this const, if it's safe... 273 const char* c_str() { 274 this->push_back(0); 275 this->pop_back(); 276 return this->data(); 277 } 278 279 /// Implicit conversion to StringRef. 280 operator StringRef() const { return str(); } 281 282 // Extra operators. 283 const SmallString &operator=(StringRef RHS) { 284 this->clear(); 285 return *this += RHS; 286 } 287 288 SmallString &operator+=(StringRef RHS) { 289 this->append(RHS.begin(), RHS.end()); 290 return *this; 291 } 292 SmallString &operator+=(char C) { 293 this->push_back(C); 294 return *this; 295 } 296}; 297 298} 299 300#endif 301