1193323Sed//===- llvm/ADT/SmallString.h - 'Normally small' strings --------*- C++ -*-===// 2193323Sed// 3193323Sed// The LLVM Compiler Infrastructure 4193323Sed// 5193323Sed// This file is distributed under the University of Illinois Open Source 6193323Sed// License. See LICENSE.TXT for details. 7193323Sed// 8193323Sed//===----------------------------------------------------------------------===// 9193323Sed// 10193323Sed// This file defines the SmallString class. 11193323Sed// 12193323Sed//===----------------------------------------------------------------------===// 13193323Sed 14193323Sed#ifndef LLVM_ADT_SMALLSTRING_H 15193323Sed#define LLVM_ADT_SMALLSTRING_H 16193323Sed 17193323Sed#include "llvm/ADT/SmallVector.h" 18198090Srdivacky#include "llvm/ADT/StringRef.h" 19193323Sed 20193323Sednamespace llvm { 21193323Sed 22193323Sed/// SmallString - A SmallString is just a SmallVector with methods and accessors 23193323Sed/// that make it work better as a string (e.g. operator+ etc). 24193323Sedtemplate<unsigned InternalLen> 25193323Sedclass SmallString : public SmallVector<char, InternalLen> { 26193323Sedpublic: 27234353Sdim /// Default ctor - Initialize to empty. 28193323Sed SmallString() {} 29193323Sed 30234353Sdim /// Initialize from a StringRef. 31218893Sdim SmallString(StringRef S) : SmallVector<char, InternalLen>(S.begin(), S.end()) {} 32218893Sdim 33234353Sdim /// Initialize with a range. 34193323Sed template<typename ItTy> 35193323Sed SmallString(ItTy S, ItTy E) : SmallVector<char, InternalLen>(S, E) {} 36193323Sed 37234353Sdim /// Copy ctor. 38193323Sed SmallString(const SmallString &RHS) : SmallVector<char, InternalLen>(RHS) {} 39193323Sed 40234353Sdim // Note that in order to add new overloads for append & assign, we have to 41234353Sdim // duplicate the inherited versions so as not to inadvertently hide them. 42193323Sed 43234353Sdim /// @} 44234353Sdim /// @name String Assignment 45234353Sdim /// @{ 46234353Sdim 47243830Sdim /// Assign from a repeated element. 48239462Sdim void assign(size_t NumElts, char Elt) { 49234353Sdim this->SmallVectorImpl<char>::assign(NumElts, Elt); 50234353Sdim } 51234353Sdim 52243830Sdim /// Assign from an iterator pair. 53234353Sdim template<typename in_iter> 54234353Sdim void assign(in_iter S, in_iter E) { 55234353Sdim this->clear(); 56234353Sdim SmallVectorImpl<char>::append(S, E); 57234353Sdim } 58234353Sdim 59243830Sdim /// Assign from a StringRef. 60234353Sdim void assign(StringRef RHS) { 61234353Sdim this->clear(); 62234353Sdim SmallVectorImpl<char>::append(RHS.begin(), RHS.end()); 63234353Sdim } 64234353Sdim 65243830Sdim /// Assign from a SmallVector. 66234353Sdim void assign(const SmallVectorImpl<char> &RHS) { 67234353Sdim this->clear(); 68234353Sdim SmallVectorImpl<char>::append(RHS.begin(), RHS.end()); 69234353Sdim } 70234353Sdim 71234353Sdim /// @} 72234353Sdim /// @name String Concatenation 73234353Sdim /// @{ 74234353Sdim 75243830Sdim /// Append from an iterator pair. 76234353Sdim template<typename in_iter> 77234353Sdim void append(in_iter S, in_iter E) { 78234353Sdim SmallVectorImpl<char>::append(S, E); 79234353Sdim } 80249423Sdim 81239462Sdim void append(size_t NumInputs, char Elt) { 82239462Sdim SmallVectorImpl<char>::append(NumInputs, Elt); 83239462Sdim } 84234353Sdim 85239462Sdim 86243830Sdim /// Append from a StringRef. 87234353Sdim void append(StringRef RHS) { 88234353Sdim SmallVectorImpl<char>::append(RHS.begin(), RHS.end()); 89234353Sdim } 90234353Sdim 91243830Sdim /// Append from a SmallVector. 92234353Sdim void append(const SmallVectorImpl<char> &RHS) { 93234353Sdim SmallVectorImpl<char>::append(RHS.begin(), RHS.end()); 94234353Sdim } 95234353Sdim 96234353Sdim /// @} 97234353Sdim /// @name String Comparison 98234353Sdim /// @{ 99234353Sdim 100243830Sdim /// Check for string equality. This is more efficient than compare() when 101243830Sdim /// the relative ordering of inequal strings isn't needed. 102234353Sdim bool equals(StringRef RHS) const { 103234353Sdim return str().equals(RHS); 104234353Sdim } 105234353Sdim 106243830Sdim /// Check for string equality, ignoring case. 107234353Sdim bool equals_lower(StringRef RHS) const { 108234353Sdim return str().equals_lower(RHS); 109234353Sdim } 110234353Sdim 111243830Sdim /// Compare two strings; the result is -1, 0, or 1 if this string is 112243830Sdim /// lexicographically less than, equal to, or greater than the \p RHS. 113234353Sdim int compare(StringRef RHS) const { 114234353Sdim return str().compare(RHS); 115234353Sdim } 116234353Sdim 117234353Sdim /// compare_lower - Compare two strings, ignoring case. 118234353Sdim int compare_lower(StringRef RHS) const { 119234353Sdim return str().compare_lower(RHS); 120234353Sdim } 121234353Sdim 122234353Sdim /// compare_numeric - Compare two strings, treating sequences of digits as 123234353Sdim /// numbers. 124234353Sdim int compare_numeric(StringRef RHS) const { 125234353Sdim return str().compare_numeric(RHS); 126234353Sdim } 127234353Sdim 128234353Sdim /// @} 129234353Sdim /// @name String Predicates 130234353Sdim /// @{ 131234353Sdim 132243830Sdim /// startswith - Check if this string starts with the given \p Prefix. 133234353Sdim bool startswith(StringRef Prefix) const { 134234353Sdim return str().startswith(Prefix); 135234353Sdim } 136234353Sdim 137243830Sdim /// endswith - Check if this string ends with the given \p Suffix. 138234353Sdim bool endswith(StringRef Suffix) const { 139234353Sdim return str().endswith(Suffix); 140234353Sdim } 141234353Sdim 142234353Sdim /// @} 143234353Sdim /// @name String Searching 144234353Sdim /// @{ 145234353Sdim 146243830Sdim /// find - Search for the first character \p C in the string. 147234353Sdim /// 148243830Sdim /// \return - The index of the first occurrence of \p C, or npos if not 149234353Sdim /// found. 150234353Sdim size_t find(char C, size_t From = 0) const { 151234353Sdim return str().find(C, From); 152234353Sdim } 153234353Sdim 154243830Sdim /// Search for the first string \p Str in the string. 155234353Sdim /// 156243830Sdim /// \returns The index of the first occurrence of \p Str, or npos if not 157234353Sdim /// found. 158234353Sdim size_t find(StringRef Str, size_t From = 0) const { 159234353Sdim return str().find(Str, From); 160234353Sdim } 161234353Sdim 162243830Sdim /// Search for the last character \p C in the string. 163234353Sdim /// 164243830Sdim /// \returns The index of the last occurrence of \p C, or npos if not 165234353Sdim /// found. 166234353Sdim size_t rfind(char C, size_t From = StringRef::npos) const { 167234353Sdim return str().rfind(C, From); 168234353Sdim } 169234353Sdim 170243830Sdim /// Search for the last string \p Str in the string. 171234353Sdim /// 172243830Sdim /// \returns The index of the last occurrence of \p Str, or npos if not 173234353Sdim /// found. 174234353Sdim size_t rfind(StringRef Str) const { 175234353Sdim return str().rfind(Str); 176234353Sdim } 177234353Sdim 178243830Sdim /// Find the first character in the string that is \p C, or npos if not 179243830Sdim /// found. Same as find. 180234353Sdim size_t find_first_of(char C, size_t From = 0) const { 181234353Sdim return str().find_first_of(C, From); 182234353Sdim } 183234353Sdim 184243830Sdim /// Find the first character in the string that is in \p Chars, or npos if 185243830Sdim /// not found. 186234353Sdim /// 187243830Sdim /// Complexity: O(size() + Chars.size()) 188234353Sdim size_t find_first_of(StringRef Chars, size_t From = 0) const { 189234353Sdim return str().find_first_of(Chars, From); 190234353Sdim } 191234353Sdim 192243830Sdim /// Find the first character in the string that is not \p C or npos if not 193243830Sdim /// found. 194234353Sdim size_t find_first_not_of(char C, size_t From = 0) const { 195234353Sdim return str().find_first_not_of(C, From); 196234353Sdim } 197234353Sdim 198243830Sdim /// Find the first character in the string that is not in the string 199243830Sdim /// \p Chars, or npos if not found. 200234353Sdim /// 201243830Sdim /// Complexity: O(size() + Chars.size()) 202234353Sdim size_t find_first_not_of(StringRef Chars, size_t From = 0) const { 203234353Sdim return str().find_first_not_of(Chars, From); 204234353Sdim } 205234353Sdim 206243830Sdim /// Find the last character in the string that is \p C, or npos if not 207243830Sdim /// found. 208234353Sdim size_t find_last_of(char C, size_t From = StringRef::npos) const { 209234353Sdim return str().find_last_of(C, From); 210234353Sdim } 211234353Sdim 212243830Sdim /// Find the last character in the string that is in \p C, or npos if not 213243830Sdim /// found. 214234353Sdim /// 215243830Sdim /// Complexity: O(size() + Chars.size()) 216234353Sdim size_t find_last_of( 217234353Sdim StringRef Chars, size_t From = StringRef::npos) const { 218234353Sdim return str().find_last_of(Chars, From); 219234353Sdim } 220234353Sdim 221234353Sdim /// @} 222234353Sdim /// @name Helpful Algorithms 223234353Sdim /// @{ 224234353Sdim 225243830Sdim /// Return the number of occurrences of \p C in the string. 226234353Sdim size_t count(char C) const { 227234353Sdim return str().count(C); 228234353Sdim } 229234353Sdim 230243830Sdim /// Return the number of non-overlapped occurrences of \p Str in the 231243830Sdim /// string. 232234353Sdim size_t count(StringRef Str) const { 233234353Sdim return str().count(Str); 234234353Sdim } 235234353Sdim 236234353Sdim /// @} 237234353Sdim /// @name Substring Operations 238234353Sdim /// @{ 239234353Sdim 240243830Sdim /// Return a reference to the substring from [Start, Start + N). 241234353Sdim /// 242243830Sdim /// \param Start The index of the starting character in the substring; if 243234353Sdim /// the index is npos or greater than the length of the string then the 244234353Sdim /// empty substring will be returned. 245234353Sdim /// 246243830Sdim /// \param N The number of characters to included in the substring. If \p N 247234353Sdim /// exceeds the number of characters remaining in the string, the string 248243830Sdim /// suffix (starting with \p Start) will be returned. 249234353Sdim StringRef substr(size_t Start, size_t N = StringRef::npos) const { 250234353Sdim return str().substr(Start, N); 251234353Sdim } 252234353Sdim 253243830Sdim /// Return a reference to the substring from [Start, End). 254234353Sdim /// 255243830Sdim /// \param Start The index of the starting character in the substring; if 256234353Sdim /// the index is npos or greater than the length of the string then the 257234353Sdim /// empty substring will be returned. 258234353Sdim /// 259243830Sdim /// \param End The index following the last character to include in the 260243830Sdim /// substring. If this is npos, or less than \p Start, or exceeds the 261234353Sdim /// number of characters remaining in the string, the string suffix 262243830Sdim /// (starting with \p Start) will be returned. 263234353Sdim StringRef slice(size_t Start, size_t End) const { 264234353Sdim return str().slice(Start, End); 265234353Sdim } 266234353Sdim 267193323Sed // Extra methods. 268234353Sdim 269243830Sdim /// Explicit conversion to StringRef. 270198090Srdivacky StringRef str() const { return StringRef(this->begin(), this->size()); } 271198090Srdivacky 272218893Sdim // TODO: Make this const, if it's safe... 273218893Sdim const char* c_str() { 274198090Srdivacky this->push_back(0); 275198090Srdivacky this->pop_back(); 276198090Srdivacky return this->data(); 277193323Sed } 278199989Srdivacky 279234353Sdim /// Implicit conversion to StringRef. 280218893Sdim operator StringRef() const { return str(); } 281218893Sdim 282193323Sed // Extra operators. 283198090Srdivacky const SmallString &operator=(StringRef RHS) { 284193323Sed this->clear(); 285193323Sed return *this += RHS; 286193323Sed } 287193323Sed 288198090Srdivacky SmallString &operator+=(StringRef RHS) { 289198090Srdivacky this->append(RHS.begin(), RHS.end()); 290193323Sed return *this; 291193323Sed } 292193323Sed SmallString &operator+=(char C) { 293193323Sed this->push_back(C); 294193323Sed return *this; 295193323Sed } 296193323Sed}; 297193323Sed 298193323Sed} 299193323Sed 300193323Sed#endif 301