LLVM  mainline
SmallString.h
Go to the documentation of this file.
00001 //===- llvm/ADT/SmallString.h - 'Normally small' strings --------*- C++ -*-===//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file is distributed under the University of Illinois Open Source
00006 // License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 //
00010 // This file defines the SmallString class.
00011 //
00012 //===----------------------------------------------------------------------===//
00013 
00014 #ifndef LLVM_ADT_SMALLSTRING_H
00015 #define LLVM_ADT_SMALLSTRING_H
00016 
00017 #include "llvm/ADT/SmallVector.h"
00018 #include "llvm/ADT/StringRef.h"
00019 
00020 namespace llvm {
00021 
00022 /// SmallString - A SmallString is just a SmallVector with methods and accessors
00023 /// that make it work better as a string (e.g. operator+ etc).
00024 template<unsigned InternalLen>
00025 class SmallString : public SmallVector<char, InternalLen> {
00026 public:
00027   /// Default ctor - Initialize to empty.
00028   SmallString() {}
00029 
00030   /// Initialize from a StringRef.
00031   SmallString(StringRef S) : SmallVector<char, InternalLen>(S.begin(), S.end()) {}
00032 
00033   /// Initialize with a range.
00034   template<typename ItTy>
00035   SmallString(ItTy S, ItTy E) : SmallVector<char, InternalLen>(S, E) {}
00036 
00037   // Note that in order to add new overloads for append & assign, we have to
00038   // duplicate the inherited versions so as not to inadvertently hide them.
00039 
00040   /// @}
00041   /// @name String Assignment
00042   /// @{
00043 
00044   /// Assign from a repeated element.
00045   void assign(size_t NumElts, char Elt) {
00046     this->SmallVectorImpl<char>::assign(NumElts, Elt);
00047   }
00048 
00049   /// Assign from an iterator pair.
00050   template<typename in_iter>
00051   void assign(in_iter S, in_iter E) {
00052     this->clear();
00053     SmallVectorImpl<char>::append(S, E);
00054   }
00055 
00056   /// Assign from a StringRef.
00057   void assign(StringRef RHS) {
00058     this->clear();
00059     SmallVectorImpl<char>::append(RHS.begin(), RHS.end());
00060   }
00061 
00062   /// Assign from a SmallVector.
00063   void assign(const SmallVectorImpl<char> &RHS) {
00064     this->clear();
00065     SmallVectorImpl<char>::append(RHS.begin(), RHS.end());
00066   }
00067 
00068   /// @}
00069   /// @name String Concatenation
00070   /// @{
00071 
00072   /// Append from an iterator pair.
00073   template<typename in_iter>
00074   void append(in_iter S, in_iter E) {
00075     SmallVectorImpl<char>::append(S, E);
00076   }
00077 
00078   void append(size_t NumInputs, char Elt) {
00079     SmallVectorImpl<char>::append(NumInputs, Elt);
00080   }
00081 
00082 
00083   /// Append from a StringRef.
00084   void append(StringRef RHS) {
00085     SmallVectorImpl<char>::append(RHS.begin(), RHS.end());
00086   }
00087 
00088   /// Append from a SmallVector.
00089   void append(const SmallVectorImpl<char> &RHS) {
00090     SmallVectorImpl<char>::append(RHS.begin(), RHS.end());
00091   }
00092 
00093   /// @}
00094   /// @name String Comparison
00095   /// @{
00096 
00097   /// Check for string equality.  This is more efficient than compare() when
00098   /// the relative ordering of inequal strings isn't needed.
00099   bool equals(StringRef RHS) const {
00100     return str().equals(RHS);
00101   }
00102 
00103   /// Check for string equality, ignoring case.
00104   bool equals_lower(StringRef RHS) const {
00105     return str().equals_lower(RHS);
00106   }
00107 
00108   /// Compare two strings; the result is -1, 0, or 1 if this string is
00109   /// lexicographically less than, equal to, or greater than the \p RHS.
00110   int compare(StringRef RHS) const {
00111     return str().compare(RHS);
00112   }
00113 
00114   /// compare_lower - Compare two strings, ignoring case.
00115   int compare_lower(StringRef RHS) const {
00116     return str().compare_lower(RHS);
00117   }
00118 
00119   /// compare_numeric - Compare two strings, treating sequences of digits as
00120   /// numbers.
00121   int compare_numeric(StringRef RHS) const {
00122     return str().compare_numeric(RHS);
00123   }
00124 
00125   /// @}
00126   /// @name String Predicates
00127   /// @{
00128 
00129   /// startswith - Check if this string starts with the given \p Prefix.
00130   bool startswith(StringRef Prefix) const {
00131     return str().startswith(Prefix);
00132   }
00133 
00134   /// endswith - Check if this string ends with the given \p Suffix.
00135   bool endswith(StringRef Suffix) const {
00136     return str().endswith(Suffix);
00137   }
00138 
00139   /// @}
00140   /// @name String Searching
00141   /// @{
00142 
00143   /// find - Search for the first character \p C in the string.
00144   ///
00145   /// \return - The index of the first occurrence of \p C, or npos if not
00146   /// found.
00147   size_t find(char C, size_t From = 0) const {
00148     return str().find(C, From);
00149   }
00150 
00151   /// Search for the first string \p Str in the string.
00152   ///
00153   /// \returns The index of the first occurrence of \p Str, or npos if not
00154   /// found.
00155   size_t find(StringRef Str, size_t From = 0) const {
00156     return str().find(Str, From);
00157   }
00158 
00159   /// Search for the last character \p C in the string.
00160   ///
00161   /// \returns The index of the last occurrence of \p C, or npos if not
00162   /// found.
00163   size_t rfind(char C, size_t From = StringRef::npos) const {
00164     return str().rfind(C, From);
00165   }
00166 
00167   /// Search for the last string \p Str in the string.
00168   ///
00169   /// \returns The index of the last occurrence of \p Str, or npos if not
00170   /// found.
00171   size_t rfind(StringRef Str) const {
00172     return str().rfind(Str);
00173   }
00174 
00175   /// Find the first character in the string that is \p C, or npos if not
00176   /// found. Same as find.
00177   size_t find_first_of(char C, size_t From = 0) const {
00178     return str().find_first_of(C, From);
00179   }
00180 
00181   /// Find the first character in the string that is in \p Chars, or npos if
00182   /// not found.
00183   ///
00184   /// Complexity: O(size() + Chars.size())
00185   size_t find_first_of(StringRef Chars, size_t From = 0) const {
00186     return str().find_first_of(Chars, From);
00187   }
00188 
00189   /// Find the first character in the string that is not \p C or npos if not
00190   /// found.
00191   size_t find_first_not_of(char C, size_t From = 0) const {
00192     return str().find_first_not_of(C, From);
00193   }
00194 
00195   /// Find the first character in the string that is not in the string
00196   /// \p Chars, or npos if not found.
00197   ///
00198   /// Complexity: O(size() + Chars.size())
00199   size_t find_first_not_of(StringRef Chars, size_t From = 0) const {
00200     return str().find_first_not_of(Chars, From);
00201   }
00202 
00203   /// Find the last character in the string that is \p C, or npos if not
00204   /// found.
00205   size_t find_last_of(char C, size_t From = StringRef::npos) const {
00206     return str().find_last_of(C, From);
00207   }
00208 
00209   /// Find the last character in the string that is in \p C, or npos if not
00210   /// found.
00211   ///
00212   /// Complexity: O(size() + Chars.size())
00213   size_t find_last_of(
00214       StringRef Chars, size_t From = StringRef::npos) const {
00215     return str().find_last_of(Chars, From);
00216   }
00217 
00218   /// @}
00219   /// @name Helpful Algorithms
00220   /// @{
00221 
00222   /// Return the number of occurrences of \p C in the string.
00223   size_t count(char C) const {
00224     return str().count(C);
00225   }
00226 
00227   /// Return the number of non-overlapped occurrences of \p Str in the
00228   /// string.
00229   size_t count(StringRef Str) const {
00230     return str().count(Str);
00231   }
00232 
00233   /// @}
00234   /// @name Substring Operations
00235   /// @{
00236 
00237   /// Return a reference to the substring from [Start, Start + N).
00238   ///
00239   /// \param Start The index of the starting character in the substring; if
00240   /// the index is npos or greater than the length of the string then the
00241   /// empty substring will be returned.
00242   ///
00243   /// \param N The number of characters to included in the substring. If \p N
00244   /// exceeds the number of characters remaining in the string, the string
00245   /// suffix (starting with \p Start) will be returned.
00246   StringRef substr(size_t Start, size_t N = StringRef::npos) const {
00247     return str().substr(Start, N);
00248   }
00249 
00250   /// Return a reference to the substring from [Start, End).
00251   ///
00252   /// \param Start The index of the starting character in the substring; if
00253   /// the index is npos or greater than the length of the string then the
00254   /// empty substring will be returned.
00255   ///
00256   /// \param End The index following the last character to include in the
00257   /// substring. If this is npos, or less than \p Start, or exceeds the
00258   /// number of characters remaining in the string, the string suffix
00259   /// (starting with \p Start) will be returned.
00260   StringRef slice(size_t Start, size_t End) const {
00261     return str().slice(Start, End);
00262   }
00263 
00264   // Extra methods.
00265 
00266   /// Explicit conversion to StringRef.
00267   StringRef str() const { return StringRef(this->begin(), this->size()); }
00268 
00269   // TODO: Make this const, if it's safe...
00270   const char* c_str() {
00271     this->push_back(0);
00272     this->pop_back();
00273     return this->data();
00274   }
00275 
00276   /// Implicit conversion to StringRef.
00277   operator StringRef() const { return str(); }
00278 
00279   // Extra operators.
00280   const SmallString &operator=(StringRef RHS) {
00281     this->clear();
00282     return *this += RHS;
00283   }
00284 
00285   SmallString &operator+=(StringRef RHS) {
00286     this->append(RHS.begin(), RHS.end());
00287     return *this;
00288   }
00289   SmallString &operator+=(char C) {
00290     this->push_back(C);
00291     return *this;
00292   }
00293 };
00294 
00295 }
00296 
00297 #endif