00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #ifndef LLVM_ADT_STRINGREF_H
00011 #define LLVM_ADT_STRINGREF_H
00012
00013 #include <cassert>
00014 #include <cstring>
00015 #include <utility>
00016 #include <string>
00017
00018 namespace llvm {
00019 template<typename T>
00020 class SmallVectorImpl;
00021 class APInt;
00022
00030 class StringRef {
00031 public:
00032 typedef const char *iterator;
00033 typedef const char *const_iterator;
00034 static const size_t npos = ~size_t(0);
00035 typedef size_t size_type;
00036
00037 private:
00039 const char *Data;
00040
00042 size_t Length;
00043
00044
00045
00046
00047 static size_t min(size_t a, size_t b) { return a < b ? a : b; }
00048 static size_t max(size_t a, size_t b) { return a > b ? a : b; }
00049
00050
00051
00052 static int compareMemory(const char *Lhs, const char *Rhs, size_t Length) {
00053 if (Length == 0) { return 0; }
00054 return ::memcmp(Lhs,Rhs,Length);
00055 }
00056
00057 public:
00060
00062 StringRef() : Data(0), Length(0) {}
00063
00065 StringRef(const char *Str)
00066 : Data(Str) {
00067 assert(Str && "StringRef cannot be built from a NULL argument");
00068 Length = ::strlen(Str);
00069 }
00070
00072 StringRef(const char *data, size_t length)
00073 : Data(data), Length(length) {
00074 assert((data || length == 0) &&
00075 "StringRef cannot be built from a NULL argument with non-null length");
00076 }
00077
00079 StringRef(const std::string &Str)
00080 : Data(Str.data()), Length(Str.length()) {}
00081
00085
00086 iterator begin() const { return Data; }
00087
00088 iterator end() const { return Data + Length; }
00089
00093
00096 const char *data() const { return Data; }
00097
00099 bool empty() const { return Length == 0; }
00100
00102 size_t size() const { return Length; }
00103
00105 char front() const {
00106 assert(!empty());
00107 return Data[0];
00108 }
00109
00111 char back() const {
00112 assert(!empty());
00113 return Data[Length-1];
00114 }
00115
00118 bool equals(StringRef RHS) const {
00119 return (Length == RHS.Length &&
00120 compareMemory(Data, RHS.Data, RHS.Length) == 0);
00121 }
00122
00124 bool equals_lower(StringRef RHS) const {
00125 return Length == RHS.Length && compare_lower(RHS) == 0;
00126 }
00127
00130 int compare(StringRef RHS) const {
00131
00132 if (int Res = compareMemory(Data, RHS.Data, min(Length, RHS.Length)))
00133 return Res < 0 ? -1 : 1;
00134
00135
00136 if (Length == RHS.Length)
00137 return 0;
00138 return Length < RHS.Length ? -1 : 1;
00139 }
00140
00142 int compare_lower(StringRef RHS) const;
00143
00146 int compare_numeric(StringRef RHS) const;
00147
00166 unsigned edit_distance(StringRef Other, bool AllowReplacements = true,
00167 unsigned MaxEditDistance = 0);
00168
00170 std::string str() const {
00171 if (Data == 0) return std::string();
00172 return std::string(Data, Length);
00173 }
00174
00178
00179 char operator[](size_t Index) const {
00180 assert(Index < Length && "Invalid index!");
00181 return Data[Index];
00182 }
00183
00187
00188 operator std::string() const {
00189 return str();
00190 }
00191
00195
00197 bool startswith(StringRef Prefix) const {
00198 return Length >= Prefix.Length &&
00199 compareMemory(Data, Prefix.Data, Prefix.Length) == 0;
00200 }
00201
00203 bool endswith(StringRef Suffix) const {
00204 return Length >= Suffix.Length &&
00205 compareMemory(end() - Suffix.Length, Suffix.Data, Suffix.Length) == 0;
00206 }
00207
00211
00216 size_t find(char C, size_t From = 0) const {
00217 for (size_t i = min(From, Length), e = Length; i != e; ++i)
00218 if (Data[i] == C)
00219 return i;
00220 return npos;
00221 }
00222
00227 size_t find(StringRef Str, size_t From = 0) const;
00228
00233 size_t rfind(char C, size_t From = npos) const {
00234 From = min(From, Length);
00235 size_t i = From;
00236 while (i != 0) {
00237 --i;
00238 if (Data[i] == C)
00239 return i;
00240 }
00241 return npos;
00242 }
00243
00248 size_t rfind(StringRef Str) const;
00249
00252 size_type find_first_of(char C, size_t From = 0) const {
00253 return find(C, From);
00254 }
00255
00260 size_type find_first_of(StringRef Chars, size_t From = 0) const;
00261
00264 size_type find_first_not_of(char C, size_t From = 0) const;
00265
00270 size_type find_first_not_of(StringRef Chars, size_t From = 0) const;
00271
00274 size_type find_last_of(char C, size_t From = npos) const {
00275 return rfind(C, From);
00276 }
00277
00282 size_type find_last_of(StringRef Chars, size_t From = npos) const;
00283
00287
00289 size_t count(char C) const {
00290 size_t Count = 0;
00291 for (size_t i = 0, e = Length; i != e; ++i)
00292 if (Data[i] == C)
00293 ++Count;
00294 return Count;
00295 }
00296
00299 size_t count(StringRef Str) const;
00300
00309 bool getAsInteger(unsigned Radix, long long &Result) const;
00310 bool getAsInteger(unsigned Radix, unsigned long long &Result) const;
00311 bool getAsInteger(unsigned Radix, int &Result) const;
00312 bool getAsInteger(unsigned Radix, unsigned &Result) const;
00313
00314
00315
00327 bool getAsInteger(unsigned Radix, APInt &Result) const;
00328
00332
00342 StringRef substr(size_t Start, size_t N = npos) const {
00343 Start = min(Start, Length);
00344 return StringRef(Data + Start, min(N, Length - Start));
00345 }
00346
00357 StringRef slice(size_t Start, size_t End) const {
00358 Start = min(Start, Length);
00359 End = min(max(Start, End), Length);
00360 return StringRef(Data + Start, End - Start);
00361 }
00362
00373 std::pair<StringRef, StringRef> split(char Separator) const {
00374 size_t Idx = find(Separator);
00375 if (Idx == npos)
00376 return std::make_pair(*this, StringRef());
00377 return std::make_pair(slice(0, Idx), slice(Idx+1, npos));
00378 }
00379
00390 std::pair<StringRef, StringRef> split(StringRef Separator) const {
00391 size_t Idx = find(Separator);
00392 if (Idx == npos)
00393 return std::make_pair(*this, StringRef());
00394 return std::make_pair(slice(0, Idx), slice(Idx + Separator.size(), npos));
00395 }
00396
00412 void split(SmallVectorImpl<StringRef> &A,
00413 StringRef Separator, int MaxSplit = -1,
00414 bool KeepEmpty = true) const;
00415
00426 std::pair<StringRef, StringRef> rsplit(char Separator) const {
00427 size_t Idx = rfind(Separator);
00428 if (Idx == npos)
00429 return std::make_pair(*this, StringRef());
00430 return std::make_pair(slice(0, Idx), slice(Idx+1, npos));
00431 }
00432
00434 };
00435
00438
00439 inline bool operator==(StringRef LHS, StringRef RHS) {
00440 return LHS.equals(RHS);
00441 }
00442
00443 inline bool operator!=(StringRef LHS, StringRef RHS) {
00444 return !(LHS == RHS);
00445 }
00446
00447 inline bool operator<(StringRef LHS, StringRef RHS) {
00448 return LHS.compare(RHS) == -1;
00449 }
00450
00451 inline bool operator<=(StringRef LHS, StringRef RHS) {
00452 return LHS.compare(RHS) != 1;
00453 }
00454
00455 inline bool operator>(StringRef LHS, StringRef RHS) {
00456 return LHS.compare(RHS) == 1;
00457 }
00458
00459 inline bool operator>=(StringRef LHS, StringRef RHS) {
00460 return LHS.compare(RHS) != -1;
00461 }
00462
00463 inline std::string &operator+=(std::string &buffer, llvm::StringRef string) {
00464 return buffer.append(string.data(), string.size());
00465 }
00466
00468
00469
00470 template <typename T> struct isPodLike;
00471 template <> struct isPodLike<StringRef> { static const bool value = true; };
00472
00473 }
00474
00475 #endif