Make most StringRef functions noexcept.

This commit is contained in:
Peter Johnson
2018-05-14 23:46:08 -07:00
parent c2b1ed3edd
commit 6699f86361
2 changed files with 80 additions and 80 deletions

View File

@@ -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;
}