Use StringRef::min instead of std::min.
[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 // MSVC emits references to this into the translation units which reference it.
14 #ifndef _MSC_VER
15 const size_t StringRef::npos;
16 #endif
17
18 static char ascii_tolower(char x) {
19   if (x >= 'A' && x <= 'Z')
20     return x - 'A' + 'a';
21   return x;
22 }
23
24 /// compare_lower - Compare strings, ignoring case.
25 int StringRef::compare_lower(StringRef RHS) const {
26   for (size_t I = 0, E = min(Length, RHS.Length); I != E; ++I) {
27     char LHC = ascii_tolower(Data[I]);
28     char RHC = ascii_tolower(RHS.Data[I]);
29     if (LHC != RHC)
30       return LHC < RHC ? -1 : 1;
31   }
32
33   if (Length == RHS.Length)
34         return 0;
35   return Length < RHS.Length ? -1 : 1;
36 }
37
38 //===----------------------------------------------------------------------===//
39 // String Searching
40 //===----------------------------------------------------------------------===//
41
42
43 /// find - Search for the first string \arg Str in the string.
44 ///
45 /// \return - The index of the first occurence of \arg Str, or npos if not
46 /// found.
47 size_t StringRef::find(StringRef Str, size_t From) const {
48   size_t N = Str.size();
49   if (N > Length)
50     return npos;
51   for (size_t e = Length - N + 1, i = min(From, e); i != e; ++i)
52     if (substr(i, N).equals(Str))
53       return i;
54   return npos;
55 }
56
57 /// rfind - Search for the last string \arg Str in the string.
58 ///
59 /// \return - The index of the last occurence of \arg Str, or npos if not
60 /// found.
61 size_t StringRef::rfind(StringRef Str) const {
62   size_t N = Str.size();
63   if (N > Length)
64     return npos;
65   for (size_t i = Length - N + 1, e = 0; i != e;) {
66     --i;
67     if (substr(i, N).equals(Str))
68       return i;
69   }
70   return npos;
71 }
72
73 /// find_first_of - Find the first character in the string that is in \arg
74 /// Chars, or npos if not found.
75 ///
76 /// Note: O(size() * Chars.size())
77 StringRef::size_type StringRef::find_first_of(StringRef Chars,
78                                               size_t From) const {
79   for (size_type i = min(From, Length), e = Length; i != e; ++i)
80     if (Chars.find(Data[i]) != npos)
81       return i;
82   return npos;
83 }
84
85 /// find_first_not_of - Find the first character in the string that is not
86 /// \arg C or npos if not found.
87 StringRef::size_type StringRef::find_first_not_of(char C, size_t From) const {
88   for (size_type i = min(From, Length), e = Length; i != e; ++i)
89     if (Data[i] != C)
90       return i;
91   return npos;
92 }
93
94 /// find_first_not_of - Find the first character in the string that is not
95 /// in the string \arg Chars, or npos if not found.
96 ///
97 /// Note: O(size() * Chars.size())
98 StringRef::size_type StringRef::find_first_not_of(StringRef Chars,
99                                                   size_t From) const {
100   for (size_type i = min(From, Length), e = Length; i != e; ++i)
101     if (Chars.find(Data[i]) == npos)
102       return i;
103   return npos;
104 }
105
106
107 //===----------------------------------------------------------------------===//
108 // Helpful Algorithms
109 //===----------------------------------------------------------------------===//
110
111 /// count - Return the number of non-overlapped occurrences of \arg Str in
112 /// the string.
113 size_t StringRef::count(StringRef Str) const {
114   size_t Count = 0;
115   size_t N = Str.size();
116   if (N > Length)
117     return 0;
118   for (size_t i = 0, e = Length - N + 1; i != e; ++i)
119     if (substr(i, N).equals(Str))
120       ++Count;
121   return Count;
122 }
123
124 /// GetAsUnsignedInteger - Workhorse method that converts a integer character
125 /// sequence of radix up to 36 to an unsigned long long value.
126 static bool GetAsUnsignedInteger(StringRef Str, unsigned Radix,
127                                  unsigned long long &Result) {
128   // Autosense radix if not specified.
129   if (Radix == 0) {
130     if (Str.startswith("0x")) {
131       Str = Str.substr(2);
132       Radix = 16;
133     } else if (Str.startswith("0b")) {
134       Str = Str.substr(2);
135       Radix = 2;
136     } else if (Str.startswith("0"))
137       Radix = 8;
138     else
139       Radix = 10;
140   }
141   
142   // Empty strings (after the radix autosense) are invalid.
143   if (Str.empty()) return true;
144   
145   // Parse all the bytes of the string given this radix.  Watch for overflow.
146   Result = 0;
147   while (!Str.empty()) {
148     unsigned CharVal;
149     if (Str[0] >= '0' && Str[0] <= '9')
150       CharVal = Str[0]-'0';
151     else if (Str[0] >= 'a' && Str[0] <= 'z')
152       CharVal = Str[0]-'a'+10;
153     else if (Str[0] >= 'A' && Str[0] <= 'Z')
154       CharVal = Str[0]-'A'+10;
155     else
156       return true;
157     
158     // If the parsed value is larger than the integer radix, the string is
159     // invalid.
160     if (CharVal >= Radix)
161       return true;
162     
163     // Add in this character.
164     unsigned long long PrevResult = Result;
165     Result = Result*Radix+CharVal;
166     
167     // Check for overflow.
168     if (Result < PrevResult)
169       return true;
170
171     Str = Str.substr(1);
172   }
173   
174   return false;
175 }
176
177 bool StringRef::getAsInteger(unsigned Radix, unsigned long long &Result) const {
178   return GetAsUnsignedInteger(*this, Radix, Result);
179 }
180
181
182 bool StringRef::getAsInteger(unsigned Radix, long long &Result) const {
183   unsigned long long ULLVal;
184   
185   // Handle positive strings first.
186   if (empty() || front() != '-') {
187     if (GetAsUnsignedInteger(*this, Radix, ULLVal) ||
188         // Check for value so large it overflows a signed value.
189         (long long)ULLVal < 0)
190       return true;
191     Result = ULLVal;
192     return false;
193   }
194   
195   // Get the positive part of the value.
196   if (GetAsUnsignedInteger(substr(1), Radix, ULLVal) ||
197       // Reject values so large they'd overflow as negative signed, but allow
198       // "-0".  This negates the unsigned so that the negative isn't undefined
199       // on signed overflow.
200       (long long)-ULLVal > 0)
201     return true;
202   
203   Result = -ULLVal;
204   return false;
205 }
206
207 bool StringRef::getAsInteger(unsigned Radix, int &Result) const {
208   long long Val;
209   if (getAsInteger(Radix, Val) ||
210       (int)Val != Val)
211     return true;
212   Result = Val;
213   return false;
214 }
215
216 bool StringRef::getAsInteger(unsigned Radix, unsigned &Result) const {
217   unsigned long long Val;
218   if (getAsInteger(Radix, Val) ||
219       (unsigned)Val != Val)
220     return true;
221   Result = Val;
222   return false;
223 }