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 | #include <cstddef> |
20 | |
21 | namespace llvm { |
22 | |
23 | /// SmallString - A SmallString is just a SmallVector with methods and accessors |
24 | /// that make it work better as a string (e.g. operator+ etc). |
25 | template<unsigned InternalLen> |
26 | class SmallString : public SmallVector<char, InternalLen> { |
27 | public: |
28 | /// Default ctor - Initialize to empty. |
29 | SmallString() = default; |
30 | |
31 | /// Initialize from a StringRef. |
32 | SmallString(StringRef S) : SmallVector<char, InternalLen>(S.begin(), S.end()) {} |
33 | |
34 | /// Initialize with a range. |
35 | template<typename ItTy> |
36 | SmallString(ItTy S, ItTy E) : SmallVector<char, InternalLen>(S, E) {} |
37 | |
38 | // Note that in order to add new overloads for append & assign, we have to |
39 | // duplicate the inherited versions so as not to inadvertently hide them. |
40 | |
41 | /// @} |
42 | /// @name String Assignment |
43 | /// @{ |
44 | |
45 | /// Assign from a repeated element. |
46 | void assign(size_t NumElts, char Elt) { |
47 | this->SmallVectorImpl<char>::assign(NumElts, Elt); |
48 | } |
49 | |
50 | /// Assign from an iterator pair. |
51 | template<typename in_iter> |
52 | void assign(in_iter S, in_iter E) { |
53 | this->clear(); |
54 | SmallVectorImpl<char>::append(S, E); |
55 | } |
56 | |
57 | /// Assign from a StringRef. |
58 | void assign(StringRef RHS) { |
59 | this->clear(); |
60 | SmallVectorImpl<char>::append(RHS.begin(), RHS.end()); |
61 | } |
62 | |
63 | /// Assign from a SmallVector. |
64 | void assign(const SmallVectorImpl<char> &RHS) { |
65 | this->clear(); |
66 | SmallVectorImpl<char>::append(RHS.begin(), RHS.end()); |
67 | } |
68 | |
69 | /// @} |
70 | /// @name String Concatenation |
71 | /// @{ |
72 | |
73 | /// Append from an iterator pair. |
74 | template<typename in_iter> |
75 | void append(in_iter S, in_iter E) { |
76 | SmallVectorImpl<char>::append(S, E); |
77 | } |
78 | |
79 | void append(size_t NumInputs, char Elt) { |
80 | SmallVectorImpl<char>::append(NumInputs, Elt); |
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 | } // end namespace llvm |
296 | |
297 | #endif // LLVM_ADT_SMALLSTRING_H |
298 | |