1dd94c8d6b2afb9c33c364ac8f0c8f8ed5d4c04a0Chris Lattner//===- llvm/ADT/SmallString.h - 'Normally small' strings --------*- C++ -*-===//
2dd94c8d6b2afb9c33c364ac8f0c8f8ed5d4c04a0Chris Lattner//
3dd94c8d6b2afb9c33c364ac8f0c8f8ed5d4c04a0Chris Lattner//                     The LLVM Compiler Infrastructure
4dd94c8d6b2afb9c33c364ac8f0c8f8ed5d4c04a0Chris Lattner//
57ed47a13356daed2a34cd2209a31f92552e3bdd8Chris Lattner// This file is distributed under the University of Illinois Open Source
67ed47a13356daed2a34cd2209a31f92552e3bdd8Chris Lattner// License. See LICENSE.TXT for details.
7dd94c8d6b2afb9c33c364ac8f0c8f8ed5d4c04a0Chris Lattner//
8dd94c8d6b2afb9c33c364ac8f0c8f8ed5d4c04a0Chris Lattner//===----------------------------------------------------------------------===//
9dd94c8d6b2afb9c33c364ac8f0c8f8ed5d4c04a0Chris Lattner//
10dd94c8d6b2afb9c33c364ac8f0c8f8ed5d4c04a0Chris Lattner// This file defines the SmallString class.
11dd94c8d6b2afb9c33c364ac8f0c8f8ed5d4c04a0Chris Lattner//
12dd94c8d6b2afb9c33c364ac8f0c8f8ed5d4c04a0Chris Lattner//===----------------------------------------------------------------------===//
13dd94c8d6b2afb9c33c364ac8f0c8f8ed5d4c04a0Chris Lattner
14dd94c8d6b2afb9c33c364ac8f0c8f8ed5d4c04a0Chris Lattner#ifndef LLVM_ADT_SMALLSTRING_H
15dd94c8d6b2afb9c33c364ac8f0c8f8ed5d4c04a0Chris Lattner#define LLVM_ADT_SMALLSTRING_H
16dd94c8d6b2afb9c33c364ac8f0c8f8ed5d4c04a0Chris Lattner
17dd94c8d6b2afb9c33c364ac8f0c8f8ed5d4c04a0Chris Lattner#include "llvm/ADT/SmallVector.h"
1804087d069a17265b964b30e8210262bbdbc4fbecDaniel Dunbar#include "llvm/ADT/StringRef.h"
19dd94c8d6b2afb9c33c364ac8f0c8f8ed5d4c04a0Chris Lattner
20dd94c8d6b2afb9c33c364ac8f0c8f8ed5d4c04a0Chris Lattnernamespace llvm {
21dd94c8d6b2afb9c33c364ac8f0c8f8ed5d4c04a0Chris Lattner
22dd94c8d6b2afb9c33c364ac8f0c8f8ed5d4c04a0Chris Lattner/// SmallString - A SmallString is just a SmallVector with methods and accessors
23dd94c8d6b2afb9c33c364ac8f0c8f8ed5d4c04a0Chris Lattner/// that make it work better as a string (e.g. operator+ etc).
24dd94c8d6b2afb9c33c364ac8f0c8f8ed5d4c04a0Chris Lattnertemplate<unsigned InternalLen>
25dd94c8d6b2afb9c33c364ac8f0c8f8ed5d4c04a0Chris Lattnerclass SmallString : public SmallVector<char, InternalLen> {
26dd94c8d6b2afb9c33c364ac8f0c8f8ed5d4c04a0Chris Lattnerpublic:
272527188a42b3250671b69dc979102565be1f910fTalin  /// Default ctor - Initialize to empty.
28dd94c8d6b2afb9c33c364ac8f0c8f8ed5d4c04a0Chris Lattner  SmallString() {}
29dd94c8d6b2afb9c33c364ac8f0c8f8ed5d4c04a0Chris Lattner
302527188a42b3250671b69dc979102565be1f910fTalin  /// Initialize from a StringRef.
31965841cfe4de695fc56cab4821fd7e032ff85b83Michael J. Spencer  SmallString(StringRef S) : SmallVector<char, InternalLen>(S.begin(), S.end()) {}
32965841cfe4de695fc56cab4821fd7e032ff85b83Michael J. Spencer
332527188a42b3250671b69dc979102565be1f910fTalin  /// Initialize with a range.
34dd94c8d6b2afb9c33c364ac8f0c8f8ed5d4c04a0Chris Lattner  template<typename ItTy>
35dd94c8d6b2afb9c33c364ac8f0c8f8ed5d4c04a0Chris Lattner  SmallString(ItTy S, ItTy E) : SmallVector<char, InternalLen>(S, E) {}
363a54b3dc87a581c203b18050b4f787b4ca28a12cMisha Brukman
372527188a42b3250671b69dc979102565be1f910fTalin  // Note that in order to add new overloads for append & assign, we have to
382527188a42b3250671b69dc979102565be1f910fTalin  // duplicate the inherited versions so as not to inadvertently hide them.
392527188a42b3250671b69dc979102565be1f910fTalin
402527188a42b3250671b69dc979102565be1f910fTalin  /// @}
412527188a42b3250671b69dc979102565be1f910fTalin  /// @name String Assignment
422527188a42b3250671b69dc979102565be1f910fTalin  /// @{
432527188a42b3250671b69dc979102565be1f910fTalin
442d9eb72178af8e79dc6432cd1b7d29bde16da1b9Dmitri Gribenko  /// Assign from a repeated element.
4555738761b393cc844e230a74e29edf4cdc37e9b8Chris Lattner  void assign(size_t NumElts, char Elt) {
462527188a42b3250671b69dc979102565be1f910fTalin    this->SmallVectorImpl<char>::assign(NumElts, Elt);
472527188a42b3250671b69dc979102565be1f910fTalin  }
482527188a42b3250671b69dc979102565be1f910fTalin
492d9eb72178af8e79dc6432cd1b7d29bde16da1b9Dmitri Gribenko  /// Assign from an iterator pair.
502527188a42b3250671b69dc979102565be1f910fTalin  template<typename in_iter>
512527188a42b3250671b69dc979102565be1f910fTalin  void assign(in_iter S, in_iter E) {
522527188a42b3250671b69dc979102565be1f910fTalin    this->clear();
532527188a42b3250671b69dc979102565be1f910fTalin    SmallVectorImpl<char>::append(S, E);
542527188a42b3250671b69dc979102565be1f910fTalin  }
552527188a42b3250671b69dc979102565be1f910fTalin
562d9eb72178af8e79dc6432cd1b7d29bde16da1b9Dmitri Gribenko  /// Assign from a StringRef.
572527188a42b3250671b69dc979102565be1f910fTalin  void assign(StringRef RHS) {
582527188a42b3250671b69dc979102565be1f910fTalin    this->clear();
592527188a42b3250671b69dc979102565be1f910fTalin    SmallVectorImpl<char>::append(RHS.begin(), RHS.end());
602527188a42b3250671b69dc979102565be1f910fTalin  }
612527188a42b3250671b69dc979102565be1f910fTalin
622d9eb72178af8e79dc6432cd1b7d29bde16da1b9Dmitri Gribenko  /// Assign from a SmallVector.
632527188a42b3250671b69dc979102565be1f910fTalin  void assign(const SmallVectorImpl<char> &RHS) {
642527188a42b3250671b69dc979102565be1f910fTalin    this->clear();
652527188a42b3250671b69dc979102565be1f910fTalin    SmallVectorImpl<char>::append(RHS.begin(), RHS.end());
662527188a42b3250671b69dc979102565be1f910fTalin  }
672527188a42b3250671b69dc979102565be1f910fTalin
682527188a42b3250671b69dc979102565be1f910fTalin  /// @}
692527188a42b3250671b69dc979102565be1f910fTalin  /// @name String Concatenation
702527188a42b3250671b69dc979102565be1f910fTalin  /// @{
712527188a42b3250671b69dc979102565be1f910fTalin
722d9eb72178af8e79dc6432cd1b7d29bde16da1b9Dmitri Gribenko  /// Append from an iterator pair.
732527188a42b3250671b69dc979102565be1f910fTalin  template<typename in_iter>
742527188a42b3250671b69dc979102565be1f910fTalin  void append(in_iter S, in_iter E) {
752527188a42b3250671b69dc979102565be1f910fTalin    SmallVectorImpl<char>::append(S, E);
762527188a42b3250671b69dc979102565be1f910fTalin  }
7754932806ac65c9818b9845ca337e57a471b31789Matt Arsenault
7855738761b393cc844e230a74e29edf4cdc37e9b8Chris Lattner  void append(size_t NumInputs, char Elt) {
7955738761b393cc844e230a74e29edf4cdc37e9b8Chris Lattner    SmallVectorImpl<char>::append(NumInputs, Elt);
8055738761b393cc844e230a74e29edf4cdc37e9b8Chris Lattner  }
8155738761b393cc844e230a74e29edf4cdc37e9b8Chris Lattner
822527188a42b3250671b69dc979102565be1f910fTalin
832d9eb72178af8e79dc6432cd1b7d29bde16da1b9Dmitri Gribenko  /// Append from a StringRef.
842527188a42b3250671b69dc979102565be1f910fTalin  void append(StringRef RHS) {
852527188a42b3250671b69dc979102565be1f910fTalin    SmallVectorImpl<char>::append(RHS.begin(), RHS.end());
862527188a42b3250671b69dc979102565be1f910fTalin  }
872527188a42b3250671b69dc979102565be1f910fTalin
882d9eb72178af8e79dc6432cd1b7d29bde16da1b9Dmitri Gribenko  /// Append from a SmallVector.
892527188a42b3250671b69dc979102565be1f910fTalin  void append(const SmallVectorImpl<char> &RHS) {
902527188a42b3250671b69dc979102565be1f910fTalin    SmallVectorImpl<char>::append(RHS.begin(), RHS.end());
912527188a42b3250671b69dc979102565be1f910fTalin  }
922527188a42b3250671b69dc979102565be1f910fTalin
932527188a42b3250671b69dc979102565be1f910fTalin  /// @}
942527188a42b3250671b69dc979102565be1f910fTalin  /// @name String Comparison
952527188a42b3250671b69dc979102565be1f910fTalin  /// @{
962527188a42b3250671b69dc979102565be1f910fTalin
972d9eb72178af8e79dc6432cd1b7d29bde16da1b9Dmitri Gribenko  /// Check for string equality.  This is more efficient than compare() when
982d9eb72178af8e79dc6432cd1b7d29bde16da1b9Dmitri Gribenko  /// the relative ordering of inequal strings isn't needed.
992527188a42b3250671b69dc979102565be1f910fTalin  bool equals(StringRef RHS) const {
1002527188a42b3250671b69dc979102565be1f910fTalin    return str().equals(RHS);
1012527188a42b3250671b69dc979102565be1f910fTalin  }
1022527188a42b3250671b69dc979102565be1f910fTalin
1032d9eb72178af8e79dc6432cd1b7d29bde16da1b9Dmitri Gribenko  /// Check for string equality, ignoring case.
1042527188a42b3250671b69dc979102565be1f910fTalin  bool equals_lower(StringRef RHS) const {
1052527188a42b3250671b69dc979102565be1f910fTalin    return str().equals_lower(RHS);
1062527188a42b3250671b69dc979102565be1f910fTalin  }
1072527188a42b3250671b69dc979102565be1f910fTalin
1082d9eb72178af8e79dc6432cd1b7d29bde16da1b9Dmitri Gribenko  /// Compare two strings; the result is -1, 0, or 1 if this string is
1092d9eb72178af8e79dc6432cd1b7d29bde16da1b9Dmitri Gribenko  /// lexicographically less than, equal to, or greater than the \p RHS.
1102527188a42b3250671b69dc979102565be1f910fTalin  int compare(StringRef RHS) const {
1112527188a42b3250671b69dc979102565be1f910fTalin    return str().compare(RHS);
1122527188a42b3250671b69dc979102565be1f910fTalin  }
1132527188a42b3250671b69dc979102565be1f910fTalin
1142527188a42b3250671b69dc979102565be1f910fTalin  /// compare_lower - Compare two strings, ignoring case.
1152527188a42b3250671b69dc979102565be1f910fTalin  int compare_lower(StringRef RHS) const {
1162527188a42b3250671b69dc979102565be1f910fTalin    return str().compare_lower(RHS);
1172527188a42b3250671b69dc979102565be1f910fTalin  }
1182527188a42b3250671b69dc979102565be1f910fTalin
1192527188a42b3250671b69dc979102565be1f910fTalin  /// compare_numeric - Compare two strings, treating sequences of digits as
1202527188a42b3250671b69dc979102565be1f910fTalin  /// numbers.
1212527188a42b3250671b69dc979102565be1f910fTalin  int compare_numeric(StringRef RHS) const {
1222527188a42b3250671b69dc979102565be1f910fTalin    return str().compare_numeric(RHS);
1232527188a42b3250671b69dc979102565be1f910fTalin  }
1242527188a42b3250671b69dc979102565be1f910fTalin
1252527188a42b3250671b69dc979102565be1f910fTalin  /// @}
1262527188a42b3250671b69dc979102565be1f910fTalin  /// @name String Predicates
1272527188a42b3250671b69dc979102565be1f910fTalin  /// @{
1282527188a42b3250671b69dc979102565be1f910fTalin
1292d9eb72178af8e79dc6432cd1b7d29bde16da1b9Dmitri Gribenko  /// startswith - Check if this string starts with the given \p Prefix.
1302527188a42b3250671b69dc979102565be1f910fTalin  bool startswith(StringRef Prefix) const {
1312527188a42b3250671b69dc979102565be1f910fTalin    return str().startswith(Prefix);
1322527188a42b3250671b69dc979102565be1f910fTalin  }
1332527188a42b3250671b69dc979102565be1f910fTalin
1342d9eb72178af8e79dc6432cd1b7d29bde16da1b9Dmitri Gribenko  /// endswith - Check if this string ends with the given \p Suffix.
1352527188a42b3250671b69dc979102565be1f910fTalin  bool endswith(StringRef Suffix) const {
1362527188a42b3250671b69dc979102565be1f910fTalin    return str().endswith(Suffix);
1372527188a42b3250671b69dc979102565be1f910fTalin  }
1382527188a42b3250671b69dc979102565be1f910fTalin
1392527188a42b3250671b69dc979102565be1f910fTalin  /// @}
1402527188a42b3250671b69dc979102565be1f910fTalin  /// @name String Searching
1412527188a42b3250671b69dc979102565be1f910fTalin  /// @{
1422527188a42b3250671b69dc979102565be1f910fTalin
1432d9eb72178af8e79dc6432cd1b7d29bde16da1b9Dmitri Gribenko  /// find - Search for the first character \p C in the string.
1442527188a42b3250671b69dc979102565be1f910fTalin  ///
1452d9eb72178af8e79dc6432cd1b7d29bde16da1b9Dmitri Gribenko  /// \return - The index of the first occurrence of \p C, or npos if not
1462527188a42b3250671b69dc979102565be1f910fTalin  /// found.
1472527188a42b3250671b69dc979102565be1f910fTalin  size_t find(char C, size_t From = 0) const {
1482527188a42b3250671b69dc979102565be1f910fTalin    return str().find(C, From);
1492527188a42b3250671b69dc979102565be1f910fTalin  }
1502527188a42b3250671b69dc979102565be1f910fTalin
1512d9eb72178af8e79dc6432cd1b7d29bde16da1b9Dmitri Gribenko  /// Search for the first string \p Str in the string.
1522527188a42b3250671b69dc979102565be1f910fTalin  ///
1532d9eb72178af8e79dc6432cd1b7d29bde16da1b9Dmitri Gribenko  /// \returns The index of the first occurrence of \p Str, or npos if not
1542527188a42b3250671b69dc979102565be1f910fTalin  /// found.
1552527188a42b3250671b69dc979102565be1f910fTalin  size_t find(StringRef Str, size_t From = 0) const {
1562527188a42b3250671b69dc979102565be1f910fTalin    return str().find(Str, From);
1572527188a42b3250671b69dc979102565be1f910fTalin  }
1582527188a42b3250671b69dc979102565be1f910fTalin
1592d9eb72178af8e79dc6432cd1b7d29bde16da1b9Dmitri Gribenko  /// Search for the last character \p C in the string.
1602527188a42b3250671b69dc979102565be1f910fTalin  ///
1612d9eb72178af8e79dc6432cd1b7d29bde16da1b9Dmitri Gribenko  /// \returns The index of the last occurrence of \p C, or npos if not
1622527188a42b3250671b69dc979102565be1f910fTalin  /// found.
1632527188a42b3250671b69dc979102565be1f910fTalin  size_t rfind(char C, size_t From = StringRef::npos) const {
1642527188a42b3250671b69dc979102565be1f910fTalin    return str().rfind(C, From);
1652527188a42b3250671b69dc979102565be1f910fTalin  }
1662527188a42b3250671b69dc979102565be1f910fTalin
1672d9eb72178af8e79dc6432cd1b7d29bde16da1b9Dmitri Gribenko  /// Search for the last string \p Str in the string.
1682527188a42b3250671b69dc979102565be1f910fTalin  ///
1692d9eb72178af8e79dc6432cd1b7d29bde16da1b9Dmitri Gribenko  /// \returns The index of the last occurrence of \p Str, or npos if not
1702527188a42b3250671b69dc979102565be1f910fTalin  /// found.
1712527188a42b3250671b69dc979102565be1f910fTalin  size_t rfind(StringRef Str) const {
1722527188a42b3250671b69dc979102565be1f910fTalin    return str().rfind(Str);
1732527188a42b3250671b69dc979102565be1f910fTalin  }
1742527188a42b3250671b69dc979102565be1f910fTalin
1752d9eb72178af8e79dc6432cd1b7d29bde16da1b9Dmitri Gribenko  /// Find the first character in the string that is \p C, or npos if not
1762d9eb72178af8e79dc6432cd1b7d29bde16da1b9Dmitri Gribenko  /// found. Same as find.
1772527188a42b3250671b69dc979102565be1f910fTalin  size_t find_first_of(char C, size_t From = 0) const {
1782527188a42b3250671b69dc979102565be1f910fTalin    return str().find_first_of(C, From);
1792527188a42b3250671b69dc979102565be1f910fTalin  }
1802527188a42b3250671b69dc979102565be1f910fTalin
1812d9eb72178af8e79dc6432cd1b7d29bde16da1b9Dmitri Gribenko  /// Find the first character in the string that is in \p Chars, or npos if
1822d9eb72178af8e79dc6432cd1b7d29bde16da1b9Dmitri Gribenko  /// not found.
1832527188a42b3250671b69dc979102565be1f910fTalin  ///
1842d9eb72178af8e79dc6432cd1b7d29bde16da1b9Dmitri Gribenko  /// Complexity: O(size() + Chars.size())
1852527188a42b3250671b69dc979102565be1f910fTalin  size_t find_first_of(StringRef Chars, size_t From = 0) const {
1862527188a42b3250671b69dc979102565be1f910fTalin    return str().find_first_of(Chars, From);
1872527188a42b3250671b69dc979102565be1f910fTalin  }
1882527188a42b3250671b69dc979102565be1f910fTalin
1892d9eb72178af8e79dc6432cd1b7d29bde16da1b9Dmitri Gribenko  /// Find the first character in the string that is not \p C or npos if not
1902d9eb72178af8e79dc6432cd1b7d29bde16da1b9Dmitri Gribenko  /// found.
1912527188a42b3250671b69dc979102565be1f910fTalin  size_t find_first_not_of(char C, size_t From = 0) const {
1922527188a42b3250671b69dc979102565be1f910fTalin    return str().find_first_not_of(C, From);
1932527188a42b3250671b69dc979102565be1f910fTalin  }
1942527188a42b3250671b69dc979102565be1f910fTalin
1952d9eb72178af8e79dc6432cd1b7d29bde16da1b9Dmitri Gribenko  /// Find the first character in the string that is not in the string
1962d9eb72178af8e79dc6432cd1b7d29bde16da1b9Dmitri Gribenko  /// \p Chars, or npos if not found.
1972527188a42b3250671b69dc979102565be1f910fTalin  ///
1982d9eb72178af8e79dc6432cd1b7d29bde16da1b9Dmitri Gribenko  /// Complexity: O(size() + Chars.size())
1992527188a42b3250671b69dc979102565be1f910fTalin  size_t find_first_not_of(StringRef Chars, size_t From = 0) const {
2002527188a42b3250671b69dc979102565be1f910fTalin    return str().find_first_not_of(Chars, From);
2012527188a42b3250671b69dc979102565be1f910fTalin  }
2022527188a42b3250671b69dc979102565be1f910fTalin
2032d9eb72178af8e79dc6432cd1b7d29bde16da1b9Dmitri Gribenko  /// Find the last character in the string that is \p C, or npos if not
2042d9eb72178af8e79dc6432cd1b7d29bde16da1b9Dmitri Gribenko  /// found.
2052527188a42b3250671b69dc979102565be1f910fTalin  size_t find_last_of(char C, size_t From = StringRef::npos) const {
2062527188a42b3250671b69dc979102565be1f910fTalin    return str().find_last_of(C, From);
2072527188a42b3250671b69dc979102565be1f910fTalin  }
2082527188a42b3250671b69dc979102565be1f910fTalin
2092d9eb72178af8e79dc6432cd1b7d29bde16da1b9Dmitri Gribenko  /// Find the last character in the string that is in \p C, or npos if not
2102d9eb72178af8e79dc6432cd1b7d29bde16da1b9Dmitri Gribenko  /// found.
2112527188a42b3250671b69dc979102565be1f910fTalin  ///
2122d9eb72178af8e79dc6432cd1b7d29bde16da1b9Dmitri Gribenko  /// Complexity: O(size() + Chars.size())
2132527188a42b3250671b69dc979102565be1f910fTalin  size_t find_last_of(
2142527188a42b3250671b69dc979102565be1f910fTalin      StringRef Chars, size_t From = StringRef::npos) const {
2152527188a42b3250671b69dc979102565be1f910fTalin    return str().find_last_of(Chars, From);
2162527188a42b3250671b69dc979102565be1f910fTalin  }
2172527188a42b3250671b69dc979102565be1f910fTalin
2182527188a42b3250671b69dc979102565be1f910fTalin  /// @}
2192527188a42b3250671b69dc979102565be1f910fTalin  /// @name Helpful Algorithms
2202527188a42b3250671b69dc979102565be1f910fTalin  /// @{
2212527188a42b3250671b69dc979102565be1f910fTalin
2222d9eb72178af8e79dc6432cd1b7d29bde16da1b9Dmitri Gribenko  /// Return the number of occurrences of \p C in the string.
2232527188a42b3250671b69dc979102565be1f910fTalin  size_t count(char C) const {
2242527188a42b3250671b69dc979102565be1f910fTalin    return str().count(C);
2252527188a42b3250671b69dc979102565be1f910fTalin  }
2262527188a42b3250671b69dc979102565be1f910fTalin
2272d9eb72178af8e79dc6432cd1b7d29bde16da1b9Dmitri Gribenko  /// Return the number of non-overlapped occurrences of \p Str in the
2282d9eb72178af8e79dc6432cd1b7d29bde16da1b9Dmitri Gribenko  /// string.
2292527188a42b3250671b69dc979102565be1f910fTalin  size_t count(StringRef Str) const {
2302527188a42b3250671b69dc979102565be1f910fTalin    return str().count(Str);
2312527188a42b3250671b69dc979102565be1f910fTalin  }
2322527188a42b3250671b69dc979102565be1f910fTalin
2332527188a42b3250671b69dc979102565be1f910fTalin  /// @}
2342527188a42b3250671b69dc979102565be1f910fTalin  /// @name Substring Operations
2352527188a42b3250671b69dc979102565be1f910fTalin  /// @{
2362527188a42b3250671b69dc979102565be1f910fTalin
2372d9eb72178af8e79dc6432cd1b7d29bde16da1b9Dmitri Gribenko  /// Return a reference to the substring from [Start, Start + N).
2382527188a42b3250671b69dc979102565be1f910fTalin  ///
2392d9eb72178af8e79dc6432cd1b7d29bde16da1b9Dmitri Gribenko  /// \param Start The index of the starting character in the substring; if
2402527188a42b3250671b69dc979102565be1f910fTalin  /// the index is npos or greater than the length of the string then the
2412527188a42b3250671b69dc979102565be1f910fTalin  /// empty substring will be returned.
2422527188a42b3250671b69dc979102565be1f910fTalin  ///
2432d9eb72178af8e79dc6432cd1b7d29bde16da1b9Dmitri Gribenko  /// \param N The number of characters to included in the substring. If \p N
2442527188a42b3250671b69dc979102565be1f910fTalin  /// exceeds the number of characters remaining in the string, the string
2452d9eb72178af8e79dc6432cd1b7d29bde16da1b9Dmitri Gribenko  /// suffix (starting with \p Start) will be returned.
2462527188a42b3250671b69dc979102565be1f910fTalin  StringRef substr(size_t Start, size_t N = StringRef::npos) const {
2472527188a42b3250671b69dc979102565be1f910fTalin    return str().substr(Start, N);
2482527188a42b3250671b69dc979102565be1f910fTalin  }
2492527188a42b3250671b69dc979102565be1f910fTalin
2502d9eb72178af8e79dc6432cd1b7d29bde16da1b9Dmitri Gribenko  /// Return a reference to the substring from [Start, End).
2512527188a42b3250671b69dc979102565be1f910fTalin  ///
2522d9eb72178af8e79dc6432cd1b7d29bde16da1b9Dmitri Gribenko  /// \param Start The index of the starting character in the substring; if
2532527188a42b3250671b69dc979102565be1f910fTalin  /// the index is npos or greater than the length of the string then the
2542527188a42b3250671b69dc979102565be1f910fTalin  /// empty substring will be returned.
2552527188a42b3250671b69dc979102565be1f910fTalin  ///
2562d9eb72178af8e79dc6432cd1b7d29bde16da1b9Dmitri Gribenko  /// \param End The index following the last character to include in the
2572d9eb72178af8e79dc6432cd1b7d29bde16da1b9Dmitri Gribenko  /// substring. If this is npos, or less than \p Start, or exceeds the
2582527188a42b3250671b69dc979102565be1f910fTalin  /// number of characters remaining in the string, the string suffix
2592d9eb72178af8e79dc6432cd1b7d29bde16da1b9Dmitri Gribenko  /// (starting with \p Start) will be returned.
2602527188a42b3250671b69dc979102565be1f910fTalin  StringRef slice(size_t Start, size_t End) const {
2612527188a42b3250671b69dc979102565be1f910fTalin    return str().slice(Start, End);
2622527188a42b3250671b69dc979102565be1f910fTalin  }
2633a54b3dc87a581c203b18050b4f787b4ca28a12cMisha Brukman
264dd94c8d6b2afb9c33c364ac8f0c8f8ed5d4c04a0Chris Lattner  // Extra methods.
2652527188a42b3250671b69dc979102565be1f910fTalin
2662d9eb72178af8e79dc6432cd1b7d29bde16da1b9Dmitri Gribenko  /// Explicit conversion to StringRef.
26704087d069a17265b964b30e8210262bbdbc4fbecDaniel Dunbar  StringRef str() const { return StringRef(this->begin(), this->size()); }
26804087d069a17265b964b30e8210262bbdbc4fbecDaniel Dunbar
26958fe86dc0ecb7efff01abe2b0024a6a53ebb2c81Michael J. Spencer  // TODO: Make this const, if it's safe...
27058fe86dc0ecb7efff01abe2b0024a6a53ebb2c81Michael J. Spencer  const char* c_str() {
27158fe86dc0ecb7efff01abe2b0024a6a53ebb2c81Michael J. Spencer    this->push_back(0);
27258fe86dc0ecb7efff01abe2b0024a6a53ebb2c81Michael J. Spencer    this->pop_back();
27358fe86dc0ecb7efff01abe2b0024a6a53ebb2c81Michael J. Spencer    return this->data();
27458fe86dc0ecb7efff01abe2b0024a6a53ebb2c81Michael J. Spencer  }
27558fe86dc0ecb7efff01abe2b0024a6a53ebb2c81Michael J. Spencer
2762527188a42b3250671b69dc979102565be1f910fTalin  /// Implicit conversion to StringRef.
277983c7fe847dd3f46945f0117ab19345b9c68e88fDaniel Dunbar  operator StringRef() const { return str(); }
278983c7fe847dd3f46945f0117ab19345b9c68e88fDaniel Dunbar
279dd94c8d6b2afb9c33c364ac8f0c8f8ed5d4c04a0Chris Lattner  // Extra operators.
28039db3439bfcdca4073dd513879f8ce12ee8c593bDaniel Dunbar  const SmallString &operator=(StringRef RHS) {
2810fbdfc3664830e8387c13bf817c44e8b71085142Chris Lattner    this->clear();
2820fbdfc3664830e8387c13bf817c44e8b71085142Chris Lattner    return *this += RHS;
2830fbdfc3664830e8387c13bf817c44e8b71085142Chris Lattner  }
2843a54b3dc87a581c203b18050b4f787b4ca28a12cMisha Brukman
28539db3439bfcdca4073dd513879f8ce12ee8c593bDaniel Dunbar  SmallString &operator+=(StringRef RHS) {
28639db3439bfcdca4073dd513879f8ce12ee8c593bDaniel Dunbar    this->append(RHS.begin(), RHS.end());
287dd94c8d6b2afb9c33c364ac8f0c8f8ed5d4c04a0Chris Lattner    return *this;
288dd94c8d6b2afb9c33c364ac8f0c8f8ed5d4c04a0Chris Lattner  }
289703f5291c4f7199a95274df5e3381b36f8faf38cChris Lattner  SmallString &operator+=(char C) {
290703f5291c4f7199a95274df5e3381b36f8faf38cChris Lattner    this->push_back(C);
291703f5291c4f7199a95274df5e3381b36f8faf38cChris Lattner    return *this;
292703f5291c4f7199a95274df5e3381b36f8faf38cChris Lattner  }
293dd94c8d6b2afb9c33c364ac8f0c8f8ed5d4c04a0Chris Lattner};
2943a54b3dc87a581c203b18050b4f787b4ca28a12cMisha Brukman
295dd94c8d6b2afb9c33c364ac8f0c8f8ed5d4c04a0Chris Lattner}
296dd94c8d6b2afb9c33c364ac8f0c8f8ed5d4c04a0Chris Lattner
297dd94c8d6b2afb9c33c364ac8f0c8f8ed5d4c04a0Chris Lattner#endif
298