/src/hermes/external/llvh/include/llvh/ADT/StringRef.h
Line | Count | Source |
1 | | //===- StringRef.h - Constant String Reference Wrapper ----------*- 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 | | #ifndef LLVM_ADT_STRINGREF_H |
10 | | #define LLVM_ADT_STRINGREF_H |
11 | | |
12 | | #include "llvh/ADT/STLExtras.h" |
13 | | #include "llvh/ADT/iterator_range.h" |
14 | | #include "llvh/Support/Compiler.h" |
15 | | #include <algorithm> |
16 | | #include <cassert> |
17 | | #include <cstddef> |
18 | | #include <cstring> |
19 | | #include <limits> |
20 | | #include <string> |
21 | | #include <type_traits> |
22 | | #include <utility> |
23 | | |
24 | | #pragma GCC diagnostic push |
25 | | |
26 | | #ifdef HERMES_COMPILER_SUPPORTS_WSHORTEN_64_TO_32 |
27 | | #pragma GCC diagnostic ignored "-Wshorten-64-to-32" |
28 | | #endif |
29 | | |
30 | | namespace llvh { |
31 | | |
32 | | class APInt; |
33 | | class hash_code; |
34 | | template <typename T> class SmallVectorImpl; |
35 | | class StringRef; |
36 | | |
37 | | /// Helper functions for StringRef::getAsInteger. |
38 | | bool getAsUnsignedInteger(StringRef Str, unsigned Radix, |
39 | | unsigned long long &Result); |
40 | | |
41 | | bool getAsSignedInteger(StringRef Str, unsigned Radix, long long &Result); |
42 | | |
43 | | bool consumeUnsignedInteger(StringRef &Str, unsigned Radix, |
44 | | unsigned long long &Result); |
45 | | bool consumeSignedInteger(StringRef &Str, unsigned Radix, long long &Result); |
46 | | |
47 | | /// StringRef - Represent a constant reference to a string, i.e. a character |
48 | | /// array and a length, which need not be null terminated. |
49 | | /// |
50 | | /// This class does not own the string data, it is expected to be used in |
51 | | /// situations where the character data resides in some other buffer, whose |
52 | | /// lifetime extends past that of the StringRef. For this reason, it is not in |
53 | | /// general safe to store a StringRef. |
54 | | class StringRef { |
55 | | public: |
56 | | static const size_t npos = ~size_t(0); |
57 | | |
58 | | using iterator = const char *; |
59 | | using const_iterator = const char *; |
60 | | using size_type = size_t; |
61 | | |
62 | | private: |
63 | | /// The start of the string, in an external buffer. |
64 | | const char *Data = nullptr; |
65 | | |
66 | | /// The length of the string. |
67 | | size_t Length = 0; |
68 | | |
69 | | // Workaround memcmp issue with null pointers (undefined behavior) |
70 | | // by providing a specialized version |
71 | | LLVM_ATTRIBUTE_ALWAYS_INLINE |
72 | 16.2M | static int compareMemory(const char *Lhs, const char *Rhs, size_t Length) { |
73 | 16.2M | if (Length == 0) { return 0; } |
74 | 15.4M | return ::memcmp(Lhs,Rhs,Length); |
75 | 16.2M | } |
76 | | |
77 | | public: |
78 | | /// @name Constructors |
79 | | /// @{ |
80 | | |
81 | | /// Construct an empty string ref. |
82 | 3.55k | /*implicit*/ StringRef() = default; |
83 | | |
84 | | /// Disable conversion from nullptr. This prevents things like |
85 | | /// if (S == nullptr) |
86 | | StringRef(std::nullptr_t) = delete; |
87 | | |
88 | | /// Construct a string ref from a cstring. |
89 | | LLVM_ATTRIBUTE_ALWAYS_INLINE |
90 | | /*implicit*/ StringRef(const char *Str) |
91 | 3.61M | : Data(Str), Length(Str ? ::strlen(Str) : 0) {} |
92 | | |
93 | | /// Construct a string ref from a pointer and length. |
94 | | LLVM_ATTRIBUTE_ALWAYS_INLINE |
95 | | /*implicit*/ constexpr StringRef(const char *data, size_t length) |
96 | 329M | : Data(data), Length(length) {} |
97 | | |
98 | | /// Construct a string ref from an std::string. |
99 | | LLVM_ATTRIBUTE_ALWAYS_INLINE |
100 | | /*implicit*/ StringRef(const std::string &Str) |
101 | 45.5k | : Data(Str.data()), Length(Str.length()) {} |
102 | | |
103 | 0 | static StringRef withNullAsEmpty(const char *data) { |
104 | 0 | return StringRef(data ? data : ""); |
105 | 0 | } |
106 | | |
107 | | /// @} |
108 | | /// @name Iterators |
109 | | /// @{ |
110 | | |
111 | 9.36M | iterator begin() const { return Data; } |
112 | | |
113 | 9.28M | iterator end() const { return Data + Length; } |
114 | | |
115 | 438 | const unsigned char *bytes_begin() const { |
116 | 438 | return reinterpret_cast<const unsigned char *>(begin()); |
117 | 438 | } |
118 | 438 | const unsigned char *bytes_end() const { |
119 | 438 | return reinterpret_cast<const unsigned char *>(end()); |
120 | 438 | } |
121 | 42 | iterator_range<const unsigned char *> bytes() const { |
122 | 42 | return make_range(bytes_begin(), bytes_end()); |
123 | 42 | } |
124 | | |
125 | | /// @} |
126 | | /// @name String Operations |
127 | | /// @{ |
128 | | |
129 | | /// data - Get a pointer to the start of the string (which may not be null |
130 | | /// terminated). |
131 | | LLVM_NODISCARD |
132 | | LLVM_ATTRIBUTE_ALWAYS_INLINE |
133 | 200M | const char *data() const { return Data; } |
134 | | |
135 | | /// empty - Check if the string is empty. |
136 | | LLVM_NODISCARD |
137 | | LLVM_ATTRIBUTE_ALWAYS_INLINE |
138 | 834 | bool empty() const { return Length == 0; } |
139 | | |
140 | | /// size - Get the string size. |
141 | | LLVM_NODISCARD |
142 | | LLVM_ATTRIBUTE_ALWAYS_INLINE |
143 | 410k | size_t size() const { return Length; } |
144 | | |
145 | | /// front - Get the first character in the string. |
146 | | LLVM_NODISCARD |
147 | 0 | char front() const { |
148 | 0 | assert(!empty()); |
149 | 0 | return Data[0]; |
150 | 0 | } |
151 | | |
152 | | /// back - Get the last character in the string. |
153 | | LLVM_NODISCARD |
154 | 0 | char back() const { |
155 | 0 | assert(!empty()); |
156 | 0 | return Data[Length-1]; |
157 | 0 | } |
158 | | |
159 | | // copy - Allocate copy in Allocator and return StringRef to it. |
160 | | template <typename Allocator> |
161 | | LLVM_NODISCARD StringRef copy(Allocator &A) const { |
162 | | // Don't request a length 0 copy from the allocator. |
163 | | if (empty()) |
164 | | return StringRef(); |
165 | | char *S = A.template Allocate<char>(Length); |
166 | | std::copy(begin(), end(), S); |
167 | | return StringRef(S, Length); |
168 | | } |
169 | | |
170 | | /// equals - Check for string equality, this is more efficient than |
171 | | /// compare() when the relative ordering of inequal strings isn't needed. |
172 | | LLVM_NODISCARD |
173 | | LLVM_ATTRIBUTE_ALWAYS_INLINE |
174 | 192M | bool equals(StringRef RHS) const { |
175 | 192M | return (Length == RHS.Length && |
176 | 16.1M | compareMemory(Data, RHS.Data, RHS.Length) == 0); |
177 | 192M | } |
178 | | |
179 | | /// equals_lower - Check for string equality, ignoring case. |
180 | | LLVM_NODISCARD |
181 | 0 | bool equals_lower(StringRef RHS) const { |
182 | 0 | return Length == RHS.Length && compare_lower(RHS) == 0; |
183 | 0 | } |
184 | | |
185 | | /// compare - Compare two strings; the result is -1, 0, or 1 if this string |
186 | | /// is lexicographically less than, equal to, or greater than the \p RHS. |
187 | | LLVM_NODISCARD |
188 | | LLVM_ATTRIBUTE_ALWAYS_INLINE |
189 | 90.8k | int compare(StringRef RHS) const { |
190 | | // Check the prefix for a mismatch. |
191 | 90.8k | if (int Res = compareMemory(Data, RHS.Data, std::min(Length, RHS.Length))) |
192 | 85.2k | return Res < 0 ? -1 : 1; |
193 | | |
194 | | // Otherwise the prefixes match, so we only need to check the lengths. |
195 | 5.60k | if (Length == RHS.Length) |
196 | 0 | return 0; |
197 | 5.60k | return Length < RHS.Length ? -1 : 1; |
198 | 5.60k | } |
199 | | |
200 | | /// compare_lower - Compare two strings, ignoring case. |
201 | | LLVM_NODISCARD |
202 | | int compare_lower(StringRef RHS) const; |
203 | | |
204 | | /// compare_numeric - Compare two strings, treating sequences of digits as |
205 | | /// numbers. |
206 | | LLVM_NODISCARD |
207 | | int compare_numeric(StringRef RHS) const; |
208 | | |
209 | | /// Determine the edit distance between this string and another |
210 | | /// string. |
211 | | /// |
212 | | /// \param Other the string to compare this string against. |
213 | | /// |
214 | | /// \param AllowReplacements whether to allow character |
215 | | /// replacements (change one character into another) as a single |
216 | | /// operation, rather than as two operations (an insertion and a |
217 | | /// removal). |
218 | | /// |
219 | | /// \param MaxEditDistance If non-zero, the maximum edit distance that |
220 | | /// this routine is allowed to compute. If the edit distance will exceed |
221 | | /// that maximum, returns \c MaxEditDistance+1. |
222 | | /// |
223 | | /// \returns the minimum number of character insertions, removals, |
224 | | /// or (if \p AllowReplacements is \c true) replacements needed to |
225 | | /// transform one of the given strings into the other. If zero, |
226 | | /// the strings are identical. |
227 | | LLVM_NODISCARD |
228 | | unsigned edit_distance(StringRef Other, bool AllowReplacements = true, |
229 | | unsigned MaxEditDistance = 0) const; |
230 | | |
231 | | /// str - Get the contents as an std::string. |
232 | | LLVM_NODISCARD |
233 | 6.01k | std::string str() const { |
234 | 6.01k | if (!Data) return std::string(); |
235 | 5.90k | return std::string(Data, Length); |
236 | 6.01k | } |
237 | | |
238 | | /// @} |
239 | | /// @name Operator Overloads |
240 | | /// @{ |
241 | | |
242 | | LLVM_NODISCARD |
243 | 42.2M | char operator[](size_t Index) const { |
244 | 42.2M | assert(Index < Length && "Invalid index!"); |
245 | 42.2M | return Data[Index]; |
246 | 42.2M | } |
247 | | |
248 | | /// Disallow accidental assignment from a temporary std::string. |
249 | | /// |
250 | | /// The declaration here is extra complicated so that `stringRef = {}` |
251 | | /// and `stringRef = "abc"` continue to select the move assignment operator. |
252 | | template <typename T> |
253 | | typename std::enable_if<std::is_same<T, std::string>::value, |
254 | | StringRef>::type & |
255 | | operator=(T &&Str) = delete; |
256 | | |
257 | | /// @} |
258 | | /// @name Type Conversions |
259 | | /// @{ |
260 | | |
261 | 5.52k | operator std::string() const { |
262 | 5.52k | return str(); |
263 | 5.52k | } |
264 | | |
265 | | /// @} |
266 | | /// @name String Predicates |
267 | | /// @{ |
268 | | |
269 | | /// Check if this string starts with the given \p Prefix. |
270 | | LLVM_NODISCARD |
271 | | LLVM_ATTRIBUTE_ALWAYS_INLINE |
272 | 247 | bool startswith(StringRef Prefix) const { |
273 | 247 | return Length >= Prefix.Length && |
274 | 247 | compareMemory(Data, Prefix.Data, Prefix.Length) == 0; |
275 | 247 | } |
276 | | |
277 | | /// Check if this string starts with the given \p Prefix, ignoring case. |
278 | | LLVM_NODISCARD |
279 | | bool startswith_lower(StringRef Prefix) const; |
280 | | |
281 | | /// Check if this string ends with the given \p Suffix. |
282 | | LLVM_NODISCARD |
283 | | LLVM_ATTRIBUTE_ALWAYS_INLINE |
284 | 0 | bool endswith(StringRef Suffix) const { |
285 | 0 | return Length >= Suffix.Length && |
286 | 0 | compareMemory(end() - Suffix.Length, Suffix.Data, Suffix.Length) == 0; |
287 | 0 | } |
288 | | |
289 | | /// Check if this string ends with the given \p Suffix, ignoring case. |
290 | | LLVM_NODISCARD |
291 | | bool endswith_lower(StringRef Suffix) const; |
292 | | |
293 | | /// @} |
294 | | /// @name String Searching |
295 | | /// @{ |
296 | | |
297 | | /// Search for the first character \p C in the string. |
298 | | /// |
299 | | /// \returns The index of the first occurrence of \p C, or npos if not |
300 | | /// found. |
301 | | LLVM_NODISCARD |
302 | | LLVM_ATTRIBUTE_ALWAYS_INLINE |
303 | 0 | size_t find(char C, size_t From = 0) const { |
304 | 0 | size_t FindBegin = std::min(From, Length); |
305 | 0 | if (FindBegin < Length) { // Avoid calling memchr with nullptr. |
306 | | // Just forward to memchr, which is faster than a hand-rolled loop. |
307 | 0 | if (const void *P = ::memchr(Data + FindBegin, C, Length - FindBegin)) |
308 | 0 | return static_cast<const char *>(P) - Data; |
309 | 0 | } |
310 | 0 | return npos; |
311 | 0 | } |
312 | | |
313 | | /// Search for the first character \p C in the string, ignoring case. |
314 | | /// |
315 | | /// \returns The index of the first occurrence of \p C, or npos if not |
316 | | /// found. |
317 | | LLVM_NODISCARD |
318 | | size_t find_lower(char C, size_t From = 0) const; |
319 | | |
320 | | /// Search for the first character satisfying the predicate \p F |
321 | | /// |
322 | | /// \returns The index of the first character satisfying \p F starting from |
323 | | /// \p From, or npos if not found. |
324 | | LLVM_NODISCARD |
325 | | LLVM_ATTRIBUTE_ALWAYS_INLINE |
326 | 0 | size_t find_if(function_ref<bool(char)> F, size_t From = 0) const { |
327 | 0 | StringRef S = drop_front(From); |
328 | 0 | while (!S.empty()) { |
329 | 0 | if (F(S.front())) |
330 | 0 | return size() - S.size(); |
331 | 0 | S = S.drop_front(); |
332 | 0 | } |
333 | 0 | return npos; |
334 | 0 | } |
335 | | |
336 | | /// Search for the first character not satisfying the predicate \p F |
337 | | /// |
338 | | /// \returns The index of the first character not satisfying \p F starting |
339 | | /// from \p From, or npos if not found. |
340 | | LLVM_NODISCARD |
341 | | LLVM_ATTRIBUTE_ALWAYS_INLINE |
342 | 0 | size_t find_if_not(function_ref<bool(char)> F, size_t From = 0) const { |
343 | 0 | return find_if([F](char c) { return !F(c); }, From); |
344 | 0 | } |
345 | | |
346 | | /// Search for the first string \p Str in the string. |
347 | | /// |
348 | | /// \returns The index of the first occurrence of \p Str, or npos if not |
349 | | /// found. |
350 | | LLVM_NODISCARD |
351 | | size_t find(StringRef Str, size_t From = 0) const; |
352 | | |
353 | | /// Search for the first string \p Str in the string, ignoring case. |
354 | | /// |
355 | | /// \returns The index of the first occurrence of \p Str, or npos if not |
356 | | /// found. |
357 | | LLVM_NODISCARD |
358 | | size_t find_lower(StringRef Str, size_t From = 0) const; |
359 | | |
360 | | /// Search for the last character \p C in the string. |
361 | | /// |
362 | | /// \returns The index of the last occurrence of \p C, or npos if not |
363 | | /// found. |
364 | | LLVM_NODISCARD |
365 | 0 | size_t rfind(char C, size_t From = npos) const { |
366 | 0 | From = std::min(From, Length); |
367 | 0 | size_t i = From; |
368 | 0 | while (i != 0) { |
369 | 0 | --i; |
370 | 0 | if (Data[i] == C) |
371 | 0 | return i; |
372 | 0 | } |
373 | 0 | return npos; |
374 | 0 | } |
375 | | |
376 | | /// Search for the last character \p C in the string, ignoring case. |
377 | | /// |
378 | | /// \returns The index of the last occurrence of \p C, or npos if not |
379 | | /// found. |
380 | | LLVM_NODISCARD |
381 | | size_t rfind_lower(char C, size_t From = npos) const; |
382 | | |
383 | | /// Search for the last string \p Str in the string. |
384 | | /// |
385 | | /// \returns The index of the last occurrence of \p Str, or npos if not |
386 | | /// found. |
387 | | LLVM_NODISCARD |
388 | | size_t rfind(StringRef Str) const; |
389 | | |
390 | | /// Search for the last string \p Str in the string, ignoring case. |
391 | | /// |
392 | | /// \returns The index of the last occurrence of \p Str, or npos if not |
393 | | /// found. |
394 | | LLVM_NODISCARD |
395 | | size_t rfind_lower(StringRef Str) const; |
396 | | |
397 | | /// Find the first character in the string that is \p C, or npos if not |
398 | | /// found. Same as find. |
399 | | LLVM_NODISCARD |
400 | 0 | size_t find_first_of(char C, size_t From = 0) const { |
401 | 0 | return find(C, From); |
402 | 0 | } |
403 | | |
404 | | /// Find the first character in the string that is in \p Chars, or npos if |
405 | | /// not found. |
406 | | /// |
407 | | /// Complexity: O(size() + Chars.size()) |
408 | | LLVM_NODISCARD |
409 | | size_t find_first_of(StringRef Chars, size_t From = 0) const; |
410 | | |
411 | | /// Find the first character in the string that is not \p C or npos if not |
412 | | /// found. |
413 | | LLVM_NODISCARD |
414 | | size_t find_first_not_of(char C, size_t From = 0) const; |
415 | | |
416 | | /// Find the first character in the string that is not in the string |
417 | | /// \p Chars, or npos if not found. |
418 | | /// |
419 | | /// Complexity: O(size() + Chars.size()) |
420 | | LLVM_NODISCARD |
421 | | size_t find_first_not_of(StringRef Chars, size_t From = 0) const; |
422 | | |
423 | | /// Find the last character in the string that is \p C, or npos if not |
424 | | /// found. |
425 | | LLVM_NODISCARD |
426 | 0 | size_t find_last_of(char C, size_t From = npos) const { |
427 | 0 | return rfind(C, From); |
428 | 0 | } |
429 | | |
430 | | /// Find the last character in the string that is in \p C, or npos if not |
431 | | /// found. |
432 | | /// |
433 | | /// Complexity: O(size() + Chars.size()) |
434 | | LLVM_NODISCARD |
435 | | size_t find_last_of(StringRef Chars, size_t From = npos) const; |
436 | | |
437 | | /// Find the last character in the string that is not \p C, or npos if not |
438 | | /// found. |
439 | | LLVM_NODISCARD |
440 | | size_t find_last_not_of(char C, size_t From = npos) const; |
441 | | |
442 | | /// Find the last character in the string that is not in \p Chars, or |
443 | | /// npos if not found. |
444 | | /// |
445 | | /// Complexity: O(size() + Chars.size()) |
446 | | LLVM_NODISCARD |
447 | | size_t find_last_not_of(StringRef Chars, size_t From = npos) const; |
448 | | |
449 | | /// Return true if the given string is a substring of *this, and false |
450 | | /// otherwise. |
451 | | LLVM_NODISCARD |
452 | | LLVM_ATTRIBUTE_ALWAYS_INLINE |
453 | 0 | bool contains(StringRef Other) const { return find(Other) != npos; } |
454 | | |
455 | | /// Return true if the given character is contained in *this, and false |
456 | | /// otherwise. |
457 | | LLVM_NODISCARD |
458 | | LLVM_ATTRIBUTE_ALWAYS_INLINE |
459 | 0 | bool contains(char C) const { return find_first_of(C) != npos; } |
460 | | |
461 | | /// Return true if the given string is a substring of *this, and false |
462 | | /// otherwise. |
463 | | LLVM_NODISCARD |
464 | | LLVM_ATTRIBUTE_ALWAYS_INLINE |
465 | 0 | bool contains_lower(StringRef Other) const { |
466 | 0 | return find_lower(Other) != npos; |
467 | 0 | } |
468 | | |
469 | | /// Return true if the given character is contained in *this, and false |
470 | | /// otherwise. |
471 | | LLVM_NODISCARD |
472 | | LLVM_ATTRIBUTE_ALWAYS_INLINE |
473 | 0 | bool contains_lower(char C) const { return find_lower(C) != npos; } |
474 | | |
475 | | /// @} |
476 | | /// @name Helpful Algorithms |
477 | | /// @{ |
478 | | |
479 | | /// Return the number of occurrences of \p C in the string. |
480 | | LLVM_NODISCARD |
481 | 0 | size_t count(char C) const { |
482 | 0 | size_t Count = 0; |
483 | 0 | for (size_t i = 0, e = Length; i != e; ++i) |
484 | 0 | if (Data[i] == C) |
485 | 0 | ++Count; |
486 | 0 | return Count; |
487 | 0 | } |
488 | | |
489 | | /// Return the number of non-overlapped occurrences of \p Str in |
490 | | /// the string. |
491 | | size_t count(StringRef Str) const; |
492 | | |
493 | | /// Parse the current string as an integer of the specified radix. If |
494 | | /// \p Radix is specified as zero, this does radix autosensing using |
495 | | /// extended C rules: 0 is octal, 0x is hex, 0b is binary. |
496 | | /// |
497 | | /// If the string is invalid or if only a subset of the string is valid, |
498 | | /// this returns true to signify the error. The string is considered |
499 | | /// erroneous if empty or if it overflows T. |
500 | | template <typename T> |
501 | | typename std::enable_if<std::numeric_limits<T>::is_signed, bool>::type |
502 | 0 | getAsInteger(unsigned Radix, T &Result) const { |
503 | 0 | long long LLVal; |
504 | 0 | if (getAsSignedInteger(*this, Radix, LLVal) || |
505 | 0 | static_cast<T>(LLVal) != LLVal) |
506 | 0 | return true; |
507 | 0 | Result = LLVal; |
508 | 0 | return false; |
509 | 0 | } |
510 | | |
511 | | template <typename T> |
512 | | typename std::enable_if<!std::numeric_limits<T>::is_signed, bool>::type |
513 | 0 | getAsInteger(unsigned Radix, T &Result) const { |
514 | 0 | unsigned long long ULLVal; |
515 | | // The additional cast to unsigned long long is required to avoid the |
516 | | // Visual C++ warning C4805: '!=' : unsafe mix of type 'bool' and type |
517 | | // 'unsigned __int64' when instantiating getAsInteger with T = bool. |
518 | 0 | if (getAsUnsignedInteger(*this, Radix, ULLVal) || |
519 | 0 | static_cast<unsigned long long>(static_cast<T>(ULLVal)) != ULLVal) |
520 | 0 | return true; |
521 | 0 | Result = ULLVal; |
522 | 0 | return false; |
523 | 0 | } Unexecuted instantiation: _ZNK4llvh9StringRef12getAsIntegerImEENSt3__19enable_ifIXntsr3std14numeric_limitsIT_EE9is_signedEbE4typeEjRS4_ Unexecuted instantiation: _ZNK4llvh9StringRef12getAsIntegerIjEENSt3__19enable_ifIXntsr3std14numeric_limitsIT_EE9is_signedEbE4typeEjRS4_ Unexecuted instantiation: _ZNK4llvh9StringRef12getAsIntegerIyEENSt3__19enable_ifIXntsr3std14numeric_limitsIT_EE9is_signedEbE4typeEjRS4_ |
524 | | |
525 | | /// Parse the current string as an integer of the specified radix. If |
526 | | /// \p Radix is specified as zero, this does radix autosensing using |
527 | | /// extended C rules: 0 is octal, 0x is hex, 0b is binary. |
528 | | /// |
529 | | /// If the string does not begin with a number of the specified radix, |
530 | | /// this returns true to signify the error. The string is considered |
531 | | /// erroneous if empty or if it overflows T. |
532 | | /// The portion of the string representing the discovered numeric value |
533 | | /// is removed from the beginning of the string. |
534 | | template <typename T> |
535 | | typename std::enable_if<std::numeric_limits<T>::is_signed, bool>::type |
536 | | consumeInteger(unsigned Radix, T &Result) { |
537 | | long long LLVal; |
538 | | if (consumeSignedInteger(*this, Radix, LLVal) || |
539 | | static_cast<long long>(static_cast<T>(LLVal)) != LLVal) |
540 | | return true; |
541 | | Result = LLVal; |
542 | | return false; |
543 | | } |
544 | | |
545 | | template <typename T> |
546 | | typename std::enable_if<!std::numeric_limits<T>::is_signed, bool>::type |
547 | 0 | consumeInteger(unsigned Radix, T &Result) { |
548 | 0 | unsigned long long ULLVal; |
549 | 0 | if (consumeUnsignedInteger(*this, Radix, ULLVal) || |
550 | 0 | static_cast<unsigned long long>(static_cast<T>(ULLVal)) != ULLVal) |
551 | 0 | return true; |
552 | 0 | Result = ULLVal; |
553 | 0 | return false; |
554 | 0 | } |
555 | | |
556 | | /// Parse the current string as an integer of the specified \p Radix, or of |
557 | | /// an autosensed radix if the \p Radix given is 0. The current value in |
558 | | /// \p Result is discarded, and the storage is changed to be wide enough to |
559 | | /// store the parsed integer. |
560 | | /// |
561 | | /// \returns true if the string does not solely consist of a valid |
562 | | /// non-empty number in the appropriate base. |
563 | | /// |
564 | | /// APInt::fromString is superficially similar but assumes the |
565 | | /// string is well-formed in the given radix. |
566 | | bool getAsInteger(unsigned Radix, APInt &Result) const; |
567 | | |
568 | | /// Parse the current string as an IEEE double-precision floating |
569 | | /// point value. The string must be a well-formed double. |
570 | | /// |
571 | | /// If \p AllowInexact is false, the function will fail if the string |
572 | | /// cannot be represented exactly. Otherwise, the function only fails |
573 | | /// in case of an overflow or underflow. |
574 | | bool getAsDouble(double &Result, bool AllowInexact = true) const; |
575 | | |
576 | | /// @} |
577 | | /// @name String Operations |
578 | | /// @{ |
579 | | |
580 | | // Convert the given ASCII string to lowercase. |
581 | | LLVM_NODISCARD |
582 | | std::string lower() const; |
583 | | |
584 | | /// Convert the given ASCII string to uppercase. |
585 | | LLVM_NODISCARD |
586 | | std::string upper() const; |
587 | | |
588 | | /// @} |
589 | | /// @name Substring Operations |
590 | | /// @{ |
591 | | |
592 | | /// Return a reference to the substring from [Start, Start + N). |
593 | | /// |
594 | | /// \param Start The index of the starting character in the substring; if |
595 | | /// the index is npos or greater than the length of the string then the |
596 | | /// empty substring will be returned. |
597 | | /// |
598 | | /// \param N The number of characters to included in the substring. If N |
599 | | /// exceeds the number of characters remaining in the string, the string |
600 | | /// suffix (starting with \p Start) will be returned. |
601 | | LLVM_NODISCARD |
602 | | LLVM_ATTRIBUTE_ALWAYS_INLINE |
603 | 46 | StringRef substr(size_t Start, size_t N = npos) const { |
604 | 46 | Start = std::min(Start, Length); |
605 | 46 | return StringRef(Data + Start, std::min(N, Length - Start)); |
606 | 46 | } |
607 | | |
608 | | /// Return a StringRef equal to 'this' but with only the first \p N |
609 | | /// elements remaining. If \p N is greater than the length of the |
610 | | /// string, the entire string is returned. |
611 | | LLVM_NODISCARD |
612 | | LLVM_ATTRIBUTE_ALWAYS_INLINE |
613 | 0 | StringRef take_front(size_t N = 1) const { |
614 | 0 | if (N >= size()) |
615 | 0 | return *this; |
616 | 0 | return drop_back(size() - N); |
617 | 0 | } |
618 | | |
619 | | /// Return a StringRef equal to 'this' but with only the last \p N |
620 | | /// elements remaining. If \p N is greater than the length of the |
621 | | /// string, the entire string is returned. |
622 | | LLVM_NODISCARD |
623 | | LLVM_ATTRIBUTE_ALWAYS_INLINE |
624 | 0 | StringRef take_back(size_t N = 1) const { |
625 | 0 | if (N >= size()) |
626 | 0 | return *this; |
627 | 0 | return drop_front(size() - N); |
628 | 0 | } |
629 | | |
630 | | /// Return the longest prefix of 'this' such that every character |
631 | | /// in the prefix satisfies the given predicate. |
632 | | LLVM_NODISCARD |
633 | | LLVM_ATTRIBUTE_ALWAYS_INLINE |
634 | 0 | StringRef take_while(function_ref<bool(char)> F) const { |
635 | 0 | return substr(0, find_if_not(F)); |
636 | 0 | } |
637 | | |
638 | | /// Return the longest prefix of 'this' such that no character in |
639 | | /// the prefix satisfies the given predicate. |
640 | | LLVM_NODISCARD |
641 | | LLVM_ATTRIBUTE_ALWAYS_INLINE |
642 | 0 | StringRef take_until(function_ref<bool(char)> F) const { |
643 | 0 | return substr(0, find_if(F)); |
644 | 0 | } |
645 | | |
646 | | /// Return a StringRef equal to 'this' but with the first \p N elements |
647 | | /// dropped. |
648 | | LLVM_NODISCARD |
649 | | LLVM_ATTRIBUTE_ALWAYS_INLINE |
650 | 46 | StringRef drop_front(size_t N = 1) const { |
651 | 46 | assert(size() >= N && "Dropping more elements than exist"); |
652 | 46 | return substr(N); |
653 | 46 | } |
654 | | |
655 | | /// Return a StringRef equal to 'this' but with the last \p N elements |
656 | | /// dropped. |
657 | | LLVM_NODISCARD |
658 | | LLVM_ATTRIBUTE_ALWAYS_INLINE |
659 | 0 | StringRef drop_back(size_t N = 1) const { |
660 | 0 | assert(size() >= N && "Dropping more elements than exist"); |
661 | 0 | return substr(0, size()-N); |
662 | 0 | } |
663 | | |
664 | | /// Return a StringRef equal to 'this', but with all characters satisfying |
665 | | /// the given predicate dropped from the beginning of the string. |
666 | | LLVM_NODISCARD |
667 | | LLVM_ATTRIBUTE_ALWAYS_INLINE |
668 | 0 | StringRef drop_while(function_ref<bool(char)> F) const { |
669 | 0 | return substr(find_if_not(F)); |
670 | 0 | } |
671 | | |
672 | | /// Return a StringRef equal to 'this', but with all characters not |
673 | | /// satisfying the given predicate dropped from the beginning of the string. |
674 | | LLVM_NODISCARD |
675 | | LLVM_ATTRIBUTE_ALWAYS_INLINE |
676 | 0 | StringRef drop_until(function_ref<bool(char)> F) const { |
677 | 0 | return substr(find_if(F)); |
678 | 0 | } |
679 | | |
680 | | /// Returns true if this StringRef has the given prefix and removes that |
681 | | /// prefix. |
682 | | LLVM_ATTRIBUTE_ALWAYS_INLINE |
683 | 247 | bool consume_front(StringRef Prefix) { |
684 | 247 | if (!startswith(Prefix)) |
685 | 201 | return false; |
686 | | |
687 | 46 | *this = drop_front(Prefix.size()); |
688 | 46 | return true; |
689 | 247 | } |
690 | | |
691 | | /// Returns true if this StringRef has the given suffix and removes that |
692 | | /// suffix. |
693 | | LLVM_ATTRIBUTE_ALWAYS_INLINE |
694 | 0 | bool consume_back(StringRef Suffix) { |
695 | 0 | if (!endswith(Suffix)) |
696 | 0 | return false; |
697 | | |
698 | 0 | *this = drop_back(Suffix.size()); |
699 | 0 | return true; |
700 | 0 | } |
701 | | |
702 | | /// Return a reference to the substring from [Start, End). |
703 | | /// |
704 | | /// \param Start The index of the starting character in the substring; if |
705 | | /// the index is npos or greater than the length of the string then the |
706 | | /// empty substring will be returned. |
707 | | /// |
708 | | /// \param End The index following the last character to include in the |
709 | | /// substring. If this is npos or exceeds the number of characters |
710 | | /// remaining in the string, the string suffix (starting with \p Start) |
711 | | /// will be returned. If this is less than \p Start, an empty string will |
712 | | /// be returned. |
713 | | LLVM_NODISCARD |
714 | | LLVM_ATTRIBUTE_ALWAYS_INLINE |
715 | 0 | StringRef slice(size_t Start, size_t End) const { |
716 | 0 | Start = std::min(Start, Length); |
717 | 0 | End = std::min(std::max(Start, End), Length); |
718 | 0 | return StringRef(Data + Start, End - Start); |
719 | 0 | } |
720 | | |
721 | | /// Split into two substrings around the first occurrence of a separator |
722 | | /// character. |
723 | | /// |
724 | | /// If \p Separator is in the string, then the result is a pair (LHS, RHS) |
725 | | /// such that (*this == LHS + Separator + RHS) is true and RHS is |
726 | | /// maximal. If \p Separator is not in the string, then the result is a |
727 | | /// pair (LHS, RHS) where (*this == LHS) and (RHS == ""). |
728 | | /// |
729 | | /// \param Separator The character to split on. |
730 | | /// \returns The split substrings. |
731 | | LLVM_NODISCARD |
732 | 0 | std::pair<StringRef, StringRef> split(char Separator) const { |
733 | 0 | return split(StringRef(&Separator, 1)); |
734 | 0 | } |
735 | | |
736 | | /// Split into two substrings around the first occurrence of a separator |
737 | | /// string. |
738 | | /// |
739 | | /// If \p Separator is in the string, then the result is a pair (LHS, RHS) |
740 | | /// such that (*this == LHS + Separator + RHS) is true and RHS is |
741 | | /// maximal. If \p Separator is not in the string, then the result is a |
742 | | /// pair (LHS, RHS) where (*this == LHS) and (RHS == ""). |
743 | | /// |
744 | | /// \param Separator - The string to split on. |
745 | | /// \return - The split substrings. |
746 | | LLVM_NODISCARD |
747 | 0 | std::pair<StringRef, StringRef> split(StringRef Separator) const { |
748 | 0 | size_t Idx = find(Separator); |
749 | 0 | if (Idx == npos) |
750 | 0 | return std::make_pair(*this, StringRef()); |
751 | 0 | return std::make_pair(slice(0, Idx), slice(Idx + Separator.size(), npos)); |
752 | 0 | } |
753 | | |
754 | | /// Split into two substrings around the last occurrence of a separator |
755 | | /// string. |
756 | | /// |
757 | | /// If \p Separator is in the string, then the result is a pair (LHS, RHS) |
758 | | /// such that (*this == LHS + Separator + RHS) is true and RHS is |
759 | | /// minimal. If \p Separator is not in the string, then the result is a |
760 | | /// pair (LHS, RHS) where (*this == LHS) and (RHS == ""). |
761 | | /// |
762 | | /// \param Separator - The string to split on. |
763 | | /// \return - The split substrings. |
764 | | LLVM_NODISCARD |
765 | 0 | std::pair<StringRef, StringRef> rsplit(StringRef Separator) const { |
766 | 0 | size_t Idx = rfind(Separator); |
767 | 0 | if (Idx == npos) |
768 | 0 | return std::make_pair(*this, StringRef()); |
769 | 0 | return std::make_pair(slice(0, Idx), slice(Idx + Separator.size(), npos)); |
770 | 0 | } |
771 | | |
772 | | /// Split into substrings around the occurrences of a separator string. |
773 | | /// |
774 | | /// Each substring is stored in \p A. If \p MaxSplit is >= 0, at most |
775 | | /// \p MaxSplit splits are done and consequently <= \p MaxSplit + 1 |
776 | | /// elements are added to A. |
777 | | /// If \p KeepEmpty is false, empty strings are not added to \p A. They |
778 | | /// still count when considering \p MaxSplit |
779 | | /// An useful invariant is that |
780 | | /// Separator.join(A) == *this if MaxSplit == -1 and KeepEmpty == true |
781 | | /// |
782 | | /// \param A - Where to put the substrings. |
783 | | /// \param Separator - The string to split on. |
784 | | /// \param MaxSplit - The maximum number of times the string is split. |
785 | | /// \param KeepEmpty - True if empty substring should be added. |
786 | | void split(SmallVectorImpl<StringRef> &A, |
787 | | StringRef Separator, int MaxSplit = -1, |
788 | | bool KeepEmpty = true) const; |
789 | | |
790 | | /// Split into substrings around the occurrences of a separator character. |
791 | | /// |
792 | | /// Each substring is stored in \p A. If \p MaxSplit is >= 0, at most |
793 | | /// \p MaxSplit splits are done and consequently <= \p MaxSplit + 1 |
794 | | /// elements are added to A. |
795 | | /// If \p KeepEmpty is false, empty strings are not added to \p A. They |
796 | | /// still count when considering \p MaxSplit |
797 | | /// An useful invariant is that |
798 | | /// Separator.join(A) == *this if MaxSplit == -1 and KeepEmpty == true |
799 | | /// |
800 | | /// \param A - Where to put the substrings. |
801 | | /// \param Separator - The string to split on. |
802 | | /// \param MaxSplit - The maximum number of times the string is split. |
803 | | /// \param KeepEmpty - True if empty substring should be added. |
804 | | void split(SmallVectorImpl<StringRef> &A, char Separator, int MaxSplit = -1, |
805 | | bool KeepEmpty = true) const; |
806 | | |
807 | | /// Split into two substrings around the last occurrence of a separator |
808 | | /// character. |
809 | | /// |
810 | | /// If \p Separator is in the string, then the result is a pair (LHS, RHS) |
811 | | /// such that (*this == LHS + Separator + RHS) is true and RHS is |
812 | | /// minimal. If \p Separator is not in the string, then the result is a |
813 | | /// pair (LHS, RHS) where (*this == LHS) and (RHS == ""). |
814 | | /// |
815 | | /// \param Separator - The character to split on. |
816 | | /// \return - The split substrings. |
817 | | LLVM_NODISCARD |
818 | 0 | std::pair<StringRef, StringRef> rsplit(char Separator) const { |
819 | 0 | return rsplit(StringRef(&Separator, 1)); |
820 | 0 | } |
821 | | |
822 | | /// Return string with consecutive \p Char characters starting from the |
823 | | /// the left removed. |
824 | | LLVM_NODISCARD |
825 | 0 | StringRef ltrim(char Char) const { |
826 | 0 | return drop_front(std::min(Length, find_first_not_of(Char))); |
827 | 0 | } |
828 | | |
829 | | /// Return string with consecutive characters in \p Chars starting from |
830 | | /// the left removed. |
831 | | LLVM_NODISCARD |
832 | 0 | StringRef ltrim(StringRef Chars = " \t\n\v\f\r") const { |
833 | 0 | return drop_front(std::min(Length, find_first_not_of(Chars))); |
834 | 0 | } |
835 | | |
836 | | /// Return string with consecutive \p Char characters starting from the |
837 | | /// right removed. |
838 | | LLVM_NODISCARD |
839 | 0 | StringRef rtrim(char Char) const { |
840 | 0 | return drop_back(Length - std::min(Length, find_last_not_of(Char) + 1)); |
841 | 0 | } |
842 | | |
843 | | /// Return string with consecutive characters in \p Chars starting from |
844 | | /// the right removed. |
845 | | LLVM_NODISCARD |
846 | 0 | StringRef rtrim(StringRef Chars = " \t\n\v\f\r") const { |
847 | 0 | return drop_back(Length - std::min(Length, find_last_not_of(Chars) + 1)); |
848 | 0 | } |
849 | | |
850 | | /// Return string with consecutive \p Char characters starting from the |
851 | | /// left and right removed. |
852 | | LLVM_NODISCARD |
853 | 0 | StringRef trim(char Char) const { |
854 | 0 | return ltrim(Char).rtrim(Char); |
855 | 0 | } |
856 | | |
857 | | /// Return string with consecutive characters in \p Chars starting from |
858 | | /// the left and right removed. |
859 | | LLVM_NODISCARD |
860 | 0 | StringRef trim(StringRef Chars = " \t\n\v\f\r") const { |
861 | 0 | return ltrim(Chars).rtrim(Chars); |
862 | 0 | } |
863 | | |
864 | | /// @} |
865 | | }; |
866 | | |
867 | | /// A wrapper around a string literal that serves as a proxy for constructing |
868 | | /// global tables of StringRefs with the length computed at compile time. |
869 | | /// In order to avoid the invocation of a global constructor, StringLiteral |
870 | | /// should *only* be used in a constexpr context, as such: |
871 | | /// |
872 | | /// constexpr StringLiteral S("test"); |
873 | | /// |
874 | | class StringLiteral : public StringRef { |
875 | | private: |
876 | 0 | constexpr StringLiteral(const char *Str, size_t N) : StringRef(Str, N) { |
877 | 0 | } |
878 | | |
879 | | public: |
880 | | template <size_t N> |
881 | | constexpr StringLiteral(const char (&Str)[N]) |
882 | | #if defined(__clang__) && __has_attribute(enable_if) |
883 | | #pragma clang diagnostic push |
884 | | #pragma clang diagnostic ignored "-Wgcc-compat" |
885 | | __attribute((enable_if(__builtin_strlen(Str) == N - 1, |
886 | | "invalid string literal"))) |
887 | | #pragma clang diagnostic pop |
888 | | #endif |
889 | 206M | : StringRef(Str, N - 1) { |
890 | 206M | } _ZN4llvh13StringLiteralC2ILm4EEEUa9enable_ifIXeqclL_Z16__builtin_strlenEfL0p_EmiLm4ELi1EEERAT__Kc Line | Count | Source | 889 | 18.7M | : StringRef(Str, N - 1) { | 890 | 18.7M | } |
_ZN4llvh13StringLiteralC2ILm3EEEUa9enable_ifIXeqclL_Z16__builtin_strlenEfL0p_EmiLm3ELi1EEERAT__Kc Line | Count | Source | 889 | 14.0M | : StringRef(Str, N - 1) { | 890 | 14.0M | } |
_ZN4llvh13StringLiteralC2ILm6EEEUa9enable_ifIXeqclL_Z16__builtin_strlenEfL0p_EmiLm6ELi1EEERAT__Kc Line | Count | Source | 889 | 42.1M | : StringRef(Str, N - 1) { | 890 | 42.1M | } |
_ZN4llvh13StringLiteralC2ILm7EEEUa9enable_ifIXeqclL_Z16__builtin_strlenEfL0p_EmiLm7ELi1EEERAT__Kc Line | Count | Source | 889 | 37.4M | : StringRef(Str, N - 1) { | 890 | 37.4M | } |
_ZN4llvh13StringLiteralC2ILm8EEEUa9enable_ifIXeqclL_Z16__builtin_strlenEfL0p_EmiLm8ELi1EEERAT__Kc Line | Count | Source | 889 | 23.4M | : StringRef(Str, N - 1) { | 890 | 23.4M | } |
_ZN4llvh13StringLiteralC2ILm9EEEUa9enable_ifIXeqclL_Z16__builtin_strlenEfL0p_EmiLm9ELi1EEERAT__Kc Line | Count | Source | 889 | 14.0M | : StringRef(Str, N - 1) { | 890 | 14.0M | } |
_ZN4llvh13StringLiteralC2ILm5EEEUa9enable_ifIXeqclL_Z16__builtin_strlenEfL0p_EmiLm5ELi1EEERAT__Kc Line | Count | Source | 889 | 37.4M | : StringRef(Str, N - 1) { | 890 | 37.4M | } |
_ZN4llvh13StringLiteralC2ILm11EEEUa9enable_ifIXeqclL_Z16__builtin_strlenEfL0p_EmiLm11ELi1EEERAT__Kc Line | Count | Source | 889 | 9.36M | : StringRef(Str, N - 1) { | 890 | 9.36M | } |
_ZN4llvh13StringLiteralC2ILm18EEEUa9enable_ifIXeqclL_Z16__builtin_strlenEfL0p_EmiLm18ELi1EEERAT__Kc Line | Count | Source | 889 | 23 | : StringRef(Str, N - 1) { | 890 | 23 | } |
_ZN4llvh13StringLiteralC2ILm10EEEUa9enable_ifIXeqclL_Z16__builtin_strlenEfL0p_EmiLm10ELi1EEERAT__Kc Line | Count | Source | 889 | 9.36M | : StringRef(Str, N - 1) { | 890 | 9.36M | } |
Unexecuted instantiation: _ZN4llvh13StringLiteralC2ILm15EEEUa9enable_ifIXeqclL_Z16__builtin_strlenEfL0p_EmiLm15ELi1EEERAT__Kc Unexecuted instantiation: _ZN4llvh13StringLiteralC2ILm12EEEUa9enable_ifIXeqclL_Z16__builtin_strlenEfL0p_EmiLm12ELi1EEERAT__Kc Unexecuted instantiation: _ZN4llvh13StringLiteralC2ILm13EEEUa9enable_ifIXeqclL_Z16__builtin_strlenEfL0p_EmiLm13ELi1EEERAT__Kc Unexecuted instantiation: _ZN4llvh13StringLiteralC2ILm14EEEUa9enable_ifIXeqclL_Z16__builtin_strlenEfL0p_EmiLm14ELi1EEERAT__Kc Unexecuted instantiation: _ZN4llvh13StringLiteralC2ILm1EEEUa9enable_ifIXeqclL_Z16__builtin_strlenEfL0p_EmiLm1ELi1EEERAT__Kc |
891 | | |
892 | | // Explicit construction for strings like "foo\0bar". |
893 | | template <size_t N> |
894 | | static constexpr StringLiteral withInnerNUL(const char (&Str)[N]) { |
895 | | return StringLiteral(Str, N - 1); |
896 | | } |
897 | | }; |
898 | | |
899 | | /// @name StringRef Comparison Operators |
900 | | /// @{ |
901 | | |
902 | | LLVM_ATTRIBUTE_ALWAYS_INLINE |
903 | 192M | inline bool operator==(StringRef LHS, StringRef RHS) { |
904 | 192M | return LHS.equals(RHS); |
905 | 192M | } |
906 | | |
907 | | LLVM_ATTRIBUTE_ALWAYS_INLINE |
908 | 0 | inline bool operator!=(StringRef LHS, StringRef RHS) { return !(LHS == RHS); } |
909 | | |
910 | 90.8k | inline bool operator<(StringRef LHS, StringRef RHS) { |
911 | 90.8k | return LHS.compare(RHS) == -1; |
912 | 90.8k | } |
913 | | |
914 | 0 | inline bool operator<=(StringRef LHS, StringRef RHS) { |
915 | 0 | return LHS.compare(RHS) != 1; |
916 | 0 | } |
917 | | |
918 | 0 | inline bool operator>(StringRef LHS, StringRef RHS) { |
919 | 0 | return LHS.compare(RHS) == 1; |
920 | 0 | } |
921 | | |
922 | 0 | inline bool operator>=(StringRef LHS, StringRef RHS) { |
923 | 0 | return LHS.compare(RHS) != -1; |
924 | 0 | } |
925 | | |
926 | 0 | inline std::string &operator+=(std::string &buffer, StringRef string) { |
927 | 0 | return buffer.append(string.data(), string.size()); |
928 | 0 | } |
929 | | |
930 | | /// @} |
931 | | |
932 | | /// Compute a hash_code for a StringRef. |
933 | | LLVM_NODISCARD |
934 | | hash_code hash_value(StringRef S); |
935 | | |
936 | | // StringRefs can be treated like a POD type. |
937 | | template <typename T> struct isPodLike; |
938 | | template <> struct isPodLike<StringRef> { static const bool value = true; }; |
939 | | |
940 | | } // end namespace llvh |
941 | | |
942 | | #pragma GCC diagnostic pop |
943 | | #endif // LLVM_ADT_STRINGREF_H |