StringRef.h revision 198396
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 10#ifndef LLVM_ADT_STRINGREF_H 11#define LLVM_ADT_STRINGREF_H 12 13#include <algorithm> 14#include <cassert> 15#include <cstring> 16#include <string> 17 18namespace llvm { 19 20 /// StringRef - Represent a constant reference to a string, i.e. a character 21 /// array and a length, which need not be null terminated. 22 /// 23 /// This class does not own the string data, it is expected to be used in 24 /// situations where the character data resides in some other buffer, whose 25 /// lifetime extends past that of the StringRef. For this reason, it is not in 26 /// general safe to store a StringRef. 27 class StringRef { 28 public: 29 typedef const char *iterator; 30 static const size_t npos = ~size_t(0); 31 typedef size_t size_type; 32 33 private: 34 /// The start of the string, in an external buffer. 35 const char *Data; 36 37 /// The length of the string. 38 size_t Length; 39 40 public: 41 /// @name Constructors 42 /// @{ 43 44 /// Construct an empty string ref. 45 /*implicit*/ StringRef() : Data(0), Length(0) {} 46 47 /// Construct a string ref from a cstring. 48 /*implicit*/ StringRef(const char *Str) 49 : Data(Str) { if (Str) Length = ::strlen(Str); else Length = 0; } 50 51 /// Construct a string ref from a pointer and length. 52 /*implicit*/ StringRef(const char *data, size_t length) 53 : Data(data), Length(length) {} 54 55 /// Construct a string ref from an std::string. 56 /*implicit*/ StringRef(const std::string &Str) 57 : Data(Str.c_str()), Length(Str.length()) {} 58 59 /// @} 60 /// @name Iterators 61 /// @{ 62 63 iterator begin() const { return Data; } 64 65 iterator end() const { return Data + Length; } 66 67 /// @} 68 /// @name String Operations 69 /// @{ 70 71 /// data - Get a pointer to the start of the string (which may not be null 72 /// terminated). 73 const char *data() const { return Data; } 74 75 /// empty - Check if the string is empty. 76 bool empty() const { return Length == 0; } 77 78 /// size - Get the string size. 79 size_t size() const { return Length; } 80 81 /// front - Get the first character in the string. 82 char front() const { 83 assert(!empty()); 84 return Data[0]; 85 } 86 87 /// back - Get the last character in the string. 88 char back() const { 89 assert(!empty()); 90 return Data[Length-1]; 91 } 92 93 /// equals - Check for string equality, this is more efficient than 94 /// compare() when the relative ordering of inequal strings isn't needed. 95 bool equals(const StringRef &RHS) const { 96 return (Length == RHS.Length && 97 memcmp(Data, RHS.Data, RHS.Length) == 0); 98 } 99 100 /// compare - Compare two strings; the result is -1, 0, or 1 if this string 101 /// is lexicographically less than, equal to, or greater than the \arg RHS. 102 int compare(const StringRef &RHS) const { 103 // Check the prefix for a mismatch. 104 if (int Res = memcmp(Data, RHS.Data, std::min(Length, RHS.Length))) 105 return Res < 0 ? -1 : 1; 106 107 // Otherwise the prefixes match, so we only need to check the lengths. 108 if (Length == RHS.Length) 109 return 0; 110 return Length < RHS.Length ? -1 : 1; 111 } 112 113 /// str - Get the contents as an std::string. 114 std::string str() const { return std::string(Data, Length); } 115 116 /// @} 117 /// @name Operator Overloads 118 /// @{ 119 120 char operator[](size_t Index) const { 121 assert(Index < Length && "Invalid index!"); 122 return Data[Index]; 123 } 124 125 /// @} 126 /// @name Type Conversions 127 /// @{ 128 129 operator std::string() const { 130 return str(); 131 } 132 133 /// @} 134 /// @name String Predicates 135 /// @{ 136 137 /// startswith - Check if this string starts with the given \arg Prefix. 138 bool startswith(const StringRef &Prefix) const { 139 return substr(0, Prefix.Length).equals(Prefix); 140 } 141 142 /// endswith - Check if this string ends with the given \arg Suffix. 143 bool endswith(const StringRef &Suffix) const { 144 return slice(size() - Suffix.Length, size()).equals(Suffix); 145 } 146 147 /// @} 148 /// @name String Searching 149 /// @{ 150 151 /// find - Search for the first character \arg C in the string. 152 /// 153 /// \return - The index of the first occurence of \arg C, or npos if not 154 /// found. 155 size_t find(char C) const { 156 for (size_t i = 0, e = Length; i != e; ++i) 157 if (Data[i] == C) 158 return i; 159 return npos; 160 } 161 162 /// find - Search for the first string \arg Str in the string. 163 /// 164 /// \return - The index of the first occurence of \arg Str, or npos if not 165 /// found. 166 size_t find(const StringRef &Str) const; 167 168 /// rfind - Search for the last character \arg C in the string. 169 /// 170 /// \return - The index of the last occurence of \arg C, or npos if not 171 /// found. 172 size_t rfind(char C, size_t From = npos) const { 173 From = std::min(From, Length); 174 size_t i = From; 175 while (i != 0) { 176 --i; 177 if (Data[i] == C) 178 return i; 179 } 180 return npos; 181 } 182 183 /// rfind - Search for the last string \arg Str in the string. 184 /// 185 /// \return - The index of the last occurence of \arg Str, or npos if not 186 /// found. 187 size_t rfind(const StringRef &Str) const; 188 189 /// find_first_of - Find the first instance of the specified character or 190 /// return npos if not in string. Same as find. 191 size_type find_first_of(char C) const { return find(C); } 192 193 /// find_first_of - Find the first character from the string 'Chars' in the 194 /// current string or return npos if not in string. 195 size_type find_first_of(StringRef Chars) const; 196 197 /// find_first_not_of - Find the first character in the string that is not 198 /// in the string 'Chars' or return npos if all are in string. Same as find. 199 size_type find_first_not_of(StringRef Chars) const; 200 201 /// @} 202 /// @name Helpful Algorithms 203 /// @{ 204 205 /// count - Return the number of occurrences of \arg C in the string. 206 size_t count(char C) const { 207 size_t Count = 0; 208 for (size_t i = 0, e = Length; i != e; ++i) 209 if (Data[i] == C) 210 ++Count; 211 return Count; 212 } 213 214 /// count - Return the number of non-overlapped occurrences of \arg Str in 215 /// the string. 216 size_t count(const StringRef &Str) const; 217 218 /// getAsInteger - Parse the current string as an integer of the specified 219 /// radix. If Radix is specified as zero, this does radix autosensing using 220 /// extended C rules: 0 is octal, 0x is hex, 0b is binary. 221 /// 222 /// If the string is invalid or if only a subset of the string is valid, 223 /// this returns true to signify the error. The string is considered 224 /// erroneous if empty. 225 /// 226 bool getAsInteger(unsigned Radix, long long &Result) const; 227 bool getAsInteger(unsigned Radix, unsigned long long &Result) const; 228 bool getAsInteger(unsigned Radix, int &Result) const; 229 bool getAsInteger(unsigned Radix, unsigned &Result) const; 230 231 // TODO: Provide overloads for int/unsigned that check for overflow. 232 233 /// @} 234 /// @name Substring Operations 235 /// @{ 236 237 /// substr - Return a reference to the substring from [Start, Start + N). 238 /// 239 /// \param Start - The index of the starting character in the substring; if 240 /// the index is npos or greater than the length of the string then the 241 /// empty substring will be returned. 242 /// 243 /// \param N - The number of characters to included in the substring. If N 244 /// exceeds the number of characters remaining in the string, the string 245 /// suffix (starting with \arg Start) will be returned. 246 StringRef substr(size_t Start, size_t N = npos) const { 247 Start = std::min(Start, Length); 248 return StringRef(Data + Start, std::min(N, Length - Start)); 249 } 250 251 /// slice - Return a reference to the substring from [Start, End). 252 /// 253 /// \param Start - The index of the starting character in the substring; if 254 /// the index is npos or greater than the length of the string then the 255 /// empty substring will be returned. 256 /// 257 /// \param End - The index following the last character to include in the 258 /// substring. If this is npos, or less than \arg Start, or exceeds the 259 /// number of characters remaining in the string, the string suffix 260 /// (starting with \arg Start) will be returned. 261 StringRef slice(size_t Start, size_t End) const { 262 Start = std::min(Start, Length); 263 End = std::min(std::max(Start, End), Length); 264 return StringRef(Data + Start, End - Start); 265 } 266 267 /// split - Split into two substrings around the first occurence of a 268 /// separator character. 269 /// 270 /// If \arg Separator is in the string, then the result is a pair (LHS, RHS) 271 /// such that (*this == LHS + Separator + RHS) is true and RHS is 272 /// maximal. If \arg Separator is not in the string, then the result is a 273 /// pair (LHS, RHS) where (*this == LHS) and (RHS == ""). 274 /// 275 /// \param Separator - The character to split on. 276 /// \return - The split substrings. 277 std::pair<StringRef, StringRef> split(char Separator) const { 278 size_t Idx = find(Separator); 279 if (Idx == npos) 280 return std::make_pair(*this, StringRef()); 281 return std::make_pair(slice(0, Idx), slice(Idx+1, npos)); 282 } 283 284 /// rsplit - Split into two substrings around the last occurence of a 285 /// separator character. 286 /// 287 /// If \arg Separator is in the string, then the result is a pair (LHS, RHS) 288 /// such that (*this == LHS + Separator + RHS) is true and RHS is 289 /// minimal. If \arg Separator is not in the string, then the result is a 290 /// pair (LHS, RHS) where (*this == LHS) and (RHS == ""). 291 /// 292 /// \param Separator - The character to split on. 293 /// \return - The split substrings. 294 std::pair<StringRef, StringRef> rsplit(char Separator) const { 295 size_t Idx = rfind(Separator); 296 if (Idx == npos) 297 return std::make_pair(*this, StringRef()); 298 return std::make_pair(slice(0, Idx), slice(Idx+1, npos)); 299 } 300 301 /// @} 302 }; 303 304 /// @name StringRef Comparison Operators 305 /// @{ 306 307 inline bool operator==(const StringRef &LHS, const StringRef &RHS) { 308 return LHS.equals(RHS); 309 } 310 311 inline bool operator!=(const StringRef &LHS, const StringRef &RHS) { 312 return !(LHS == RHS); 313 } 314 315 inline bool operator<(const StringRef &LHS, const StringRef &RHS) { 316 return LHS.compare(RHS) == -1; 317 } 318 319 inline bool operator<=(const StringRef &LHS, const StringRef &RHS) { 320 return LHS.compare(RHS) != 1; 321 } 322 323 inline bool operator>(const StringRef &LHS, const StringRef &RHS) { 324 return LHS.compare(RHS) == 1; 325 } 326 327 inline bool operator>=(const StringRef &LHS, const StringRef &RHS) { 328 return LHS.compare(RHS) != -1; 329 } 330 331 /// @} 332 333} 334 335#endif 336