WPILibC++  unspecified
StringRef.h
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 "llvm/iterator_range.h"
14 #include "llvm/Compiler.h"
15 #include <algorithm>
16 #include <cassert>
17 #include <cstring>
18 #include <limits>
19 #include <ostream>
20 #include <string>
21 #include <utility>
22 
23 namespace llvm {
24  template <typename T>
25  class SmallVectorImpl;
26  class hash_code;
27  class StringRef;
28 
30  bool getAsUnsignedInteger(StringRef Str, unsigned Radix,
31  unsigned long long &Result);
32 
33  bool getAsSignedInteger(StringRef Str, unsigned Radix, long long &Result);
34 
42  class StringRef {
43  public:
44  typedef const char *iterator;
45  typedef const char *const_iterator;
46  static const size_t npos = ~size_t(0);
47  typedef size_t size_type;
48 
49  private:
51  const char *Data;
52 
56  size_t Length;
57 
58  // Workaround memcmp issue with null pointers (undefined behavior)
59  // by providing a specialized version
60  static int compareMemory(const char *Lhs, const char *Rhs, size_t Length) {
61  if (Length == 0) { return 0; }
62  return ::memcmp(Lhs,Rhs,Length);
63  }
64 
66  void set_null_terminated(bool set) {
67  if (set)
68  Length |= ((size_t)1 << (sizeof(size_t) * 8 - 1));
69  else {
70  Length &= ~((size_t)1 << (sizeof(size_t) * 8 - 1));
71  }
72  }
73 
74  public:
77 
79  /*implicit*/ StringRef() : Data(""), Length(0) {
80  set_null_terminated(true);
81  }
82 
84  /*implicit*/ StringRef(const char *Str)
85  : Data(Str) {
86  assert(Str && "StringRef cannot be built from a NULL argument");
87  Length = ::strlen(Str); // invoking strlen(NULL) is undefined behavior
88  // Require length to not use MSB of size
89  assert(Length < ~((size_t)1 << (sizeof(size_t) * 8 - 1)));
90  // If from a const char*, we are null terminated
91  set_null_terminated(true);
92  }
93 
95  /*implicit*/ StringRef(const char *data, size_t length, bool isNullTerminated = false)
96  : Data(data), Length(length) {
97  assert((data || length == 0) &&
98  "StringRef cannot be built from a NULL argument with non-null length");
99  // Require length to not use MSB of size
100  assert(Length < ~((size_t)1 << (sizeof(size_t) * 8 - 1)));
101  // If passed an explicit length, use the parameter
102  // Default to false (not null) to match previous behavior.
103  set_null_terminated(isNullTerminated);
104  }
105 
107  /*implicit*/ StringRef(const std::string &Str)
108  : Data(Str.data()), Length(Str.length()) {
109  // Require length to not use MSB of size
110  assert(Length < ~((size_t)1 << (sizeof(size_t) * 8 - 1)));
111  // If from a std::string, we are null terminated
112  set_null_terminated(true);
113  }
114 
118 
119  iterator begin() const { return Data; }
120 
121  iterator end() const { return Data + size(); }
122 
123  const unsigned char *bytes_begin() const {
124  return reinterpret_cast<const unsigned char *>(begin());
125  }
126  const unsigned char *bytes_end() const {
127  return reinterpret_cast<const unsigned char *>(end());
128  }
130  return make_range(bytes_begin(), bytes_end());
131  }
132 
136 
139  const char *data() const { return Data; }
140 
143  const char *c_str(llvm::SmallVectorImpl<char>& buf) const;
144 
146  bool empty() const { return size() == 0; }
147 
149  size_t size() const {
150  return Length & ~((size_t)1 << (sizeof(size_t) * 8 - 1));
151  }
152 
154  bool is_null_terminated() const {
155  return (Length & ((size_t)1 << (sizeof(size_t) * 8 - 1))) ==
156  ((size_t)1 << (sizeof(size_t) * 8 - 1));
157  }
158 
160  char front() const {
161  assert(!empty());
162  return Data[0];
163  }
164 
166  char back() const {
167  assert(!empty());
168  return Data[size()-1];
169  }
170 
171  // copy - Allocate copy in Allocator and return StringRef to it.
172  template <typename Allocator> StringRef copy(Allocator &A) const {
173  // Don't request a length 0 copy from the allocator.
174  if (empty())
175  return StringRef();
176  char *S = A.template Allocate<char>(size());
177  std::copy(begin(), end(), S);
178  return StringRef(S, size());
179  }
180 
183  bool equals(StringRef RHS) const {
184  return (size() == RHS.size() &&
185  compareMemory(Data, RHS.Data, RHS.size()) == 0);
186  }
187 
189  bool equals_lower(StringRef RHS) const {
190  return size() == RHS.size() && compare_lower(RHS) == 0;
191  }
192 
195  int compare(StringRef RHS) const {
196  // Check the prefix for a mismatch.
197  if (int Res = compareMemory(Data, RHS.Data, std::min(size(), RHS.size())))
198  return Res < 0 ? -1 : 1;
199 
200  // Otherwise the prefixes match, so we only need to check the lengths.
201  if (size() == RHS.size())
202  return 0;
203  return size() < RHS.size() ? -1 : 1;
204  }
205 
207  int compare_lower(StringRef RHS) const;
208 
211  int compare_numeric(StringRef RHS) const;
212 
214  std::string str() const {
215  if (!Data) return std::string();
216  return std::string(Data, size());
217  }
218 
222 
223  char operator[](size_t Index) const {
224  assert(Index < size() && "Invalid index!");
225  return Data[Index];
226  }
227 
231 
232  operator std::string() const {
233  return str();
234  }
235 
239 
241  bool startswith(StringRef Prefix) const {
242  return size() >= Prefix.size() &&
243  compareMemory(Data, Prefix.Data, Prefix.size()) == 0;
244  }
245 
247  bool startswith_lower(StringRef Prefix) const;
248 
250  bool endswith(StringRef Suffix) const {
251  return size() >= Suffix.size() &&
252  compareMemory(end() - Suffix.size(), Suffix.Data, Suffix.size()) == 0;
253  }
254 
256  bool endswith_lower(StringRef Suffix) const;
257 
261 
266  size_t find(char C, size_t From = 0) const {
267  size_t FindBegin = std::min(From, size());
268  if (FindBegin < size()) { // Avoid calling memchr with nullptr.
269  // Just forward to memchr, which is faster than a hand-rolled loop.
270  if (const void *P = ::memchr(Data + FindBegin, C, size() - FindBegin))
271  return static_cast<const char *>(P) - Data;
272  }
273  return npos;
274  }
275 
280  size_t find(StringRef Str, size_t From = 0) const;
281 
286  size_t rfind(char C, size_t From = npos) const {
287  From = std::min(From, size());
288  size_t i = From;
289  while (i != 0) {
290  --i;
291  if (Data[i] == C)
292  return i;
293  }
294  return npos;
295  }
296 
301  size_t rfind(StringRef Str) const;
302 
305  size_t find_first_of(char C, size_t From = 0) const {
306  return find(C, From);
307  }
308 
313  size_t find_first_of(StringRef Chars, size_t From = 0) const;
314 
317  size_t find_first_not_of(char C, size_t From = 0) const;
318 
323  size_t find_first_not_of(StringRef Chars, size_t From = 0) const;
324 
327  size_t find_last_of(char C, size_t From = npos) const {
328  return rfind(C, From);
329  }
330 
335  size_t find_last_of(StringRef Chars, size_t From = npos) const;
336 
339  size_t find_last_not_of(char C, size_t From = npos) const;
340 
345  size_t find_last_not_of(StringRef Chars, size_t From = npos) const;
346 
350 
352  size_t count(char C) const {
353  size_t Count = 0;
354  for (size_t i = 0, e = size(); i != e; ++i)
355  if (Data[i] == C)
356  ++Count;
357  return Count;
358  }
359 
362  size_t count(StringRef Str) const;
363 
371  template <typename T>
372  typename std::enable_if<std::numeric_limits<T>::is_signed, bool>::type
373  getAsInteger(unsigned Radix, T &Result) const {
374  long long LLVal;
375  if (getAsSignedInteger(*this, Radix, LLVal) ||
376  static_cast<T>(LLVal) != LLVal)
377  return true;
378  Result = LLVal;
379  return false;
380  }
381 
382  template <typename T>
383  typename std::enable_if<!std::numeric_limits<T>::is_signed, bool>::type
384  getAsInteger(unsigned Radix, T &Result) const {
385  unsigned long long ULLVal;
386  // The additional cast to unsigned long long is required to avoid the
387  // Visual C++ warning C4805: '!=' : unsafe mix of type 'bool' and type
388  // 'unsigned __int64' when instantiating getAsInteger with T = bool.
389  if (getAsUnsignedInteger(*this, Radix, ULLVal) ||
390  static_cast<unsigned long long>(static_cast<T>(ULLVal)) != ULLVal)
391  return true;
392  Result = ULLVal;
393  return false;
394  }
395 
399 
400  // Convert the given ASCII string to lowercase.
401  std::string lower() const;
402 
404  std::string upper() const;
405 
409 
419  StringRef substr(size_t Start, size_t N = npos) const {
420  Start = std::min(Start, size());
421  return StringRef(Data + Start, std::min(N, size() - Start));
422  }
423 
426  StringRef drop_front(size_t N = 1) const {
427  assert(size() >= N && "Dropping more elements than exist");
428  return substr(N);
429  }
430 
433  StringRef drop_back(size_t N = 1) const {
434  assert(size() >= N && "Dropping more elements than exist");
435  return substr(0, size()-N);
436  }
437 
449  StringRef slice(size_t Start, size_t End) const {
450  Start = std::min(Start, size());
451  End = std::min(std::max(Start, End), size());
452  return StringRef(Data + Start, End - Start);
453  }
454 
465  std::pair<StringRef, StringRef> split(char Separator) const {
466  size_t Idx = find(Separator);
467  if (Idx == npos)
468  return std::make_pair(*this, StringRef());
469  return std::make_pair(slice(0, Idx), slice(Idx+1, npos));
470  }
471 
482  std::pair<StringRef, StringRef> split(StringRef Separator) const {
483  size_t Idx = find(Separator);
484  if (Idx == npos)
485  return std::make_pair(*this, StringRef());
486  return std::make_pair(slice(0, Idx), slice(Idx + Separator.size(), npos));
487  }
488 
504  StringRef Separator, int MaxSplit = -1,
505  bool KeepEmpty = true) const;
506 
521  void split(SmallVectorImpl<StringRef> &A, char Separator, int MaxSplit = -1,
522  bool KeepEmpty = true) const;
523 
534  std::pair<StringRef, StringRef> rsplit(char Separator) const {
535  size_t Idx = rfind(Separator);
536  if (Idx == npos)
537  return std::make_pair(*this, StringRef());
538  return std::make_pair(slice(0, Idx), slice(Idx+1, npos));
539  }
540 
543  StringRef ltrim(char Char) const {
544  return drop_front(std::min(size(), find_first_not_of(Char)));
545  }
546 
549  StringRef ltrim(StringRef Chars = " \t\n\v\f\r") const {
550  return drop_front(std::min(size(), find_first_not_of(Chars)));
551  }
552 
555  StringRef rtrim(char Char) const {
556  return drop_back(size() - std::min(size(), find_last_not_of(Char) + 1));
557  }
558 
561  StringRef rtrim(StringRef Chars = " \t\n\v\f\r") const {
562  return drop_back(size() - std::min(size(), find_last_not_of(Chars) + 1));
563  }
564 
567  StringRef trim(char Char) const {
568  return ltrim(Char).rtrim(Char);
569  }
570 
573  StringRef trim(StringRef Chars = " \t\n\v\f\r") const {
574  return ltrim(Chars).rtrim(Chars);
575  }
576 
578  };
579 
582 
583  inline bool operator==(StringRef LHS, StringRef RHS) {
584  return LHS.equals(RHS);
585  }
586 
587  inline bool operator!=(StringRef LHS, StringRef RHS) {
588  return !(LHS == RHS);
589  }
590 
591  inline bool operator<(StringRef LHS, StringRef RHS) {
592  return LHS.compare(RHS) == -1;
593  }
594 
595  inline bool operator<=(StringRef LHS, StringRef RHS) {
596  return LHS.compare(RHS) != 1;
597  }
598 
599  inline bool operator>(StringRef LHS, StringRef RHS) {
600  return LHS.compare(RHS) == 1;
601  }
602 
603  inline bool operator>=(StringRef LHS, StringRef RHS) {
604  return LHS.compare(RHS) != -1;
605  }
606 
607  inline std::string &operator+=(std::string &buffer, StringRef string) {
608  return buffer.append(string.data(), string.size());
609  }
610 
611  inline std::ostream &operator<<(std::ostream &os, StringRef string) {
612  os.write(string.data(), string.size());
613  return os;
614  }
615 
617 
619  hash_code hash_value(StringRef S);
620 
621  // StringRefs can be treated like a POD type.
622  template <typename T> struct isPodLike;
623  template <> struct isPodLike<StringRef> { static const bool value = true; };
624 } // namespace llvm
625 
626 #endif
std::enable_if< std::numeric_limits< T >::is_signed, bool >::type getAsInteger(unsigned Radix, T &Result) const
Parse the current string as an integer of the specified radix.
Definition: StringRef.h:373
int compare_lower(StringRef RHS) const
compare_lower - Compare two strings, ignoring case.
Definition: StringRef.cpp:52
size_t size() const
size - Get the string size.
Definition: StringRef.h:149
Definition: Path.inc:31
size_t find(char C, size_t From=0) const
Search for the first character C in the string.
Definition: StringRef.h:266
This provides a very simple, boring adaptor for a begin and end iterator into a range type...
bool endswith(StringRef Suffix) const
Check if this string ends with the given Suffix.
Definition: StringRef.h:250
std::pair< StringRef, StringRef > split(char Separator) const
Split into two substrings around the first occurrence of a separator character.
Definition: StringRef.h:465
size_t rfind(char C, size_t From=npos) const
Search for the last character C in the string.
Definition: StringRef.h:286
StringRef substr(size_t Start, size_t N=npos) const
Return a reference to the substring from [Start, Start + N).
Definition: StringRef.h:419
std::string str() const
str - Get the contents as an std::string.
Definition: StringRef.h:214
bool is_null_terminated() const
is_null_terminated - Get if the string is guaranteed null terminated
Definition: StringRef.h:154
StringRef drop_back(size_t N=1) const
Return a StringRef equal to &#39;this&#39; but with the last N elements dropped.
Definition: StringRef.h:433
std::pair< StringRef, StringRef > rsplit(char Separator) const
Split into two substrings around the last occurrence of a separator character.
Definition: StringRef.h:534
bool endswith_lower(StringRef Suffix) const
Check if this string ends with the given Suffix, ignoring case.
Definition: StringRef.cpp:67
int compare(StringRef RHS) const
compare - Compare two strings; the result is -1, 0, or 1 if this string is lexicographically less tha...
Definition: StringRef.h:195
StringRef rtrim(StringRef Chars=" \t\n\v\f\r") const
Return string with consecutive characters in Chars starting from the right removed.
Definition: StringRef.h:561
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
Definition: iterator_range.h:54
const char * data() const
data - Get a pointer to the start of the string (which may not be null terminated).
Definition: StringRef.h:139
StringRef()
Construct an empty string ref.
Definition: StringRef.h:79
const char * c_str(llvm::SmallVectorImpl< char > &buf) const
c_str - Get a null terminated pointer to the start of the string If string is not null terminated...
Definition: StringRef.cpp:123
size_t find_last_not_of(char C, size_t From=npos) const
Find the last character in the string that is not C, or npos if not found.
Definition: StringRef.cpp:264
StringRef trim(char Char) const
Return string with consecutive Char characters starting from the left and right removed.
Definition: StringRef.h:567
StringRef(const char *data, size_t length, bool isNullTerminated=false)
Construct a string ref from a pointer and length.
Definition: StringRef.h:95
StringRef trim(StringRef Chars=" \t\n\v\f\r") const
Return string with consecutive characters in Chars starting from the left and right removed...
Definition: StringRef.h:573
char back() const
back - Get the last character in the string.
Definition: StringRef.h:166
size_t count(char C) const
Return the number of occurrences of C in the string.
Definition: StringRef.h:352
StringRef ltrim(char Char) const
Return string with consecutive Char characters starting from the the left removed.
Definition: StringRef.h:543
std::pair< StringRef, StringRef > split(StringRef Separator) const
Split into two substrings around the first occurrence of a separator string.
Definition: StringRef.h:482
size_t find_first_not_of(char C, size_t From=0) const
Find the first character in the string that is not C or npos if not found.
Definition: StringRef.cpp:223
StringRef rtrim(char Char) const
Return string with consecutive Char characters starting from the right removed.
Definition: StringRef.h:555
StringRef(const std::string &Str)
Construct a string ref from an std::string.
Definition: StringRef.h:107
size_t find_last_of(char C, size_t From=npos) const
Find the last character in the string that is C, or npos if not found.
Definition: StringRef.h:327
isPodLike - This is a type trait that is used to determine whether a given type can be copied around ...
Definition: Optional.h:147
bool startswith(StringRef Prefix) const
Check if this string starts with the given Prefix.
Definition: StringRef.h:241
StringRef drop_front(size_t N=1) const
Return a StringRef equal to &#39;this&#39; but with the first N elements dropped.
Definition: StringRef.h:426
std::string upper() const
Convert the given ASCII string to uppercase.
Definition: StringRef.cpp:115
A range adaptor for a pair of iterators.
Definition: iterator_range.h:32
An opaque object representing a hash code.
Definition: Hashing.h:70
bool equals(StringRef RHS) const
equals - Check for string equality, this is more efficient than compare() when the relative ordering ...
Definition: StringRef.h:183
bool equals_lower(StringRef RHS) const
equals_lower - Check for string equality, ignoring case.
Definition: StringRef.h:189
StringRef(const char *Str)
Construct a string ref from a cstring.
Definition: StringRef.h:84
size_t find_first_of(char C, size_t From=0) const
Find the first character in the string that is C, or npos if not found.
Definition: StringRef.h:305
char front() const
front - Get the first character in the string.
Definition: StringRef.h:160
int compare_numeric(StringRef RHS) const
compare_numeric - Compare two strings, treating sequences of digits as numbers.
Definition: StringRef.cpp:73
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:42
StringRef slice(size_t Start, size_t End) const
Return a reference to the substring from [Start, End).
Definition: StringRef.h:449
bool startswith_lower(StringRef Prefix) const
Check if this string starts with the given Prefix, ignoring case.
Definition: StringRef.cpp:61
StringRef ltrim(StringRef Chars=" \t\n\v\f\r") const
Return string with consecutive characters in Chars starting from the left removed.
Definition: StringRef.h:549
bool empty() const
empty - Check if the string is empty.
Definition: StringRef.h:146