provide a "strtoull" operation that works on StringRef's.
[oota-llvm.git] / lib / Support / StringRef.cpp
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 "llvm/ADT/StringRef.h"
11 using namespace llvm;
12
13 const size_t StringRef::npos;
14
15 static bool GetAsUnsignedInteger(StringRef Str, unsigned Radix,
16                                  unsigned long long &Result) {
17   // Autosense radix if not specified.
18   if (Radix == 0) {
19     if (Str[0] != '0') {
20       Radix = 10;
21     } else {
22       if (Str.size() < 2) {
23         Radix = 8;
24       } else {
25         if (Str[1] == 'x') {
26           Str = Str.substr(2);
27           Radix = 16;
28         } else if (Str[1] == 'b') {
29           Str = Str.substr(2);
30           Radix = 2;
31         } else {
32           Radix = 8;
33         }
34       }
35     }
36   }
37   
38   // Empty strings (after the radix autosense) are invalid.
39   if (Str.empty()) return true;
40   
41   // Parse all the bytes of the string given this radix.  Watch for overflow.
42   Result = 0;
43   while (!Str.empty()) {
44     unsigned CharVal;
45     if (Str[0] >= '0' && Str[0] <= '9')
46       CharVal = Str[0]-'0';
47     else if (Str[0] >= 'a' && Str[0] <= 'z')
48       CharVal = Str[0]-'a'+10;
49     else if (Str[0] >= 'A' && Str[0] <= 'Z')
50       CharVal = Str[0]-'A'+10;
51     else
52       return true;
53     
54     // If the parsed value is larger than the integer radix, the string is
55     // invalid.
56     if (CharVal >= Radix)
57       return true;
58     
59     // Add in this character.
60     unsigned long long PrevResult = Result;
61     Result = Result*Radix+CharVal;
62     
63     // Check for overflow.
64     if (Result < PrevResult)
65       return true;
66
67     Str = Str.substr(1);
68   }
69   
70   return false;
71 }
72
73 bool StringRef::getAsInteger(unsigned Radix, unsigned long long &Result) const {
74   return GetAsUnsignedInteger(*this, Radix, Result);
75 }
76