/src/hermes/external/llvh/lib/Support/StringRef.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | //===-- StringRef.cpp - Lightweight String References ---------------------===// |
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 | | #include "llvh/ADT/StringRef.h" |
11 | | #include "llvh/ADT/APFloat.h" |
12 | | #include "llvh/ADT/APInt.h" |
13 | | #include "llvh/ADT/Hashing.h" |
14 | | #include "llvh/ADT/StringExtras.h" |
15 | | #include "llvh/ADT/edit_distance.h" |
16 | | #include <bitset> |
17 | | |
18 | | using namespace llvh; |
19 | | |
20 | | // MSVC emits references to this into the translation units which reference it. |
21 | | #ifndef _MSC_VER |
22 | | const size_t StringRef::npos; |
23 | | #endif |
24 | | |
25 | | // strncasecmp() is not available on non-POSIX systems, so define an |
26 | | // alternative function here. |
27 | 0 | static int ascii_strncasecmp(const char *LHS, const char *RHS, size_t Length) { |
28 | 0 | for (size_t I = 0; I < Length; ++I) { |
29 | 0 | unsigned char LHC = toLower(LHS[I]); |
30 | 0 | unsigned char RHC = toLower(RHS[I]); |
31 | 0 | if (LHC != RHC) |
32 | 0 | return LHC < RHC ? -1 : 1; |
33 | 0 | } |
34 | 0 | return 0; |
35 | 0 | } |
36 | | |
37 | | /// compare_lower - Compare strings, ignoring case. |
38 | 0 | int StringRef::compare_lower(StringRef RHS) const { |
39 | 0 | if (int Res = ascii_strncasecmp(Data, RHS.Data, std::min(Length, RHS.Length))) |
40 | 0 | return Res; |
41 | 0 | if (Length == RHS.Length) |
42 | 0 | return 0; |
43 | 0 | return Length < RHS.Length ? -1 : 1; |
44 | 0 | } |
45 | | |
46 | | /// Check if this string starts with the given \p Prefix, ignoring case. |
47 | 0 | bool StringRef::startswith_lower(StringRef Prefix) const { |
48 | 0 | return Length >= Prefix.Length && |
49 | 0 | ascii_strncasecmp(Data, Prefix.Data, Prefix.Length) == 0; |
50 | 0 | } |
51 | | |
52 | | /// Check if this string ends with the given \p Suffix, ignoring case. |
53 | 0 | bool StringRef::endswith_lower(StringRef Suffix) const { |
54 | 0 | return Length >= Suffix.Length && |
55 | 0 | ascii_strncasecmp(end() - Suffix.Length, Suffix.Data, Suffix.Length) == 0; |
56 | 0 | } |
57 | | |
58 | 0 | size_t StringRef::find_lower(char C, size_t From) const { |
59 | 0 | char L = toLower(C); |
60 | 0 | return find_if([L](char D) { return toLower(D) == L; }, From); |
61 | 0 | } |
62 | | |
63 | | /// compare_numeric - Compare strings, handle embedded numbers. |
64 | 0 | int StringRef::compare_numeric(StringRef RHS) const { |
65 | 0 | for (size_t I = 0, E = std::min(Length, RHS.Length); I != E; ++I) { |
66 | | // Check for sequences of digits. |
67 | 0 | if (isDigit(Data[I]) && isDigit(RHS.Data[I])) { |
68 | | // The longer sequence of numbers is considered larger. |
69 | | // This doesn't really handle prefixed zeros well. |
70 | 0 | size_t J; |
71 | 0 | for (J = I + 1; J != E + 1; ++J) { |
72 | 0 | bool ld = J < Length && isDigit(Data[J]); |
73 | 0 | bool rd = J < RHS.Length && isDigit(RHS.Data[J]); |
74 | 0 | if (ld != rd) |
75 | 0 | return rd ? -1 : 1; |
76 | 0 | if (!rd) |
77 | 0 | break; |
78 | 0 | } |
79 | | // The two number sequences have the same length (J-I), just memcmp them. |
80 | 0 | if (int Res = compareMemory(Data + I, RHS.Data + I, J - I)) |
81 | 0 | return Res < 0 ? -1 : 1; |
82 | | // Identical number sequences, continue search after the numbers. |
83 | 0 | I = J - 1; |
84 | 0 | continue; |
85 | 0 | } |
86 | 0 | if (Data[I] != RHS.Data[I]) |
87 | 0 | return (unsigned char)Data[I] < (unsigned char)RHS.Data[I] ? -1 : 1; |
88 | 0 | } |
89 | 0 | if (Length == RHS.Length) |
90 | 0 | return 0; |
91 | 0 | return Length < RHS.Length ? -1 : 1; |
92 | 0 | } |
93 | | |
94 | | // Compute the edit distance between the two given strings. |
95 | | unsigned StringRef::edit_distance(llvh::StringRef Other, |
96 | | bool AllowReplacements, |
97 | 0 | unsigned MaxEditDistance) const { |
98 | 0 | return llvh::ComputeEditDistance( |
99 | 0 | makeArrayRef(data(), size()), |
100 | 0 | makeArrayRef(Other.data(), Other.size()), |
101 | 0 | AllowReplacements, MaxEditDistance); |
102 | 0 | } |
103 | | |
104 | | //===----------------------------------------------------------------------===// |
105 | | // String Operations |
106 | | //===----------------------------------------------------------------------===// |
107 | | |
108 | 0 | std::string StringRef::lower() const { |
109 | 0 | std::string Result(size(), char()); |
110 | 0 | for (size_type i = 0, e = size(); i != e; ++i) { |
111 | 0 | Result[i] = toLower(Data[i]); |
112 | 0 | } |
113 | 0 | return Result; |
114 | 0 | } |
115 | | |
116 | 0 | std::string StringRef::upper() const { |
117 | 0 | std::string Result(size(), char()); |
118 | 0 | for (size_type i = 0, e = size(); i != e; ++i) { |
119 | 0 | Result[i] = toUpper(Data[i]); |
120 | 0 | } |
121 | 0 | return Result; |
122 | 0 | } |
123 | | |
124 | | //===----------------------------------------------------------------------===// |
125 | | // String Searching |
126 | | //===----------------------------------------------------------------------===// |
127 | | |
128 | | |
129 | | /// find - Search for the first string \arg Str in the string. |
130 | | /// |
131 | | /// \return - The index of the first occurrence of \arg Str, or npos if not |
132 | | /// found. |
133 | 0 | size_t StringRef::find(StringRef Str, size_t From) const { |
134 | 0 | if (From > Length) |
135 | 0 | return npos; |
136 | | |
137 | 0 | const char *Start = Data + From; |
138 | 0 | size_t Size = Length - From; |
139 | |
|
140 | 0 | const char *Needle = Str.data(); |
141 | 0 | size_t N = Str.size(); |
142 | 0 | if (N == 0) |
143 | 0 | return From; |
144 | 0 | if (Size < N) |
145 | 0 | return npos; |
146 | 0 | if (N == 1) { |
147 | 0 | const char *Ptr = (const char *)::memchr(Start, Needle[0], Size); |
148 | 0 | return Ptr == nullptr ? npos : Ptr - Data; |
149 | 0 | } |
150 | | |
151 | 0 | const char *Stop = Start + (Size - N + 1); |
152 | | |
153 | | // For short haystacks or unsupported needles fall back to the naive algorithm |
154 | 0 | if (Size < 16 || N > 255) { |
155 | 0 | do { |
156 | 0 | if (std::memcmp(Start, Needle, N) == 0) |
157 | 0 | return Start - Data; |
158 | 0 | ++Start; |
159 | 0 | } while (Start < Stop); |
160 | 0 | return npos; |
161 | 0 | } |
162 | | |
163 | | // Build the bad char heuristic table, with uint8_t to reduce cache thrashing. |
164 | 0 | uint8_t BadCharSkip[256]; |
165 | 0 | std::memset(BadCharSkip, N, 256); |
166 | 0 | for (unsigned i = 0; i != N-1; ++i) |
167 | 0 | BadCharSkip[(uint8_t)Str[i]] = N-1-i; |
168 | |
|
169 | 0 | do { |
170 | 0 | uint8_t Last = Start[N - 1]; |
171 | 0 | if (LLVM_UNLIKELY(Last == (uint8_t)Needle[N - 1])) |
172 | 0 | if (std::memcmp(Start, Needle, N - 1) == 0) |
173 | 0 | return Start - Data; |
174 | | |
175 | | // Otherwise skip the appropriate number of bytes. |
176 | 0 | Start += BadCharSkip[Last]; |
177 | 0 | } while (Start < Stop); |
178 | | |
179 | 0 | return npos; |
180 | 0 | } |
181 | | |
182 | 0 | size_t StringRef::find_lower(StringRef Str, size_t From) const { |
183 | 0 | StringRef This = substr(From); |
184 | 0 | while (This.size() >= Str.size()) { |
185 | 0 | if (This.startswith_lower(Str)) |
186 | 0 | return From; |
187 | 0 | This = This.drop_front(); |
188 | 0 | ++From; |
189 | 0 | } |
190 | 0 | return npos; |
191 | 0 | } |
192 | | |
193 | 0 | size_t StringRef::rfind_lower(char C, size_t From) const { |
194 | 0 | From = std::min(From, Length); |
195 | 0 | size_t i = From; |
196 | 0 | while (i != 0) { |
197 | 0 | --i; |
198 | 0 | if (toLower(Data[i]) == toLower(C)) |
199 | 0 | return i; |
200 | 0 | } |
201 | 0 | return npos; |
202 | 0 | } |
203 | | |
204 | | /// rfind - Search for the last string \arg Str in the string. |
205 | | /// |
206 | | /// \return - The index of the last occurrence of \arg Str, or npos if not |
207 | | /// found. |
208 | 0 | size_t StringRef::rfind(StringRef Str) const { |
209 | 0 | size_t N = Str.size(); |
210 | 0 | if (N > Length) |
211 | 0 | return npos; |
212 | 0 | for (size_t i = Length - N + 1, e = 0; i != e;) { |
213 | 0 | --i; |
214 | 0 | if (substr(i, N).equals(Str)) |
215 | 0 | return i; |
216 | 0 | } |
217 | 0 | return npos; |
218 | 0 | } |
219 | | |
220 | 0 | size_t StringRef::rfind_lower(StringRef Str) const { |
221 | 0 | size_t N = Str.size(); |
222 | 0 | if (N > Length) |
223 | 0 | return npos; |
224 | 0 | for (size_t i = Length - N + 1, e = 0; i != e;) { |
225 | 0 | --i; |
226 | 0 | if (substr(i, N).equals_lower(Str)) |
227 | 0 | return i; |
228 | 0 | } |
229 | 0 | return npos; |
230 | 0 | } |
231 | | |
232 | | /// find_first_of - Find the first character in the string that is in \arg |
233 | | /// Chars, or npos if not found. |
234 | | /// |
235 | | /// Note: O(size() + Chars.size()) |
236 | | StringRef::size_type StringRef::find_first_of(StringRef Chars, |
237 | 0 | size_t From) const { |
238 | 0 | std::bitset<1 << CHAR_BIT> CharBits; |
239 | 0 | for (size_type i = 0; i != Chars.size(); ++i) |
240 | 0 | CharBits.set((unsigned char)Chars[i]); |
241 | |
|
242 | 0 | for (size_type i = std::min(From, Length), e = Length; i != e; ++i) |
243 | 0 | if (CharBits.test((unsigned char)Data[i])) |
244 | 0 | return i; |
245 | 0 | return npos; |
246 | 0 | } |
247 | | |
248 | | /// find_first_not_of - Find the first character in the string that is not |
249 | | /// \arg C or npos if not found. |
250 | 0 | StringRef::size_type StringRef::find_first_not_of(char C, size_t From) const { |
251 | 0 | for (size_type i = std::min(From, Length), e = Length; i != e; ++i) |
252 | 0 | if (Data[i] != C) |
253 | 0 | return i; |
254 | 0 | return npos; |
255 | 0 | } |
256 | | |
257 | | /// find_first_not_of - Find the first character in the string that is not |
258 | | /// in the string \arg Chars, or npos if not found. |
259 | | /// |
260 | | /// Note: O(size() + Chars.size()) |
261 | | StringRef::size_type StringRef::find_first_not_of(StringRef Chars, |
262 | 0 | size_t From) const { |
263 | 0 | std::bitset<1 << CHAR_BIT> CharBits; |
264 | 0 | for (size_type i = 0; i != Chars.size(); ++i) |
265 | 0 | CharBits.set((unsigned char)Chars[i]); |
266 | |
|
267 | 0 | for (size_type i = std::min(From, Length), e = Length; i != e; ++i) |
268 | 0 | if (!CharBits.test((unsigned char)Data[i])) |
269 | 0 | return i; |
270 | 0 | return npos; |
271 | 0 | } |
272 | | |
273 | | /// find_last_of - Find the last character in the string that is in \arg C, |
274 | | /// or npos if not found. |
275 | | /// |
276 | | /// Note: O(size() + Chars.size()) |
277 | | StringRef::size_type StringRef::find_last_of(StringRef Chars, |
278 | 0 | size_t From) const { |
279 | 0 | std::bitset<1 << CHAR_BIT> CharBits; |
280 | 0 | for (size_type i = 0; i != Chars.size(); ++i) |
281 | 0 | CharBits.set((unsigned char)Chars[i]); |
282 | |
|
283 | 0 | for (size_type i = std::min(From, Length) - 1, e = -1; i != e; --i) |
284 | 0 | if (CharBits.test((unsigned char)Data[i])) |
285 | 0 | return i; |
286 | 0 | return npos; |
287 | 0 | } |
288 | | |
289 | | /// find_last_not_of - Find the last character in the string that is not |
290 | | /// \arg C, or npos if not found. |
291 | 0 | StringRef::size_type StringRef::find_last_not_of(char C, size_t From) const { |
292 | 0 | for (size_type i = std::min(From, Length) - 1, e = -1; i != e; --i) |
293 | 0 | if (Data[i] != C) |
294 | 0 | return i; |
295 | 0 | return npos; |
296 | 0 | } |
297 | | |
298 | | /// find_last_not_of - Find the last character in the string that is not in |
299 | | /// \arg Chars, or npos if not found. |
300 | | /// |
301 | | /// Note: O(size() + Chars.size()) |
302 | | StringRef::size_type StringRef::find_last_not_of(StringRef Chars, |
303 | 0 | size_t From) const { |
304 | 0 | std::bitset<1 << CHAR_BIT> CharBits; |
305 | 0 | for (size_type i = 0, e = Chars.size(); i != e; ++i) |
306 | 0 | CharBits.set((unsigned char)Chars[i]); |
307 | |
|
308 | 0 | for (size_type i = std::min(From, Length) - 1, e = -1; i != e; --i) |
309 | 0 | if (!CharBits.test((unsigned char)Data[i])) |
310 | 0 | return i; |
311 | 0 | return npos; |
312 | 0 | } |
313 | | |
314 | | void StringRef::split(SmallVectorImpl<StringRef> &A, |
315 | | StringRef Separator, int MaxSplit, |
316 | 0 | bool KeepEmpty) const { |
317 | 0 | StringRef S = *this; |
318 | | |
319 | | // Count down from MaxSplit. When MaxSplit is -1, this will just split |
320 | | // "forever". This doesn't support splitting more than 2^31 times |
321 | | // intentionally; if we ever want that we can make MaxSplit a 64-bit integer |
322 | | // but that seems unlikely to be useful. |
323 | 0 | while (MaxSplit-- != 0) { |
324 | 0 | size_t Idx = S.find(Separator); |
325 | 0 | if (Idx == npos) |
326 | 0 | break; |
327 | | |
328 | | // Push this split. |
329 | 0 | if (KeepEmpty || Idx > 0) |
330 | 0 | A.push_back(S.slice(0, Idx)); |
331 | | |
332 | | // Jump forward. |
333 | 0 | S = S.slice(Idx + Separator.size(), npos); |
334 | 0 | } |
335 | | |
336 | | // Push the tail. |
337 | 0 | if (KeepEmpty || !S.empty()) |
338 | 0 | A.push_back(S); |
339 | 0 | } |
340 | | |
341 | | void StringRef::split(SmallVectorImpl<StringRef> &A, char Separator, |
342 | 0 | int MaxSplit, bool KeepEmpty) const { |
343 | 0 | StringRef S = *this; |
344 | | |
345 | | // Count down from MaxSplit. When MaxSplit is -1, this will just split |
346 | | // "forever". This doesn't support splitting more than 2^31 times |
347 | | // intentionally; if we ever want that we can make MaxSplit a 64-bit integer |
348 | | // but that seems unlikely to be useful. |
349 | 0 | while (MaxSplit-- != 0) { |
350 | 0 | size_t Idx = S.find(Separator); |
351 | 0 | if (Idx == npos) |
352 | 0 | break; |
353 | | |
354 | | // Push this split. |
355 | 0 | if (KeepEmpty || Idx > 0) |
356 | 0 | A.push_back(S.slice(0, Idx)); |
357 | | |
358 | | // Jump forward. |
359 | 0 | S = S.slice(Idx + 1, npos); |
360 | 0 | } |
361 | | |
362 | | // Push the tail. |
363 | 0 | if (KeepEmpty || !S.empty()) |
364 | 0 | A.push_back(S); |
365 | 0 | } |
366 | | |
367 | | //===----------------------------------------------------------------------===// |
368 | | // Helpful Algorithms |
369 | | //===----------------------------------------------------------------------===// |
370 | | |
371 | | /// count - Return the number of non-overlapped occurrences of \arg Str in |
372 | | /// the string. |
373 | 0 | size_t StringRef::count(StringRef Str) const { |
374 | 0 | size_t Count = 0; |
375 | 0 | size_t N = Str.size(); |
376 | 0 | if (N > Length) |
377 | 0 | return 0; |
378 | 0 | for (size_t i = 0, e = Length - N + 1; i != e; ++i) |
379 | 0 | if (substr(i, N).equals(Str)) |
380 | 0 | ++Count; |
381 | 0 | return Count; |
382 | 0 | } |
383 | | |
384 | 0 | static unsigned GetAutoSenseRadix(StringRef &Str) { |
385 | 0 | if (Str.empty()) |
386 | 0 | return 10; |
387 | | |
388 | 0 | if (Str.startswith("0x") || Str.startswith("0X")) { |
389 | 0 | Str = Str.substr(2); |
390 | 0 | return 16; |
391 | 0 | } |
392 | | |
393 | 0 | if (Str.startswith("0b") || Str.startswith("0B")) { |
394 | 0 | Str = Str.substr(2); |
395 | 0 | return 2; |
396 | 0 | } |
397 | | |
398 | 0 | if (Str.startswith("0o")) { |
399 | 0 | Str = Str.substr(2); |
400 | 0 | return 8; |
401 | 0 | } |
402 | | |
403 | 0 | if (Str[0] == '0' && Str.size() > 1 && isDigit(Str[1])) { |
404 | 0 | Str = Str.substr(1); |
405 | 0 | return 8; |
406 | 0 | } |
407 | | |
408 | 0 | return 10; |
409 | 0 | } |
410 | | |
411 | | bool llvh::consumeUnsignedInteger(StringRef &Str, unsigned Radix, |
412 | 0 | unsigned long long &Result) { |
413 | | // Autosense radix if not specified. |
414 | 0 | if (Radix == 0) |
415 | 0 | Radix = GetAutoSenseRadix(Str); |
416 | | |
417 | | // Empty strings (after the radix autosense) are invalid. |
418 | 0 | if (Str.empty()) return true; |
419 | | |
420 | | // Parse all the bytes of the string given this radix. Watch for overflow. |
421 | 0 | StringRef Str2 = Str; |
422 | 0 | Result = 0; |
423 | 0 | while (!Str2.empty()) { |
424 | 0 | unsigned CharVal; |
425 | 0 | if (Str2[0] >= '0' && Str2[0] <= '9') |
426 | 0 | CharVal = Str2[0] - '0'; |
427 | 0 | else if (Str2[0] >= 'a' && Str2[0] <= 'z') |
428 | 0 | CharVal = Str2[0] - 'a' + 10; |
429 | 0 | else if (Str2[0] >= 'A' && Str2[0] <= 'Z') |
430 | 0 | CharVal = Str2[0] - 'A' + 10; |
431 | 0 | else |
432 | 0 | break; |
433 | | |
434 | | // If the parsed value is larger than the integer radix, we cannot |
435 | | // consume any more characters. |
436 | 0 | if (CharVal >= Radix) |
437 | 0 | break; |
438 | | |
439 | | // Add in this character. |
440 | 0 | unsigned long long PrevResult = Result; |
441 | 0 | Result = Result * Radix + CharVal; |
442 | | |
443 | | // Check for overflow by shifting back and seeing if bits were lost. |
444 | 0 | if (Result / Radix < PrevResult) |
445 | 0 | return true; |
446 | | |
447 | 0 | Str2 = Str2.substr(1); |
448 | 0 | } |
449 | | |
450 | | // We consider the operation a failure if no characters were consumed |
451 | | // successfully. |
452 | 0 | if (Str.size() == Str2.size()) |
453 | 0 | return true; |
454 | | |
455 | 0 | Str = Str2; |
456 | 0 | return false; |
457 | 0 | } |
458 | | |
459 | | bool llvh::consumeSignedInteger(StringRef &Str, unsigned Radix, |
460 | 0 | long long &Result) { |
461 | 0 | unsigned long long ULLVal; |
462 | | |
463 | | // Handle positive strings first. |
464 | 0 | if (Str.empty() || Str.front() != '-') { |
465 | 0 | if (consumeUnsignedInteger(Str, Radix, ULLVal) || |
466 | | // Check for value so large it overflows a signed value. |
467 | 0 | (long long)ULLVal < 0) |
468 | 0 | return true; |
469 | 0 | Result = ULLVal; |
470 | 0 | return false; |
471 | 0 | } |
472 | | |
473 | | // Get the positive part of the value. |
474 | 0 | StringRef Str2 = Str.drop_front(1); |
475 | 0 | if (consumeUnsignedInteger(Str2, Radix, ULLVal) || |
476 | | // Reject values so large they'd overflow as negative signed, but allow |
477 | | // "-0". This negates the unsigned so that the negative isn't undefined |
478 | | // on signed overflow. |
479 | 0 | (long long)-ULLVal > 0) |
480 | 0 | return true; |
481 | | |
482 | 0 | Str = Str2; |
483 | 0 | Result = -ULLVal; |
484 | 0 | return false; |
485 | 0 | } |
486 | | |
487 | | /// GetAsUnsignedInteger - Workhorse method that converts a integer character |
488 | | /// sequence of radix up to 36 to an unsigned long long value. |
489 | | bool llvh::getAsUnsignedInteger(StringRef Str, unsigned Radix, |
490 | 0 | unsigned long long &Result) { |
491 | 0 | if (consumeUnsignedInteger(Str, Radix, Result)) |
492 | 0 | return true; |
493 | | |
494 | | // For getAsUnsignedInteger, we require the whole string to be consumed or |
495 | | // else we consider it a failure. |
496 | 0 | return !Str.empty(); |
497 | 0 | } |
498 | | |
499 | | bool llvh::getAsSignedInteger(StringRef Str, unsigned Radix, |
500 | 0 | long long &Result) { |
501 | 0 | if (consumeSignedInteger(Str, Radix, Result)) |
502 | 0 | return true; |
503 | | |
504 | | // For getAsSignedInteger, we require the whole string to be consumed or else |
505 | | // we consider it a failure. |
506 | 0 | return !Str.empty(); |
507 | 0 | } |
508 | | |
509 | 0 | bool StringRef::getAsInteger(unsigned Radix, APInt &Result) const { |
510 | 0 | StringRef Str = *this; |
511 | | |
512 | | // Autosense radix if not specified. |
513 | 0 | if (Radix == 0) |
514 | 0 | Radix = GetAutoSenseRadix(Str); |
515 | |
|
516 | 0 | assert(Radix > 1 && Radix <= 36); |
517 | | |
518 | | // Empty strings (after the radix autosense) are invalid. |
519 | 0 | if (Str.empty()) return true; |
520 | | |
521 | | // Skip leading zeroes. This can be a significant improvement if |
522 | | // it means we don't need > 64 bits. |
523 | 0 | while (!Str.empty() && Str.front() == '0') |
524 | 0 | Str = Str.substr(1); |
525 | | |
526 | | // If it was nothing but zeroes.... |
527 | 0 | if (Str.empty()) { |
528 | 0 | Result = APInt(64, 0); |
529 | 0 | return false; |
530 | 0 | } |
531 | | |
532 | | // (Over-)estimate the required number of bits. |
533 | 0 | unsigned Log2Radix = 0; |
534 | 0 | while ((1U << Log2Radix) < Radix) Log2Radix++; |
535 | 0 | bool IsPowerOf2Radix = ((1U << Log2Radix) == Radix); |
536 | |
|
537 | 0 | unsigned BitWidth = Log2Radix * Str.size(); |
538 | 0 | if (BitWidth < Result.getBitWidth()) |
539 | 0 | BitWidth = Result.getBitWidth(); // don't shrink the result |
540 | 0 | else if (BitWidth > Result.getBitWidth()) |
541 | 0 | Result = Result.zext(BitWidth); |
542 | |
|
543 | 0 | APInt RadixAP, CharAP; // unused unless !IsPowerOf2Radix |
544 | 0 | if (!IsPowerOf2Radix) { |
545 | | // These must have the same bit-width as Result. |
546 | 0 | RadixAP = APInt(BitWidth, Radix); |
547 | 0 | CharAP = APInt(BitWidth, 0); |
548 | 0 | } |
549 | | |
550 | | // Parse all the bytes of the string given this radix. |
551 | 0 | Result = 0; |
552 | 0 | while (!Str.empty()) { |
553 | 0 | unsigned CharVal; |
554 | 0 | if (Str[0] >= '0' && Str[0] <= '9') |
555 | 0 | CharVal = Str[0]-'0'; |
556 | 0 | else if (Str[0] >= 'a' && Str[0] <= 'z') |
557 | 0 | CharVal = Str[0]-'a'+10; |
558 | 0 | else if (Str[0] >= 'A' && Str[0] <= 'Z') |
559 | 0 | CharVal = Str[0]-'A'+10; |
560 | 0 | else |
561 | 0 | return true; |
562 | | |
563 | | // If the parsed value is larger than the integer radix, the string is |
564 | | // invalid. |
565 | 0 | if (CharVal >= Radix) |
566 | 0 | return true; |
567 | | |
568 | | // Add in this character. |
569 | 0 | if (IsPowerOf2Radix) { |
570 | 0 | Result <<= Log2Radix; |
571 | 0 | Result |= CharVal; |
572 | 0 | } else { |
573 | 0 | Result *= RadixAP; |
574 | 0 | CharAP = CharVal; |
575 | 0 | Result += CharAP; |
576 | 0 | } |
577 | |
|
578 | 0 | Str = Str.substr(1); |
579 | 0 | } |
580 | | |
581 | 0 | return false; |
582 | 0 | } |
583 | | |
584 | 0 | bool StringRef::getAsDouble(double &Result, bool AllowInexact) const { |
585 | 0 | APFloat F(0.0); |
586 | 0 | APFloat::opStatus Status = |
587 | 0 | F.convertFromString(*this, APFloat::rmNearestTiesToEven); |
588 | 0 | if (Status != APFloat::opOK) { |
589 | 0 | if (!AllowInexact || !(Status & APFloat::opInexact)) |
590 | 0 | return true; |
591 | 0 | } |
592 | | |
593 | 0 | Result = F.convertToDouble(); |
594 | 0 | return false; |
595 | 0 | } |
596 | | |
597 | | // Implementation of StringRef hashing. |
598 | 4.30M | hash_code llvh::hash_value(StringRef S) { |
599 | 4.30M | return hash_combine_range(S.begin(), S.end()); |
600 | 4.30M | } |