]>
Commit | Line | Data |
---|---|---|
223e47cc LB |
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 | 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 | ||
223e47cc LB |
37 | // Note that in order to add new overloads for append & assign, we have to |
38 | // duplicate the inherited versions so as not to inadvertently hide them. | |
39 | ||
40 | /// @} | |
41 | /// @name String Assignment | |
42 | /// @{ | |
43 | ||
44 | /// Assign from a repeated element. | |
45 | void assign(size_t NumElts, char Elt) { | |
46 | this->SmallVectorImpl<char>::assign(NumElts, Elt); | |
47 | } | |
48 | ||
49 | /// Assign from an iterator pair. | |
50 | template<typename in_iter> | |
51 | void assign(in_iter S, in_iter E) { | |
52 | this->clear(); | |
53 | SmallVectorImpl<char>::append(S, E); | |
54 | } | |
55 | ||
56 | /// Assign from a StringRef. | |
57 | void assign(StringRef RHS) { | |
58 | this->clear(); | |
59 | SmallVectorImpl<char>::append(RHS.begin(), RHS.end()); | |
60 | } | |
61 | ||
62 | /// Assign from a SmallVector. | |
63 | void assign(const SmallVectorImpl<char> &RHS) { | |
64 | this->clear(); | |
65 | SmallVectorImpl<char>::append(RHS.begin(), RHS.end()); | |
66 | } | |
67 | ||
68 | /// @} | |
69 | /// @name String Concatenation | |
70 | /// @{ | |
71 | ||
72 | /// Append from an iterator pair. | |
73 | template<typename in_iter> | |
74 | void append(in_iter S, in_iter E) { | |
75 | SmallVectorImpl<char>::append(S, E); | |
76 | } | |
970d7e83 | 77 | |
223e47cc LB |
78 | void append(size_t NumInputs, char Elt) { |
79 | SmallVectorImpl<char>::append(NumInputs, Elt); | |
80 | } | |
81 | ||
82 | ||
83 | /// Append from a StringRef. | |
84 | void append(StringRef RHS) { | |
85 | SmallVectorImpl<char>::append(RHS.begin(), RHS.end()); | |
86 | } | |
87 | ||
88 | /// Append from a SmallVector. | |
89 | void append(const SmallVectorImpl<char> &RHS) { | |
90 | SmallVectorImpl<char>::append(RHS.begin(), RHS.end()); | |
91 | } | |
92 | ||
93 | /// @} | |
94 | /// @name String Comparison | |
95 | /// @{ | |
96 | ||
97 | /// Check for string equality. This is more efficient than compare() when | |
98 | /// the relative ordering of inequal strings isn't needed. | |
99 | bool equals(StringRef RHS) const { | |
100 | return str().equals(RHS); | |
101 | } | |
102 | ||
103 | /// Check for string equality, ignoring case. | |
104 | bool equals_lower(StringRef RHS) const { | |
105 | return str().equals_lower(RHS); | |
106 | } | |
107 | ||
108 | /// Compare two strings; the result is -1, 0, or 1 if this string is | |
109 | /// lexicographically less than, equal to, or greater than the \p RHS. | |
110 | int compare(StringRef RHS) const { | |
111 | return str().compare(RHS); | |
112 | } | |
113 | ||
114 | /// compare_lower - Compare two strings, ignoring case. | |
115 | int compare_lower(StringRef RHS) const { | |
116 | return str().compare_lower(RHS); | |
117 | } | |
118 | ||
119 | /// compare_numeric - Compare two strings, treating sequences of digits as | |
120 | /// numbers. | |
121 | int compare_numeric(StringRef RHS) const { | |
122 | return str().compare_numeric(RHS); | |
123 | } | |
124 | ||
125 | /// @} | |
126 | /// @name String Predicates | |
127 | /// @{ | |
128 | ||
129 | /// startswith - Check if this string starts with the given \p Prefix. | |
130 | bool startswith(StringRef Prefix) const { | |
131 | return str().startswith(Prefix); | |
132 | } | |
133 | ||
134 | /// endswith - Check if this string ends with the given \p Suffix. | |
135 | bool endswith(StringRef Suffix) const { | |
136 | return str().endswith(Suffix); | |
137 | } | |
138 | ||
139 | /// @} | |
140 | /// @name String Searching | |
141 | /// @{ | |
142 | ||
143 | /// find - Search for the first character \p C in the string. | |
144 | /// | |
145 | /// \return - The index of the first occurrence of \p C, or npos if not | |
146 | /// found. | |
147 | size_t find(char C, size_t From = 0) const { | |
148 | return str().find(C, From); | |
149 | } | |
150 | ||
151 | /// Search for the first string \p Str in the string. | |
152 | /// | |
153 | /// \returns The index of the first occurrence of \p Str, or npos if not | |
154 | /// found. | |
155 | size_t find(StringRef Str, size_t From = 0) const { | |
156 | return str().find(Str, From); | |
157 | } | |
158 | ||
159 | /// Search for the last character \p C in the string. | |
160 | /// | |
161 | /// \returns The index of the last occurrence of \p C, or npos if not | |
162 | /// found. | |
163 | size_t rfind(char C, size_t From = StringRef::npos) const { | |
164 | return str().rfind(C, From); | |
165 | } | |
166 | ||
167 | /// Search for the last string \p Str in the string. | |
168 | /// | |
169 | /// \returns The index of the last occurrence of \p Str, or npos if not | |
170 | /// found. | |
171 | size_t rfind(StringRef Str) const { | |
172 | return str().rfind(Str); | |
173 | } | |
174 | ||
175 | /// Find the first character in the string that is \p C, or npos if not | |
176 | /// found. Same as find. | |
177 | size_t find_first_of(char C, size_t From = 0) const { | |
178 | return str().find_first_of(C, From); | |
179 | } | |
180 | ||
181 | /// Find the first character in the string that is in \p Chars, or npos if | |
182 | /// not found. | |
183 | /// | |
184 | /// Complexity: O(size() + Chars.size()) | |
185 | size_t find_first_of(StringRef Chars, size_t From = 0) const { | |
186 | return str().find_first_of(Chars, From); | |
187 | } | |
188 | ||
189 | /// Find the first character in the string that is not \p C or npos if not | |
190 | /// found. | |
191 | size_t find_first_not_of(char C, size_t From = 0) const { | |
192 | return str().find_first_not_of(C, From); | |
193 | } | |
194 | ||
195 | /// Find the first character in the string that is not in the string | |
196 | /// \p Chars, or npos if not found. | |
197 | /// | |
198 | /// Complexity: O(size() + Chars.size()) | |
199 | size_t find_first_not_of(StringRef Chars, size_t From = 0) const { | |
200 | return str().find_first_not_of(Chars, From); | |
201 | } | |
202 | ||
203 | /// Find the last character in the string that is \p C, or npos if not | |
204 | /// found. | |
205 | size_t find_last_of(char C, size_t From = StringRef::npos) const { | |
206 | return str().find_last_of(C, From); | |
207 | } | |
208 | ||
209 | /// Find the last character in the string that is in \p C, or npos if not | |
210 | /// found. | |
211 | /// | |
212 | /// Complexity: O(size() + Chars.size()) | |
213 | size_t find_last_of( | |
214 | StringRef Chars, size_t From = StringRef::npos) const { | |
215 | return str().find_last_of(Chars, From); | |
216 | } | |
217 | ||
218 | /// @} | |
219 | /// @name Helpful Algorithms | |
220 | /// @{ | |
221 | ||
222 | /// Return the number of occurrences of \p C in the string. | |
223 | size_t count(char C) const { | |
224 | return str().count(C); | |
225 | } | |
226 | ||
227 | /// Return the number of non-overlapped occurrences of \p Str in the | |
228 | /// string. | |
229 | size_t count(StringRef Str) const { | |
230 | return str().count(Str); | |
231 | } | |
232 | ||
233 | /// @} | |
234 | /// @name Substring Operations | |
235 | /// @{ | |
236 | ||
237 | /// Return a reference to the substring from [Start, Start + N). | |
238 | /// | |
239 | /// \param Start The index of the starting character in the substring; if | |
240 | /// the index is npos or greater than the length of the string then the | |
241 | /// empty substring will be returned. | |
242 | /// | |
243 | /// \param N The number of characters to included in the substring. If \p N | |
244 | /// exceeds the number of characters remaining in the string, the string | |
245 | /// suffix (starting with \p Start) will be returned. | |
246 | StringRef substr(size_t Start, size_t N = StringRef::npos) const { | |
247 | return str().substr(Start, N); | |
248 | } | |
249 | ||
250 | /// Return a reference to the substring from [Start, End). | |
251 | /// | |
252 | /// \param Start The index of the starting character in the substring; if | |
253 | /// the index is npos or greater than the length of the string then the | |
254 | /// empty substring will be returned. | |
255 | /// | |
256 | /// \param End The index following the last character to include in the | |
257 | /// substring. If this is npos, or less than \p Start, or exceeds the | |
258 | /// number of characters remaining in the string, the string suffix | |
259 | /// (starting with \p Start) will be returned. | |
260 | StringRef slice(size_t Start, size_t End) const { | |
261 | return str().slice(Start, End); | |
262 | } | |
263 | ||
264 | // Extra methods. | |
265 | ||
266 | /// Explicit conversion to StringRef. | |
267 | StringRef str() const { return StringRef(this->begin(), this->size()); } | |
268 | ||
269 | // TODO: Make this const, if it's safe... | |
270 | const char* c_str() { | |
271 | this->push_back(0); | |
272 | this->pop_back(); | |
273 | return this->data(); | |
274 | } | |
275 | ||
276 | /// Implicit conversion to StringRef. | |
277 | operator StringRef() const { return str(); } | |
278 | ||
279 | // Extra operators. | |
280 | const SmallString &operator=(StringRef RHS) { | |
281 | this->clear(); | |
282 | return *this += RHS; | |
283 | } | |
284 | ||
285 | SmallString &operator+=(StringRef RHS) { | |
286 | this->append(RHS.begin(), RHS.end()); | |
287 | return *this; | |
288 | } | |
289 | SmallString &operator+=(char C) { | |
290 | this->push_back(C); | |
291 | return *this; | |
292 | } | |
293 | }; | |
294 | ||
295 | } | |
296 | ||
297 | #endif |