10 #ifndef WPIUTIL_WPI_STRINGREF_H
11 #define WPIUTIL_WPI_STRINGREF_H
13 #include "wpi/STLExtras.h"
15 #include "wpi/Compiler.h"
23 #include <type_traits>
29 template <
typename T>
class SmallVectorImpl;
34 unsigned long long &Result) noexcept;
36 bool getAsSignedInteger(StringRef Str,
unsigned Radix,
long long &Result) noexcept;
38 bool consumeUnsignedInteger(StringRef &Str,
unsigned Radix,
39 unsigned long long &Result) noexcept;
40 bool consumeSignedInteger(StringRef &Str,
unsigned Radix,
long long &Result) noexcept;
51 static const size_t npos = ~size_t(0);
53 using iterator =
const char *;
54 using const_iterator =
const char *;
55 using size_type = size_t;
59 const char *Data =
nullptr;
66 LLVM_ATTRIBUTE_ALWAYS_INLINE
67 static int compareMemory(
const char *Lhs,
const char *Rhs,
size_t Length) noexcept {
68 if (Length == 0) {
return 0; }
69 return ::memcmp(Lhs,Rhs,Length);
84 LLVM_ATTRIBUTE_ALWAYS_INLINE
86 : Data(Str), Length(Str ? ::strlen(Str) : 0) {}
89 LLVM_ATTRIBUTE_ALWAYS_INLINE
91 : Data(data), Length(length) {}
94 LLVM_ATTRIBUTE_ALWAYS_INLINE
96 : Data(Str.
data()), Length(Str.length()) {}
106 iterator begin() const noexcept {
return Data; }
108 iterator end() const noexcept {
return Data + Length; }
110 const unsigned char *bytes_begin() const noexcept {
111 return reinterpret_cast<const unsigned char *
>(begin());
113 const unsigned char *bytes_end() const noexcept {
114 return reinterpret_cast<const unsigned char *
>(end());
116 iterator_range<const unsigned char *> bytes() const noexcept {
117 return make_range(bytes_begin(), bytes_end());
127 LLVM_ATTRIBUTE_ALWAYS_INLINE
128 const char *
data() const noexcept {
return Data; }
132 LLVM_ATTRIBUTE_ALWAYS_INLINE
137 LLVM_ATTRIBUTE_ALWAYS_INLINE
138 size_t size() const noexcept {
return Length; }
151 return Data[Length-1];
155 template <
typename Allocator>
156 LLVM_NODISCARD
StringRef copy(Allocator &A)
const {
160 char *S = A.template Allocate<char>(Length);
161 std::copy(begin(), end(), S);
168 LLVM_ATTRIBUTE_ALWAYS_INLINE
170 return (Length == RHS.Length &&
171 compareMemory(Data, RHS.Data, RHS.Length) == 0);
183 LLVM_ATTRIBUTE_ALWAYS_INLINE
186 if (
int Res = compareMemory(Data, RHS.Data, std::min(Length, RHS.Length)))
187 return Res < 0 ? -1 : 1;
190 if (Length == RHS.Length)
192 return Length < RHS.Length ? -1 : 1;
207 if (!Data)
return std::string();
208 return std::string(Data, Length);
216 char operator[](
size_t Index)
const noexcept {
217 assert(Index < Length &&
"Invalid index!");
225 template <
typename T>
226 typename std::enable_if<std::is_same<T, std::string>::value,
234 operator std::string()
const {
244 LLVM_ATTRIBUTE_ALWAYS_INLINE
246 return Length >= Prefix.Length &&
247 compareMemory(Data, Prefix.Data, Prefix.Length) == 0;
256 LLVM_ATTRIBUTE_ALWAYS_INLINE
258 return Length >= Suffix.Length &&
259 compareMemory(end() - Suffix.Length, Suffix.Data, Suffix.Length) == 0;
275 LLVM_ATTRIBUTE_ALWAYS_INLINE
276 size_t find(
char C,
size_t From = 0) const noexcept {
277 size_t FindBegin = std::min(From, Length);
278 if (FindBegin < Length) {
280 if (
const void *P = ::memchr(Data + FindBegin, C, Length - FindBegin))
281 return static_cast<const char *
>(P) - Data;
291 size_t find_lower(
char C,
size_t From = 0) const noexcept;
298 LLVM_ATTRIBUTE_ALWAYS_INLINE
314 LLVM_ATTRIBUTE_ALWAYS_INLINE
316 return find_if([F](
char c) {
return !F(c); }, From);
338 size_t rfind(
char C,
size_t From = npos) const noexcept {
339 From = std::min(From, Length);
354 size_t rfind_lower(
char C,
size_t From = npos) const noexcept;
374 return find(C, From);
400 return rfind(C, From);
425 LLVM_ATTRIBUTE_ALWAYS_INLINE
431 LLVM_ATTRIBUTE_ALWAYS_INLINE
437 LLVM_ATTRIBUTE_ALWAYS_INLINE
445 LLVM_ATTRIBUTE_ALWAYS_INLINE
454 size_t count(
char C)
const noexcept {
456 for (
size_t i = 0, e = Length; i != e; ++i)
473 template <
typename T>
474 typename std::enable_if<std::numeric_limits<T>::is_signed,
bool>::type
477 if (getAsSignedInteger(*
this, Radix, LLVal) ||
478 static_cast<T>(LLVal) != LLVal)
484 template <
typename T>
485 typename std::enable_if<!std::numeric_limits<T>::is_signed,
bool>::type
486 getAsInteger(
unsigned Radix, T &Result)
const noexcept {
487 unsigned long long ULLVal;
492 static_cast<unsigned long long>(static_cast<T>(ULLVal)) != ULLVal)
507 template <
typename T>
508 typename std::enable_if<std::numeric_limits<T>::is_signed,
bool>::type
511 if (consumeSignedInteger(*
this, Radix, LLVal) ||
512 static_cast<long long>(static_cast<T>(LLVal)) != LLVal)
518 template <
typename T>
519 typename std::enable_if<!std::numeric_limits<T>::is_signed,
bool>::type
521 unsigned long long ULLVal;
522 if (consumeUnsignedInteger(*
this, Radix, ULLVal) ||
523 static_cast<unsigned long long>(static_cast<T>(ULLVal)) != ULLVal)
535 std::string lower()
const;
539 std::string
upper()
const;
555 LLVM_ATTRIBUTE_ALWAYS_INLINE
557 Start = std::min(Start, Length);
558 return StringRef(Data + Start, std::min(N, Length - Start));
565 LLVM_ATTRIBUTE_ALWAYS_INLINE
576 LLVM_ATTRIBUTE_ALWAYS_INLINE
586 LLVM_ATTRIBUTE_ALWAYS_INLINE
594 LLVM_ATTRIBUTE_ALWAYS_INLINE
602 LLVM_ATTRIBUTE_ALWAYS_INLINE
604 assert(
size() >= N &&
"Dropping more elements than exist");
611 LLVM_ATTRIBUTE_ALWAYS_INLINE
613 assert(
size() >= N &&
"Dropping more elements than exist");
620 LLVM_ATTRIBUTE_ALWAYS_INLINE
628 LLVM_ATTRIBUTE_ALWAYS_INLINE
635 LLVM_ATTRIBUTE_ALWAYS_INLINE
646 LLVM_ATTRIBUTE_ALWAYS_INLINE
667 LLVM_ATTRIBUTE_ALWAYS_INLINE
669 Start = std::min(Start, Length);
670 End = std::min(std::max(Start, End), Length);
671 return StringRef(Data + Start, End - Start);
685 std::pair<StringRef, StringRef>
split(
char Separator)
const {
686 size_t Idx =
find(Separator);
688 return std::make_pair(*
this,
StringRef());
689 return std::make_pair(
slice(0, Idx),
slice(Idx+1, npos));
704 size_t Idx =
find(Separator);
706 return std::make_pair(*
this,
StringRef());
707 return std::make_pair(
slice(0, Idx),
slice(Idx + Separator.
size(), npos));
726 bool KeepEmpty =
true)
const;
743 bool KeepEmpty =
true)
const;
756 std::pair<StringRef, StringRef>
rsplit(
char Separator)
const {
757 size_t Idx =
rfind(Separator);
759 return std::make_pair(*
this,
StringRef());
760 return std::make_pair(
slice(0, Idx),
slice(Idx+1, npos));
822 constexpr StringLiteral(
const char (&Str)[N])
823 #if defined(__clang__) && __has_attribute(enable_if)
824 #pragma clang diagnostic push
825 #pragma clang diagnostic ignored "-Wgcc-compat"
826 __attribute((enable_if(__builtin_strlen(Str) == N - 1,
827 "invalid string literal")))
828 #pragma clang diagnostic pop
835 static constexpr StringLiteral withInnerNUL(
const char (&Str)[N]) {
836 return StringLiteral(Str, N - 1);
843 LLVM_ATTRIBUTE_ALWAYS_INLINE
845 return LHS.equals(RHS);
848 LLVM_ATTRIBUTE_ALWAYS_INLINE
849 bool operator!=(StringRef LHS, StringRef RHS) noexcept {
850 return !(LHS == RHS);
853 inline bool operator<(StringRef LHS, StringRef RHS) noexcept {
854 return LHS.compare(RHS) == -1;
857 inline bool operator<=(StringRef LHS, StringRef RHS) noexcept {
858 return LHS.compare(RHS) != 1;
861 inline bool operator>(StringRef LHS, StringRef RHS) noexcept {
862 return LHS.compare(RHS) == 1;
865 inline bool operator>=(StringRef LHS, StringRef RHS) noexcept {
866 return LHS.compare(RHS) != -1;
869 inline bool operator==(StringRef LHS,
const char *RHS) noexcept {
870 return LHS.equals(StringRef(RHS));
873 inline bool operator!=(StringRef LHS,
const char *RHS) noexcept {
874 return !(LHS == StringRef(RHS));
877 inline bool operator<(StringRef LHS,
const char *RHS) noexcept {
878 return LHS.compare(StringRef(RHS)) == -1;
881 inline bool operator<=(StringRef LHS,
const char *RHS) noexcept {
882 return LHS.compare(StringRef(RHS)) != 1;
885 inline bool operator>(StringRef LHS,
const char *RHS) noexcept {
886 return LHS.compare(StringRef(RHS)) == 1;
889 inline bool operator>=(StringRef LHS,
const char *RHS) noexcept {
890 return LHS.compare(StringRef(RHS)) != -1;
893 inline bool operator==(
const char *LHS, StringRef RHS) noexcept {
894 return StringRef(LHS).equals(RHS);
897 inline bool operator!=(
const char *LHS, StringRef RHS) noexcept {
898 return !(StringRef(LHS) == RHS);
901 inline bool operator<(
const char *LHS, StringRef RHS) noexcept {
902 return StringRef(LHS).compare(RHS) == -1;
905 inline bool operator<=(
const char *LHS, StringRef RHS) noexcept {
906 return StringRef(LHS).compare(RHS) != 1;
909 inline bool operator>(
const char *LHS, StringRef RHS) noexcept {
910 return StringRef(LHS).compare(RHS) == 1;
913 inline bool operator>=(
const char *LHS, StringRef RHS) noexcept {
914 return StringRef(LHS).compare(RHS) != -1;
917 inline std::string &operator+=(std::string &buffer, StringRef
string) {
918 return buffer.append(
string.data(),
string.
size());
921 std::ostream &operator<<(std::ostream &os, StringRef
string);
927 hash_code hash_value(StringRef S);
930 template <
typename T>
struct isPodLike;
935 #endif // LLVM_ADT_STRINGREF_H
LLVM_NODISCARD bool startswith_lower(StringRef Prefix) const noexcept
Check if this string starts with the given Prefix, ignoring case.
LLVM_NODISCARD StringRef ltrim(StringRef Chars=" \t\n\v\f\r") const noexcept
Return string with consecutive characters in Chars starting from the left removed.
Definition: StringRef.h:773
LLVM_ATTRIBUTE_ALWAYS_INLINE StringRef(const char *Str)
Construct a string ref from a cstring.
Definition: StringRef.h:85
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE size_t find_if_not(function_ref< bool(char)> F, size_t From=0) const noexcept
Search for the first character not satisfying the predicate F.
Definition: StringRef.h:315
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE bool endswith(StringRef Suffix) const noexcept
Check if this string ends with the given Suffix.
Definition: StringRef.h:257
LLVM_NODISCARD char front() const noexcept
front - Get the first character in the string.
Definition: StringRef.h:142
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE size_t find_if(function_ref< bool(char)> F, size_t From=0) const noexcept
Search for the first character satisfying the predicate F.
Definition: StringRef.h:299
LLVM_NODISCARD size_t find_last_of(char C, size_t From=npos) const noexcept
Find the last character in the string that is C, or npos if not found.
Definition: StringRef.h:399
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE StringRef substr(size_t Start, size_t N=npos) const noexcept
Return a reference to the substring from [Start, Start + N).
Definition: StringRef.h:556
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition: hostname.h:17
LLVM_NODISCARD size_t find_first_of(char C, size_t From=0) const noexcept
Find the first character in the string that is C, or npos if not found.
Definition: StringRef.h:373
LLVM_NODISCARD bool equals_lower(StringRef RHS) const noexcept
equals_lower - Check for string equality, ignoring case.
Definition: StringRef.h:176
LLVM_ATTRIBUTE_ALWAYS_INLINE bool consume_front(StringRef Prefix) noexcept
Returns true if this StringRef has the given prefix and removes that prefix.
Definition: StringRef.h:636
LLVM_ATTRIBUTE_ALWAYS_INLINE bool consume_back(StringRef Suffix) noexcept
Returns true if this StringRef has the given suffix and removes that suffix.
Definition: StringRef.h:647
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE size_t find(char C, size_t From=0) const noexcept
Search for the first character C in the string.
Definition: StringRef.h:276
LLVM_NODISCARD int compare_lower(StringRef RHS) const noexcept
compare_lower - Compare two strings, ignoring case.
This provides a very simple, boring adaptor for a begin and end iterator into a range type...
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE bool contains(StringRef Other) const noexcept
Return true if the given string is a substring of *this, and false otherwise.
Definition: StringRef.h:426
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE bool contains(char C) const noexcept
Return true if the given character is contained in *this, and false otherwise.
Definition: StringRef.h:432
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE StringRef drop_until(function_ref< bool(char)> F) const noexcept
Return a StringRef equal to 'this', but with all characters not satisfying the given predicate droppe...
Definition: StringRef.h:629
LLVM_ATTRIBUTE_ALWAYS_INLINE constexpr StringRef(const char *data, size_t length)
Construct a string ref from a pointer and length.
Definition: StringRef.h:90
std::enable_if< std::numeric_limits< T >::is_signed, bool >::type consumeInteger(unsigned Radix, T &Result) noexcept
Parse the current string as an integer of the specified radix.
Definition: StringRef.h:509
LLVM_NODISCARD size_t rfind_lower(char C, size_t From=npos) const noexcept
Search for the last character C in the string, ignoring case.
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE const char * data() const noexcept
data - Get a pointer to the start of the string (which may not be null terminated).
Definition: StringRef.h:128
WPILib C++ utilities (wpiutil) namespace.
Definition: SmallString.h:21
LLVM_NODISCARD size_t find_last_not_of(char C, size_t From=npos) const noexcept
Find the last character in the string that is not C, or npos if not found.
LLVM_NODISCARD std::string upper() const
Convert the given ASCII string to uppercase.
An efficient, type-erasing, non-owning reference to a callable.
Definition: STLExtras.h:88
isPodLike - This is a type trait that is used to determine whether a given type can be copied around ...
Definition: ArrayRef.h:530
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE int compare(StringRef RHS) const noexcept
compare - Compare two strings; the result is -1, 0, or 1 if this string is lexicographically less tha...
Definition: StringRef.h:184
LLVM_NODISCARD StringRef trim(char Char) const noexcept
Return string with consecutive Char characters starting from the left and right removed.
Definition: StringRef.h:794
LLVM_NODISCARD size_t find_lower(char C, size_t From=0) const noexcept
Search for the first character C in the string, ignoring case.
LLVM_NODISCARD std::pair< StringRef, StringRef > split(char Separator) const
Split into two substrings around the first occurrence of a separator character.
Definition: StringRef.h:685
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE bool contains_lower(StringRef Other) const noexcept
Return true if the given string is a substring of *this, and false otherwise.
Definition: StringRef.h:438
bool getAsUnsignedInteger(StringRef Str, unsigned Radix, unsigned long long &Result) noexcept
Helper functions for StringRef::getAsInteger.
std::enable_if< std::numeric_limits< T >::is_signed, bool >::type getAsInteger(unsigned Radix, T &Result) const noexcept
Parse the current string as an integer of the specified radix.
Definition: StringRef.h:475
StringRef()=default
Construct an empty string ref.
LLVM_NODISCARD size_t count(char C) const noexcept
Return the number of occurrences of C in the string.
Definition: StringRef.h:454
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE bool equals(StringRef RHS) const noexcept
equals - Check for string equality, this is more efficient than compare() when the relative ordering ...
Definition: StringRef.h:169
LLVM_NODISCARD size_t rfind(char C, size_t From=npos) const noexcept
Search for the last character C in the string.
Definition: StringRef.h:338
LLVM_NODISCARD StringRef ltrim(char Char) const noexcept
Return string with consecutive Char characters starting from the the left removed.
Definition: StringRef.h:766
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE bool contains_lower(char C) const noexcept
Return true if the given character is contained in *this, and false otherwise.
Definition: StringRef.h:446
LLVM_NODISCARD StringRef trim(StringRef Chars=" \t\n\v\f\r") const noexcept
Return string with consecutive characters in Chars starting from the left and right removed...
Definition: StringRef.h:801
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE StringRef drop_while(function_ref< bool(char)> F) const noexcept
Return a StringRef equal to 'this', but with all characters satisfying the given predicate dropped fr...
Definition: StringRef.h:621
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE StringRef drop_front(size_t N=1) const noexcept
Return a StringRef equal to 'this' but with the first N elements dropped.
Definition: StringRef.h:603
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
Definition: iterator_range.h:54
LLVM_NODISCARD bool endswith_lower(StringRef Suffix) const noexcept
Check if this string ends with the given Suffix, ignoring case.
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE bool empty() const noexcept
empty - Check if the string is empty.
Definition: StringRef.h:133
A wrapper around a string literal that serves as a proxy for constructing global tables of StringRefs...
Definition: StringRef.h:815
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE StringRef take_front(size_t N=1) const noexcept
Return a StringRef equal to 'this' but with only the first N elements remaining.
Definition: StringRef.h:566
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE StringRef take_until(function_ref< bool(char)> F) const noexcept
Return the longest prefix of 'this' such that no character in the prefix satisfies the given predicat...
Definition: StringRef.h:595
auto size(R &&Range, typename std::enable_if< std::is_same< typename std::iterator_traits< decltype(Range.begin())>::iterator_category, std::random_access_iterator_tag >::value, void >::type *=nullptr) -> decltype(std::distance(Range.begin(), Range.end()))
Get the size of a range.
Definition: STLExtras.h:999
LLVM_ATTRIBUTE_ALWAYS_INLINE StringRef(const std::string &Str)
Construct a string ref from an std::string.
Definition: StringRef.h:95
LLVM_NODISCARD std::pair< StringRef, StringRef > split(StringRef Separator) const
Split into two substrings around the first occurrence of a separator string.
Definition: StringRef.h:703
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:49
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE StringRef drop_back(size_t N=1) const noexcept
Return a StringRef equal to 'this' but with the last N elements dropped.
Definition: StringRef.h:612
std::enable_if< std::is_same< T, std::string >::value, StringRef >::type & operator=(T &&Str)=delete
Disallow accidental assignment from a temporary std::string.
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE size_t size() const noexcept
size - Get the string size.
Definition: StringRef.h:138
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE StringRef slice(size_t Start, size_t End) const noexcept
Return a reference to the substring from [Start, End).
Definition: StringRef.h:668
LLVM_NODISCARD size_t find_first_not_of(char C, size_t From=0) const noexcept
Find the first character in the string that is not C or npos if not found.
LLVM_NODISCARD int compare_numeric(StringRef RHS) const noexcept
compare_numeric - Compare two strings, treating sequences of digits as numbers.
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE StringRef take_while(function_ref< bool(char)> F) const noexcept
Return the longest prefix of 'this' such that every character in the prefix satisfies the given predi...
Definition: StringRef.h:587
LLVM_NODISCARD char back() const noexcept
back - Get the last character in the string.
Definition: StringRef.h:149
LLVM_NODISCARD std::pair< StringRef, StringRef > rsplit(char Separator) const
Split into two substrings around the last occurrence of a separator character.
Definition: StringRef.h:756
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE StringRef take_back(size_t N=1) const noexcept
Return a StringRef equal to 'this' but with only the last N elements remaining.
Definition: StringRef.h:577
LLVM_NODISCARD std::string str() const
str - Get the contents as an std::string.
Definition: StringRef.h:206
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE bool startswith(StringRef Prefix) const noexcept
Check if this string starts with the given Prefix.
Definition: StringRef.h:245
LLVM_NODISCARD StringRef rtrim(StringRef Chars=" \t\n\v\f\r") const noexcept
Return string with consecutive characters in Chars starting from the right removed.
Definition: StringRef.h:787
LLVM_NODISCARD StringRef rtrim(char Char) const noexcept
Return string with consecutive Char characters starting from the right removed.
Definition: StringRef.h:780