LLVM API Documentation

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