Clean up SmallString a bit
[oota-llvm.git] / include / llvm / ADT / SmallString.h
1 //===- llvm/ADT/SmallString.h - 'Normally small' strings --------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file defines the SmallString class.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #ifndef LLVM_ADT_SMALLSTRING_H
15 #define LLVM_ADT_SMALLSTRING_H
16
17 #include "llvm/ADT/SmallVector.h"
18 #include "llvm/ADT/StringRef.h"
19
20 namespace llvm {
21
22 /// SmallString - A SmallString is just a SmallVector with methods and accessors
23 /// that make it work better as a string (e.g. operator+ etc).
24 template<unsigned InternalLen>
25 class SmallString : public SmallVector<char, InternalLen> {
26 public:
27   /// Default ctor - Initialize to empty.
28   SmallString() {}
29
30   /// Initialize from a StringRef.
31   /*implicit*/ SmallString(StringRef S) : SmallVector<char, InternalLen>(S.begin(), S.end()) {}
32
33   /// Initialize with a range.
34   template<typename ItTy>
35   SmallString(ItTy S, ItTy E) : SmallVector<char, InternalLen>(S, E) {}
36
37   /// @}
38   /// @name String Assignment
39   /// @{
40
41   // Provide assign from SmallVectorImpl<char>
42   using SmallVectorImpl<char>::assign;
43
44   /// Assign from a StringRef.
45   void assign(StringRef RHS) {
46     this->clear();
47     SmallVectorImpl<char>::append(RHS.begin(), RHS.end());
48   }
49
50   /// Assign from a SmallVector.
51   void assign(const SmallVectorImpl<char> &RHS) {
52     this->clear();
53     SmallVectorImpl<char>::append(RHS.begin(), RHS.end());
54   }
55
56   using SmallVectorImpl<char>::append;
57
58   /// Append from a StringRef.
59   void append(StringRef RHS) {
60     SmallVectorImpl<char>::append(RHS.begin(), RHS.end());
61   }
62
63   /// Append from a SmallVector.
64   void append(const SmallVectorImpl<char> &RHS) {
65     SmallVectorImpl<char>::append(RHS.begin(), RHS.end());
66   }
67
68   /// @}
69   /// @name String Comparison
70   /// @{
71
72   /// Check for string equality, ignoring case.
73   bool equals_lower(StringRef RHS) const {
74     return str().equals_lower(RHS);
75   }
76
77   /// Compare two strings; the result is -1, 0, or 1 if this string is
78   /// lexicographically less than, equal to, or greater than the \p RHS.
79   int compare(StringRef RHS) const {
80     return str().compare(RHS);
81   }
82
83   /// compare_lower - Compare two strings, ignoring case.
84   int compare_lower(StringRef RHS) const {
85     return str().compare_lower(RHS);
86   }
87
88   /// compare_numeric - Compare two strings, treating sequences of digits as
89   /// numbers.
90   int compare_numeric(StringRef RHS) const {
91     return str().compare_numeric(RHS);
92   }
93
94   /// @}
95   /// @name String Predicates
96   /// @{
97
98   /// startswith - Check if this string starts with the given \p Prefix.
99   bool startswith(StringRef Prefix) const {
100     return str().startswith(Prefix);
101   }
102
103   /// endswith - Check if this string ends with the given \p Suffix.
104   bool endswith(StringRef Suffix) const {
105     return str().endswith(Suffix);
106   }
107
108   /// @}
109   /// @name String Searching
110   /// @{
111
112   /// find - Search for the first character \p C in the string.
113   ///
114   /// \return - The index of the first occurrence of \p C, or npos if not
115   /// found.
116   size_t find(char C, size_t From = 0) const {
117     return str().find(C, From);
118   }
119
120   /// Search for the first string \p Str in the string.
121   ///
122   /// \returns The index of the first occurrence of \p Str, or npos if not
123   /// found.
124   size_t find(StringRef Str, size_t From = 0) const {
125     return str().find(Str, From);
126   }
127
128   /// Search for the last character \p C in the string.
129   ///
130   /// \returns The index of the last occurrence of \p C, or npos if not
131   /// found.
132   size_t rfind(char C, size_t From = StringRef::npos) const {
133     return str().rfind(C, From);
134   }
135
136   /// Search for the last string \p Str in the string.
137   ///
138   /// \returns The index of the last occurrence of \p Str, or npos if not
139   /// found.
140   size_t rfind(StringRef Str) const {
141     return str().rfind(Str);
142   }
143
144   /// Find the first character in the string that is \p C, or npos if not
145   /// found. Same as find.
146   size_t find_first_of(char C, size_t From = 0) const {
147     return str().find_first_of(C, From);
148   }
149
150   /// Find the first character in the string that is in \p Chars, or npos if
151   /// not found.
152   ///
153   /// Complexity: O(size() + Chars.size())
154   size_t find_first_of(StringRef Chars, size_t From = 0) const {
155     return str().find_first_of(Chars, From);
156   }
157
158   /// Find the first character in the string that is not \p C or npos if not
159   /// found.
160   size_t find_first_not_of(char C, size_t From = 0) const {
161     return str().find_first_not_of(C, From);
162   }
163
164   /// Find the first character in the string that is not in the string
165   /// \p Chars, or npos if not found.
166   ///
167   /// Complexity: O(size() + Chars.size())
168   size_t find_first_not_of(StringRef Chars, size_t From = 0) const {
169     return str().find_first_not_of(Chars, From);
170   }
171
172   /// Find the last character in the string that is \p C, or npos if not
173   /// found.
174   size_t find_last_of(char C, size_t From = StringRef::npos) const {
175     return str().find_last_of(C, From);
176   }
177
178   /// Find the last character in the string that is in \p C, or npos if not
179   /// found.
180   ///
181   /// Complexity: O(size() + Chars.size())
182   size_t find_last_of(
183       StringRef Chars, size_t From = StringRef::npos) const {
184     return str().find_last_of(Chars, From);
185   }
186
187   /// @}
188   /// @name Helpful Algorithms
189   /// @{
190
191   /// Return the number of occurrences of \p C in the string.
192   size_t count(char C) const {
193     return str().count(C);
194   }
195
196   /// Return the number of non-overlapped occurrences of \p Str in the
197   /// string.
198   size_t count(StringRef Str) const {
199     return str().count(Str);
200   }
201
202   /// @}
203   /// @name Substring Operations
204   /// @{
205
206   /// Return a reference to the substring from [Start, Start + N).
207   ///
208   /// \param Start The index of the starting character in the substring; if
209   /// the index is npos or greater than the length of the string then the
210   /// empty substring will be returned.
211   ///
212   /// \param N The number of characters to included in the substring. If \p N
213   /// exceeds the number of characters remaining in the string, the string
214   /// suffix (starting with \p Start) will be returned.
215   StringRef substr(size_t Start, size_t N = StringRef::npos) const {
216     return str().substr(Start, N);
217   }
218
219   /// Return a reference to the substring from [Start, End).
220   ///
221   /// \param Start The index of the starting character in the substring; if
222   /// the index is npos or greater than the length of the string then the
223   /// empty substring will be returned.
224   ///
225   /// \param End The index following the last character to include in the
226   /// substring. If this is npos, or less than \p Start, or exceeds the
227   /// number of characters remaining in the string, the string suffix
228   /// (starting with \p Start) will be returned.
229   StringRef slice(size_t Start, size_t End) const {
230     return str().slice(Start, End);
231   }
232
233   // Extra methods.
234
235   /// Explicit conversion to StringRef.
236   StringRef str() const { return StringRef(this->begin(), this->size()); }
237
238   // TODO: Make this const, if it's safe...
239   const char* c_str() {
240     this->push_back(0);
241     this->pop_back();
242     return this->data();
243   }
244
245   /// Implicit conversion to StringRef.
246   operator StringRef() const { return str(); }
247
248   // Provide op= for SmallVectorImpl<char>
249   using SmallVectorImpl<char>::operator=;
250
251   // Extra operators.
252   const SmallString &operator=(StringRef RHS) {
253     this->clear();
254     return *this += RHS;
255   }
256
257   SmallString &operator+=(StringRef RHS) {
258     append(RHS.begin(), RHS.end());
259     return *this;
260   }
261
262   SmallString &operator+=(const SmallVectorImpl<char> &RHS) {
263     append(RHS.begin(), RHS.end());
264     return *this;
265   }
266
267   SmallString &operator+=(char C) {
268     this->push_back(C);
269     return *this;
270   }
271 };
272
273 }
274
275 #endif