|
11 | 11 | #include <vector>
|
12 | 12 |
|
13 | 13 | #include "llvm/ADT/ArrayRef.h"
|
| 14 | +#include "llvm/ADT/StringRef.h" |
14 | 15 |
|
15 | 16 | namespace glow {
|
16 | 17 | /// \brief A range adaptor for a pair of iterators.
|
@@ -138,332 +139,7 @@ inline bool operator!=(MutableArrayRef<T> LHS, MutableArrayRef<T> RHS) {
|
138 | 139 | return !(LHS == RHS);
|
139 | 140 | }
|
140 | 141 |
|
141 |
| -/// StringRef - Represent a constant reference to a string, i.e. a character |
142 |
| -/// array and a length, which need not be null terminated. |
143 |
| -/// |
144 |
| -/// This class does not own the string data, it is expected to be used in |
145 |
| -/// situations where the character data resides in some other buffer, whose |
146 |
| -/// lifetime extends past that of the StringRef. For this reason, it is not in |
147 |
| -/// general safe to store a StringRef. |
148 |
| -class StringRef { |
149 |
| -public: |
150 |
| - static const size_t npos = ~size_t(0); |
151 |
| - |
152 |
| - using iterator = const char *; |
153 |
| - using const_iterator = const char *; |
154 |
| - using size_type = size_t; |
155 |
| - |
156 |
| -private: |
157 |
| - /// The start of the string, in an external buffer. |
158 |
| - const char *Data = nullptr; |
159 |
| - |
160 |
| - /// The length of the string. |
161 |
| - size_t Length = 0; |
162 |
| - |
163 |
| - // Workaround memcmp issue with null pointers (undefined behavior) |
164 |
| - // by providing a specialized version |
165 |
| - static int compareMemory(const char *Lhs, const char *Rhs, size_t Length) { |
166 |
| - if (Length == 0) { |
167 |
| - return 0; |
168 |
| - } |
169 |
| - return ::memcmp(Lhs, Rhs, Length); |
170 |
| - } |
171 |
| - |
172 |
| -public: |
173 |
| - /// Construct an empty string ref. |
174 |
| - StringRef() = default; |
175 |
| - |
176 |
| - /// Disable conversion from nullptr. This prevents things like |
177 |
| - /// if (S == nullptr) |
178 |
| - StringRef(std::nullptr_t) = delete; |
179 |
| - |
180 |
| - /// Construct a string ref from a cstring. |
181 |
| - StringRef(const char *Str) : Data(Str), Length(Str ? ::strlen(Str) : 0) {} |
182 |
| - |
183 |
| - /// Construct a string ref from a pointer and length. |
184 |
| - constexpr StringRef(const char *data, size_t length) |
185 |
| - : Data(data), Length(length) {} |
186 |
| - |
187 |
| - /// Construct a string ref from an std::string. |
188 |
| - StringRef(const std::string &Str) : Data(Str.data()), Length(Str.length()) {} |
189 |
| - |
190 |
| - static StringRef withNullAsEmpty(const char *data) { |
191 |
| - return StringRef(data ? data : ""); |
192 |
| - } |
193 |
| - |
194 |
| - iterator begin() const { return Data; } |
195 |
| - iterator end() const { return Data + Length; } |
196 |
| - |
197 |
| - const unsigned char *bytes_begin() const { |
198 |
| - return reinterpret_cast<const unsigned char *>(begin()); |
199 |
| - } |
200 |
| - const unsigned char *bytes_end() const { |
201 |
| - return reinterpret_cast<const unsigned char *>(end()); |
202 |
| - } |
203 |
| - iterator_range<const unsigned char *> bytes() const { |
204 |
| - return make_range(bytes_begin(), bytes_end()); |
205 |
| - } |
206 |
| - |
207 |
| - /// data - Get a pointer to the start of the string (which may not be null |
208 |
| - /// terminated). |
209 |
| - const char *data() const { return Data; } |
210 |
| - |
211 |
| - /// empty - Check if the string is empty. |
212 |
| - bool empty() const { return Length == 0; } |
213 |
| - |
214 |
| - /// size - Get the string size. |
215 |
| - size_t size() const { return Length; } |
216 |
| - |
217 |
| - /// front - Get the first character in the string. |
218 |
| - char front() const { |
219 |
| - assert(!empty()); |
220 |
| - return Data[0]; |
221 |
| - } |
222 |
| - |
223 |
| - /// back - Get the last character in the string. |
224 |
| - char back() const { |
225 |
| - assert(!empty()); |
226 |
| - return Data[Length - 1]; |
227 |
| - } |
228 |
| - |
229 |
| - // copy - Allocate copy in Allocator and return StringRef to it. |
230 |
| - template <typename Allocator> StringRef copy(Allocator &A) const { |
231 |
| - // Don't request a length 0 copy from the allocator. |
232 |
| - if (empty()) |
233 |
| - return StringRef(); |
234 |
| - char *S = A.template Allocate<char>(Length); |
235 |
| - std::copy(begin(), end(), S); |
236 |
| - return StringRef(S, Length); |
237 |
| - } |
238 |
| - |
239 |
| - /// equals - Check for string equality, this is more efficient than |
240 |
| - /// compare() when the relative ordering of inequal strings isn't needed. |
241 |
| - bool equals(StringRef RHS) const { |
242 |
| - return (Length == RHS.Length && |
243 |
| - compareMemory(Data, RHS.Data, RHS.Length) == 0); |
244 |
| - } |
245 |
| - |
246 |
| - /// compare - Compare two strings; the result is -1, 0, or 1 if this string |
247 |
| - /// is lexicographically less than, equal to, or greater than the \p RHS. |
248 |
| - int compare(StringRef RHS) const { |
249 |
| - // Check the prefix for a mismatch. |
250 |
| - if (int Res = compareMemory(Data, RHS.Data, std::min(Length, RHS.Length))) |
251 |
| - return Res < 0 ? -1 : 1; |
252 |
| - |
253 |
| - // Otherwise the prefixes match, so we only need to check the lengths. |
254 |
| - if (Length == RHS.Length) |
255 |
| - return 0; |
256 |
| - return Length < RHS.Length ? -1 : 1; |
257 |
| - } |
258 |
| - |
259 |
| - /// str - Get the contents as an std::string. |
260 |
| - std::string str() const { |
261 |
| - if (!Data) |
262 |
| - return std::string(); |
263 |
| - return std::string(Data, Length); |
264 |
| - } |
265 |
| - |
266 |
| - char operator[](size_t Index) const { |
267 |
| - assert(Index < Length && "Invalid index!"); |
268 |
| - return Data[Index]; |
269 |
| - } |
270 |
| - |
271 |
| - /// Disallow accidental assignment from a temporary std::string. |
272 |
| - /// |
273 |
| - /// The declaration here is extra complicated so that `stringRef = {}` |
274 |
| - /// and `stringRef = "abc"` continue to select the move assignment operator. |
275 |
| - template <typename T> |
276 |
| - typename std::enable_if<std::is_same<T, std::string>::value, StringRef>::type |
277 |
| - & |
278 |
| - operator=(T &&Str) = delete; |
279 |
| - |
280 |
| - operator std::string() const { return str(); } |
281 |
| - |
282 |
| - /// Check if this string starts with the given \p Prefix. |
283 |
| - bool startswith(StringRef Prefix) const { |
284 |
| - return Length >= Prefix.Length && |
285 |
| - compareMemory(Data, Prefix.Data, Prefix.Length) == 0; |
286 |
| - } |
287 |
| - |
288 |
| - /// Check if this string ends with the given \p Suffix. |
289 |
| - bool endswith(StringRef Suffix) const { |
290 |
| - return Length >= Suffix.Length && |
291 |
| - compareMemory(end() - Suffix.Length, Suffix.Data, Suffix.Length) == |
292 |
| - 0; |
293 |
| - } |
294 |
| - |
295 |
| - /// Search for the first character \p C in the string. |
296 |
| - /// |
297 |
| - /// \returns The index of the first occurrence of \p C, or npos if not |
298 |
| - /// found. |
299 |
| - size_t find(char C, size_t From = 0) const { |
300 |
| - size_t FindBegin = std::min(From, Length); |
301 |
| - if (FindBegin < Length) { // Avoid calling memchr with nullptr. |
302 |
| - // Just forward to memchr, which is faster than a hand-rolled loop. |
303 |
| - if (const void *P = ::memchr(Data + FindBegin, C, Length - FindBegin)) |
304 |
| - return static_cast<const char *>(P) - Data; |
305 |
| - } |
306 |
| - return npos; |
307 |
| - } |
308 |
| - |
309 |
| - /// Search for the last character \p C in the string. |
310 |
| - /// |
311 |
| - /// \returns The index of the last occurrence of \p C, or npos if not |
312 |
| - /// found. |
313 |
| - size_t rfind(char C, size_t From = npos) const { |
314 |
| - From = std::min(From, Length); |
315 |
| - size_t i = From; |
316 |
| - while (i != 0) { |
317 |
| - --i; |
318 |
| - if (Data[i] == C) |
319 |
| - return i; |
320 |
| - } |
321 |
| - return npos; |
322 |
| - } |
323 |
| - |
324 |
| - /// Find the first character in the string that is \p C, or npos if not |
325 |
| - /// found. Same as find. |
326 |
| - size_t find_first_of(char C, size_t From = 0) const { return find(C, From); } |
327 |
| - |
328 |
| - /// Find the last character in the string that is \p C, or npos if not |
329 |
| - /// found. |
330 |
| - size_t find_last_of(char C, size_t From = npos) const { |
331 |
| - return rfind(C, From); |
332 |
| - } |
333 |
| - |
334 |
| - /// Return the number of occurrences of \p C in the string. |
335 |
| - size_t count(char C) const { |
336 |
| - size_t Count = 0; |
337 |
| - for (size_t i = 0, e = Length; i != e; ++i) |
338 |
| - if (Data[i] == C) |
339 |
| - ++Count; |
340 |
| - return Count; |
341 |
| - } |
342 |
| - |
343 |
| - /// Return a reference to the substring from [Start, Start + N). |
344 |
| - /// |
345 |
| - /// \param Start The index of the starting character in the substring; if |
346 |
| - /// the index is npos or greater than the length of the string then the |
347 |
| - /// empty substring will be returned. |
348 |
| - /// |
349 |
| - /// \param N The number of characters to included in the substring. If N |
350 |
| - /// exceeds the number of characters remaining in the string, the string |
351 |
| - /// suffix (starting with \p Start) will be returned. |
352 |
| - StringRef substr(size_t Start, size_t N = npos) const { |
353 |
| - Start = std::min(Start, Length); |
354 |
| - return StringRef(Data + Start, std::min(N, Length - Start)); |
355 |
| - } |
356 |
| - |
357 |
| - /// Return a StringRef equal to 'this' but with only the first \p N |
358 |
| - /// elements remaining. If \p N is greater than the length of the |
359 |
| - /// string, the entire string is returned. |
360 |
| - StringRef take_front(size_t N = 1) const { |
361 |
| - if (N >= size()) |
362 |
| - return *this; |
363 |
| - return drop_back(size() - N); |
364 |
| - } |
365 |
| - |
366 |
| - /// Return a StringRef equal to 'this' but with only the last \p N |
367 |
| - /// elements remaining. If \p N is greater than the length of the |
368 |
| - /// string, the entire string is returned. |
369 |
| - StringRef take_back(size_t N = 1) const { |
370 |
| - if (N >= size()) |
371 |
| - return *this; |
372 |
| - return drop_front(size() - N); |
373 |
| - } |
374 |
| - |
375 |
| - /// Return a StringRef equal to 'this' but with the first \p N elements |
376 |
| - /// dropped. |
377 |
| - StringRef drop_front(size_t N = 1) const { |
378 |
| - assert(size() >= N && "Dropping more elements than exist"); |
379 |
| - return substr(N); |
380 |
| - } |
381 |
| - |
382 |
| - /// Return a StringRef equal to 'this' but with the last \p N elements |
383 |
| - /// dropped. |
384 |
| - StringRef drop_back(size_t N = 1) const { |
385 |
| - assert(size() >= N && "Dropping more elements than exist"); |
386 |
| - return substr(0, size() - N); |
387 |
| - } |
388 |
| - |
389 |
| - /// Returns true if this StringRef has the given prefix and removes that |
390 |
| - /// prefix. |
391 |
| - bool consume_front(StringRef Prefix) { |
392 |
| - if (!startswith(Prefix)) |
393 |
| - return false; |
394 |
| - |
395 |
| - *this = drop_front(Prefix.size()); |
396 |
| - return true; |
397 |
| - } |
398 |
| - |
399 |
| - /// Returns true if this StringRef has the given suffix and removes that |
400 |
| - /// suffix. |
401 |
| - bool consume_back(StringRef Suffix) { |
402 |
| - if (!endswith(Suffix)) |
403 |
| - return false; |
404 |
| - |
405 |
| - *this = drop_back(Suffix.size()); |
406 |
| - return true; |
407 |
| - } |
408 |
| - |
409 |
| - /// Return a reference to the substring from [Start, End). |
410 |
| - /// |
411 |
| - /// \param Start The index of the starting character in the substring; if |
412 |
| - /// the index is npos or greater than the length of the string then the |
413 |
| - /// empty substring will be returned. |
414 |
| - /// |
415 |
| - /// \param End The index following the last character to include in the |
416 |
| - /// substring. If this is npos or exceeds the number of characters |
417 |
| - /// remaining in the string, the string suffix (starting with \p Start) |
418 |
| - /// will be returned. If this is less than \p Start, an empty string will |
419 |
| - /// be returned. |
420 |
| - StringRef slice(size_t Start, size_t End) const { |
421 |
| - Start = std::min(Start, Length); |
422 |
| - End = std::min(std::max(Start, End), Length); |
423 |
| - return StringRef(Data + Start, End - Start); |
424 |
| - } |
425 |
| - |
426 |
| - /// Split into two substrings around the first occurrence of a separator |
427 |
| - /// character. |
428 |
| - /// |
429 |
| - /// If \p Separator is in the string, then the result is a pair (LHS, RHS) |
430 |
| - /// such that (*this == LHS + Separator + RHS) is true and RHS is |
431 |
| - /// maximal. If \p Separator is not in the string, then the result is a |
432 |
| - /// pair (LHS, RHS) where (*this == LHS) and (RHS == ""). |
433 |
| - /// |
434 |
| - /// \param Separator The character to split on. |
435 |
| - /// \returns The split substrings. |
436 |
| - std::pair<StringRef, StringRef> split(char Separator) const { |
437 |
| - size_t Idx = find(Separator); |
438 |
| - if (Idx == npos) |
439 |
| - return std::make_pair(*this, StringRef()); |
440 |
| - return std::make_pair(slice(0, Idx), slice(Idx + 1, npos)); |
441 |
| - } |
442 |
| -}; |
443 |
| - |
444 |
| -inline bool operator==(StringRef LHS, StringRef RHS) { return LHS.equals(RHS); } |
445 |
| - |
446 |
| -inline bool operator!=(StringRef LHS, StringRef RHS) { return !(LHS == RHS); } |
447 |
| - |
448 |
| -inline bool operator<(StringRef LHS, StringRef RHS) { |
449 |
| - return LHS.compare(RHS) == -1; |
450 |
| -} |
451 |
| - |
452 |
| -inline bool operator<=(StringRef LHS, StringRef RHS) { |
453 |
| - return LHS.compare(RHS) != 1; |
454 |
| -} |
455 |
| - |
456 |
| -inline bool operator>(StringRef LHS, StringRef RHS) { |
457 |
| - return LHS.compare(RHS) == 1; |
458 |
| -} |
459 |
| - |
460 |
| -inline bool operator>=(StringRef LHS, StringRef RHS) { |
461 |
| - return LHS.compare(RHS) != -1; |
462 |
| -} |
463 |
| - |
464 |
| -inline std::string &operator+=(std::string &buffer, StringRef string) { |
465 |
| - return buffer.append(string.data(), string.size()); |
466 |
| -} |
| 142 | +using llvm::StringRef; |
467 | 143 |
|
468 | 144 | } // namespace glow
|
469 | 145 |
|
|
0 commit comments