mirror of
https://github.com/wpilibsuite/allwpilib
synced 2026-06-24 01:31:46 +00:00
Make most StringRef functions noexcept.
This commit is contained in:
@@ -28,9 +28,9 @@ namespace wpi {
|
||||
|
||||
/// Helper functions for StringRef::getAsInteger.
|
||||
bool getAsUnsignedInteger(StringRef Str, unsigned Radix,
|
||||
unsigned long long &Result);
|
||||
unsigned long long &Result) noexcept;
|
||||
|
||||
bool getAsSignedInteger(StringRef Str, unsigned Radix, long long &Result);
|
||||
bool getAsSignedInteger(StringRef Str, unsigned Radix, long long &Result) noexcept;
|
||||
|
||||
/// StringRef - Represent a constant reference to a string, i.e. a character
|
||||
/// array and a length, which need not be null terminated.
|
||||
@@ -57,13 +57,13 @@ namespace wpi {
|
||||
|
||||
// Workaround memcmp issue with null pointers (undefined behavior)
|
||||
// by providing a specialized version
|
||||
static int compareMemory(const char *Lhs, const char *Rhs, size_t Length) {
|
||||
static int compareMemory(const char *Lhs, const char *Rhs, size_t Length) noexcept {
|
||||
if (Length == 0) { return 0; }
|
||||
return ::memcmp(Lhs,Rhs,Length);
|
||||
}
|
||||
|
||||
/// Set the flag to say we are null terminated
|
||||
void set_null_terminated(bool set) {
|
||||
void set_null_terminated(bool set) noexcept {
|
||||
if (set)
|
||||
Length |= ((size_t)1 << (sizeof(size_t) * 8 - 1));
|
||||
else {
|
||||
@@ -76,12 +76,12 @@ namespace wpi {
|
||||
/// @{
|
||||
|
||||
/// Construct an empty string ref.
|
||||
/*implicit*/ StringRef() : Data(""), Length(0) {
|
||||
/*implicit*/ StringRef() noexcept : Data(""), Length(0) {
|
||||
set_null_terminated(true);
|
||||
}
|
||||
|
||||
/// Construct a string ref from a cstring.
|
||||
/*implicit*/ StringRef(const char *Str)
|
||||
/*implicit*/ StringRef(const char *Str) noexcept
|
||||
: Data(Str) {
|
||||
assert(Str && "StringRef cannot be built from a NULL argument");
|
||||
Length = ::strlen(Str); // invoking strlen(NULL) is undefined behavior
|
||||
@@ -92,7 +92,7 @@ namespace wpi {
|
||||
}
|
||||
|
||||
/// Construct a string ref from a pointer and length.
|
||||
/*implicit*/ StringRef(const char *data, size_t length, bool isNullTerminated = false)
|
||||
/*implicit*/ StringRef(const char *data, size_t length, bool isNullTerminated = false) noexcept
|
||||
: Data(data), Length(length) {
|
||||
assert((data || length == 0) &&
|
||||
"StringRef cannot be built from a NULL argument with non-null length");
|
||||
@@ -116,17 +116,17 @@ namespace wpi {
|
||||
/// @name Iterators
|
||||
/// @{
|
||||
|
||||
iterator begin() const { return Data; }
|
||||
iterator begin() const noexcept { return Data; }
|
||||
|
||||
iterator end() const { return Data + size(); }
|
||||
iterator end() const noexcept { return Data + size(); }
|
||||
|
||||
const unsigned char *bytes_begin() const {
|
||||
const unsigned char *bytes_begin() const noexcept {
|
||||
return reinterpret_cast<const unsigned char *>(begin());
|
||||
}
|
||||
const unsigned char *bytes_end() const {
|
||||
const unsigned char *bytes_end() const noexcept {
|
||||
return reinterpret_cast<const unsigned char *>(end());
|
||||
}
|
||||
iterator_range<const unsigned char *> bytes() const {
|
||||
iterator_range<const unsigned char *> bytes() const noexcept {
|
||||
return make_range(bytes_begin(), bytes_end());
|
||||
}
|
||||
|
||||
@@ -136,34 +136,34 @@ namespace wpi {
|
||||
|
||||
/// data - Get a pointer to the start of the string (which may not be null
|
||||
/// terminated).
|
||||
const char *data() const { return Data; }
|
||||
const char *data() const noexcept { return Data; }
|
||||
|
||||
/// c_str - Get a null terminated pointer to the start of the string
|
||||
/// If string is not null terminated, use buffer to store new string
|
||||
const char *c_str(wpi::SmallVectorImpl<char>& buf) const;
|
||||
|
||||
/// empty - Check if the string is empty.
|
||||
bool empty() const { return size() == 0; }
|
||||
bool empty() const noexcept { return size() == 0; }
|
||||
|
||||
/// size - Get the string size.
|
||||
size_t size() const {
|
||||
size_t size() const noexcept {
|
||||
return Length & ~((size_t)1 << (sizeof(size_t) * 8 - 1));
|
||||
}
|
||||
|
||||
/// is_null_terminated - Get if the string is guaranteed null terminated
|
||||
bool is_null_terminated() const {
|
||||
bool is_null_terminated() const noexcept {
|
||||
return (Length & ((size_t)1 << (sizeof(size_t) * 8 - 1))) ==
|
||||
((size_t)1 << (sizeof(size_t) * 8 - 1));
|
||||
}
|
||||
|
||||
/// front - Get the first character in the string.
|
||||
char front() const {
|
||||
char front() const noexcept {
|
||||
assert(!empty());
|
||||
return Data[0];
|
||||
}
|
||||
|
||||
/// back - Get the last character in the string.
|
||||
char back() const {
|
||||
char back() const noexcept {
|
||||
assert(!empty());
|
||||
return Data[size()-1];
|
||||
}
|
||||
@@ -180,19 +180,19 @@ namespace wpi {
|
||||
|
||||
/// equals - Check for string equality, this is more efficient than
|
||||
/// compare() when the relative ordering of inequal strings isn't needed.
|
||||
bool equals(StringRef RHS) const {
|
||||
bool equals(StringRef RHS) const noexcept {
|
||||
return (size() == RHS.size() &&
|
||||
compareMemory(Data, RHS.Data, RHS.size()) == 0);
|
||||
}
|
||||
|
||||
/// equals_lower - Check for string equality, ignoring case.
|
||||
bool equals_lower(StringRef RHS) const {
|
||||
bool equals_lower(StringRef RHS) const noexcept {
|
||||
return size() == RHS.size() && compare_lower(RHS) == 0;
|
||||
}
|
||||
|
||||
/// compare - Compare two strings; the result is -1, 0, or 1 if this string
|
||||
/// is lexicographically less than, equal to, or greater than the \p RHS.
|
||||
int compare(StringRef RHS) const {
|
||||
int compare(StringRef RHS) const noexcept {
|
||||
// Check the prefix for a mismatch.
|
||||
if (int Res = compareMemory(Data, RHS.Data, std::min(size(), RHS.size())))
|
||||
return Res < 0 ? -1 : 1;
|
||||
@@ -204,11 +204,11 @@ namespace wpi {
|
||||
}
|
||||
|
||||
/// compare_lower - Compare two strings, ignoring case.
|
||||
int compare_lower(StringRef RHS) const;
|
||||
int compare_lower(StringRef RHS) const noexcept;
|
||||
|
||||
/// compare_numeric - Compare two strings, treating sequences of digits as
|
||||
/// numbers.
|
||||
int compare_numeric(StringRef RHS) const;
|
||||
int compare_numeric(StringRef RHS) const noexcept;
|
||||
|
||||
/// str - Get the contents as an std::string.
|
||||
std::string str() const {
|
||||
@@ -220,7 +220,7 @@ namespace wpi {
|
||||
/// @name Operator Overloads
|
||||
/// @{
|
||||
|
||||
char operator[](size_t Index) const {
|
||||
char operator[](size_t Index) const noexcept {
|
||||
assert(Index < size() && "Invalid index!");
|
||||
return Data[Index];
|
||||
}
|
||||
@@ -238,22 +238,22 @@ namespace wpi {
|
||||
/// @{
|
||||
|
||||
/// Check if this string starts with the given \p Prefix.
|
||||
bool startswith(StringRef Prefix) const {
|
||||
bool startswith(StringRef Prefix) const noexcept {
|
||||
return size() >= Prefix.size() &&
|
||||
compareMemory(Data, Prefix.Data, Prefix.size()) == 0;
|
||||
}
|
||||
|
||||
/// Check if this string starts with the given \p Prefix, ignoring case.
|
||||
bool startswith_lower(StringRef Prefix) const;
|
||||
bool startswith_lower(StringRef Prefix) const noexcept;
|
||||
|
||||
/// Check if this string ends with the given \p Suffix.
|
||||
bool endswith(StringRef Suffix) const {
|
||||
bool endswith(StringRef Suffix) const noexcept {
|
||||
return size() >= Suffix.size() &&
|
||||
compareMemory(end() - Suffix.size(), Suffix.Data, Suffix.size()) == 0;
|
||||
}
|
||||
|
||||
/// Check if this string ends with the given \p Suffix, ignoring case.
|
||||
bool endswith_lower(StringRef Suffix) const;
|
||||
bool endswith_lower(StringRef Suffix) const noexcept;
|
||||
|
||||
/// @}
|
||||
/// @name String Searching
|
||||
@@ -263,7 +263,7 @@ namespace wpi {
|
||||
///
|
||||
/// \returns The index of the first occurrence of \p C, or npos if not
|
||||
/// found.
|
||||
size_t find(char C, size_t From = 0) const {
|
||||
size_t find(char C, size_t From = 0) const noexcept {
|
||||
size_t FindBegin = std::min(From, size());
|
||||
if (FindBegin < size()) { // Avoid calling memchr with nullptr.
|
||||
// Just forward to memchr, which is faster than a hand-rolled loop.
|
||||
@@ -277,13 +277,13 @@ namespace wpi {
|
||||
///
|
||||
/// \returns The index of the first occurrence of \p Str, or npos if not
|
||||
/// found.
|
||||
size_t find(StringRef Str, size_t From = 0) const;
|
||||
size_t find(StringRef Str, size_t From = 0) const noexcept;
|
||||
|
||||
/// Search for the last character \p C in the string.
|
||||
///
|
||||
/// \returns The index of the last occurrence of \p C, or npos if not
|
||||
/// found.
|
||||
size_t rfind(char C, size_t From = npos) const {
|
||||
size_t rfind(char C, size_t From = npos) const noexcept {
|
||||
From = std::min(From, size());
|
||||
size_t i = From;
|
||||
while (i != 0) {
|
||||
@@ -298,11 +298,11 @@ namespace wpi {
|
||||
///
|
||||
/// \returns The index of the last occurrence of \p Str, or npos if not
|
||||
/// found.
|
||||
size_t rfind(StringRef Str) const;
|
||||
size_t rfind(StringRef Str) const noexcept;
|
||||
|
||||
/// Find the first character in the string that is \p C, or npos if not
|
||||
/// found. Same as find.
|
||||
size_t find_first_of(char C, size_t From = 0) const {
|
||||
size_t find_first_of(char C, size_t From = 0) const noexcept {
|
||||
return find(C, From);
|
||||
}
|
||||
|
||||
@@ -310,21 +310,21 @@ namespace wpi {
|
||||
/// not found.
|
||||
///
|
||||
/// Complexity: O(size() + Chars.size())
|
||||
size_t find_first_of(StringRef Chars, size_t From = 0) const;
|
||||
size_t find_first_of(StringRef Chars, size_t From = 0) const noexcept;
|
||||
|
||||
/// Find the first character in the string that is not \p C or npos if not
|
||||
/// found.
|
||||
size_t find_first_not_of(char C, size_t From = 0) const;
|
||||
size_t find_first_not_of(char C, size_t From = 0) const noexcept;
|
||||
|
||||
/// Find the first character in the string that is not in the string
|
||||
/// \p Chars, or npos if not found.
|
||||
///
|
||||
/// Complexity: O(size() + Chars.size())
|
||||
size_t find_first_not_of(StringRef Chars, size_t From = 0) const;
|
||||
size_t find_first_not_of(StringRef Chars, size_t From = 0) const noexcept;
|
||||
|
||||
/// Find the last character in the string that is \p C, or npos if not
|
||||
/// found.
|
||||
size_t find_last_of(char C, size_t From = npos) const {
|
||||
size_t find_last_of(char C, size_t From = npos) const noexcept {
|
||||
return rfind(C, From);
|
||||
}
|
||||
|
||||
@@ -332,24 +332,24 @@ namespace wpi {
|
||||
/// found.
|
||||
///
|
||||
/// Complexity: O(size() + Chars.size())
|
||||
size_t find_last_of(StringRef Chars, size_t From = npos) const;
|
||||
size_t find_last_of(StringRef Chars, size_t From = npos) const noexcept;
|
||||
|
||||
/// Find the last character in the string that is not \p C, or npos if not
|
||||
/// found.
|
||||
size_t find_last_not_of(char C, size_t From = npos) const;
|
||||
size_t find_last_not_of(char C, size_t From = npos) const noexcept;
|
||||
|
||||
/// Find the last character in the string that is not in \p Chars, or
|
||||
/// npos if not found.
|
||||
///
|
||||
/// Complexity: O(size() + Chars.size())
|
||||
size_t find_last_not_of(StringRef Chars, size_t From = npos) const;
|
||||
size_t find_last_not_of(StringRef Chars, size_t From = npos) const noexcept;
|
||||
|
||||
/// @}
|
||||
/// @name Helpful Algorithms
|
||||
/// @{
|
||||
|
||||
/// Return the number of occurrences of \p C in the string.
|
||||
size_t count(char C) const {
|
||||
size_t count(char C) const noexcept {
|
||||
size_t Count = 0;
|
||||
for (size_t i = 0, e = size(); i != e; ++i)
|
||||
if (Data[i] == C)
|
||||
@@ -359,7 +359,7 @@ namespace wpi {
|
||||
|
||||
/// Return the number of non-overlapped occurrences of \p Str in
|
||||
/// the string.
|
||||
size_t count(StringRef Str) const;
|
||||
size_t count(StringRef Str) const noexcept;
|
||||
|
||||
/// Parse the current string as an integer of the specified radix. If
|
||||
/// \p Radix is specified as zero, this does radix autosensing using
|
||||
@@ -370,7 +370,7 @@ namespace wpi {
|
||||
/// erroneous if empty or if it overflows T.
|
||||
template <typename T>
|
||||
typename std::enable_if<std::numeric_limits<T>::is_signed, bool>::type
|
||||
getAsInteger(unsigned Radix, T &Result) const {
|
||||
getAsInteger(unsigned Radix, T &Result) const noexcept {
|
||||
long long LLVal;
|
||||
if (getAsSignedInteger(*this, Radix, LLVal) ||
|
||||
static_cast<T>(LLVal) != LLVal)
|
||||
@@ -381,7 +381,7 @@ namespace wpi {
|
||||
|
||||
template <typename T>
|
||||
typename std::enable_if<!std::numeric_limits<T>::is_signed, bool>::type
|
||||
getAsInteger(unsigned Radix, T &Result) const {
|
||||
getAsInteger(unsigned Radix, T &Result) const noexcept {
|
||||
unsigned long long ULLVal;
|
||||
// The additional cast to unsigned long long is required to avoid the
|
||||
// Visual C++ warning C4805: '!=' : unsafe mix of type 'bool' and type
|
||||
@@ -416,21 +416,21 @@ namespace wpi {
|
||||
/// \param N The number of characters to included in the substring. If N
|
||||
/// exceeds the number of characters remaining in the string, the string
|
||||
/// suffix (starting with \p Start) will be returned.
|
||||
StringRef substr(size_t Start, size_t N = npos) const {
|
||||
StringRef substr(size_t Start, size_t N = npos) const noexcept {
|
||||
Start = std::min(Start, size());
|
||||
return StringRef(Data + Start, std::min(N, size() - Start));
|
||||
}
|
||||
|
||||
/// Return a StringRef equal to 'this' but with the first \p N elements
|
||||
/// dropped.
|
||||
StringRef drop_front(size_t N = 1) const {
|
||||
StringRef drop_front(size_t N = 1) const noexcept {
|
||||
assert(size() >= N && "Dropping more elements than exist");
|
||||
return substr(N);
|
||||
}
|
||||
|
||||
/// Return a StringRef equal to 'this' but with the last \p N elements
|
||||
/// dropped.
|
||||
StringRef drop_back(size_t N = 1) const {
|
||||
StringRef drop_back(size_t N = 1) const noexcept {
|
||||
assert(size() >= N && "Dropping more elements than exist");
|
||||
return substr(0, size()-N);
|
||||
}
|
||||
@@ -446,7 +446,7 @@ namespace wpi {
|
||||
/// remaining in the string, the string suffix (starting with \p Start)
|
||||
/// will be returned. If this is less than \p Start, an empty string will
|
||||
/// be returned.
|
||||
StringRef slice(size_t Start, size_t End) const {
|
||||
StringRef slice(size_t Start, size_t End) const noexcept {
|
||||
Start = std::min(Start, size());
|
||||
End = std::min(std::max(Start, End), size());
|
||||
return StringRef(Data + Start, End - Start);
|
||||
@@ -540,37 +540,37 @@ namespace wpi {
|
||||
|
||||
/// Return string with consecutive \p Char characters starting from the
|
||||
/// the left removed.
|
||||
StringRef ltrim(char Char) const {
|
||||
StringRef ltrim(char Char) const noexcept {
|
||||
return drop_front(std::min(size(), find_first_not_of(Char)));
|
||||
}
|
||||
|
||||
/// Return string with consecutive characters in \p Chars starting from
|
||||
/// the left removed.
|
||||
StringRef ltrim(StringRef Chars = " \t\n\v\f\r") const {
|
||||
StringRef ltrim(StringRef Chars = " \t\n\v\f\r") const noexcept {
|
||||
return drop_front(std::min(size(), find_first_not_of(Chars)));
|
||||
}
|
||||
|
||||
/// Return string with consecutive \p Char characters starting from the
|
||||
/// right removed.
|
||||
StringRef rtrim(char Char) const {
|
||||
StringRef rtrim(char Char) const noexcept {
|
||||
return drop_back(size() - std::min(size(), find_last_not_of(Char) + 1));
|
||||
}
|
||||
|
||||
/// Return string with consecutive characters in \p Chars starting from
|
||||
/// the right removed.
|
||||
StringRef rtrim(StringRef Chars = " \t\n\v\f\r") const {
|
||||
StringRef rtrim(StringRef Chars = " \t\n\v\f\r") const noexcept {
|
||||
return drop_back(size() - std::min(size(), find_last_not_of(Chars) + 1));
|
||||
}
|
||||
|
||||
/// Return string with consecutive \p Char characters starting from the
|
||||
/// left and right removed.
|
||||
StringRef trim(char Char) const {
|
||||
StringRef trim(char Char) const noexcept {
|
||||
return ltrim(Char).rtrim(Char);
|
||||
}
|
||||
|
||||
/// Return string with consecutive characters in \p Chars starting from
|
||||
/// the left and right removed.
|
||||
StringRef trim(StringRef Chars = " \t\n\v\f\r") const {
|
||||
StringRef trim(StringRef Chars = " \t\n\v\f\r") const noexcept {
|
||||
return ltrim(Chars).rtrim(Chars);
|
||||
}
|
||||
|
||||
@@ -580,27 +580,27 @@ namespace wpi {
|
||||
/// @name StringRef Comparison Operators
|
||||
/// @{
|
||||
|
||||
inline bool operator==(StringRef LHS, StringRef RHS) {
|
||||
inline bool operator==(StringRef LHS, StringRef RHS) noexcept {
|
||||
return LHS.equals(RHS);
|
||||
}
|
||||
|
||||
inline bool operator!=(StringRef LHS, StringRef RHS) {
|
||||
inline bool operator!=(StringRef LHS, StringRef RHS) noexcept {
|
||||
return !(LHS == RHS);
|
||||
}
|
||||
|
||||
inline bool operator<(StringRef LHS, StringRef RHS) {
|
||||
inline bool operator<(StringRef LHS, StringRef RHS) noexcept {
|
||||
return LHS.compare(RHS) == -1;
|
||||
}
|
||||
|
||||
inline bool operator<=(StringRef LHS, StringRef RHS) {
|
||||
inline bool operator<=(StringRef LHS, StringRef RHS) noexcept {
|
||||
return LHS.compare(RHS) != 1;
|
||||
}
|
||||
|
||||
inline bool operator>(StringRef LHS, StringRef RHS) {
|
||||
inline bool operator>(StringRef LHS, StringRef RHS) noexcept {
|
||||
return LHS.compare(RHS) == 1;
|
||||
}
|
||||
|
||||
inline bool operator>=(StringRef LHS, StringRef RHS) {
|
||||
inline bool operator>=(StringRef LHS, StringRef RHS) noexcept {
|
||||
return LHS.compare(RHS) != -1;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user